From f18f7be6f77b9525d0797b8479d6b1bfad65445d Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Sun, 5 May 2024 23:08:24 +0330 Subject: [PATCH] Update X121 Backups ... --- .../Classes/x-saherelm.http.class.ex5 | Bin 0 -> 6594 bytes .../Classes/x-saherelm.http.class.mq5 | 385 ++ .../x-saherelm.x121.provider.class.mq5 | 1851 ++++++ .../Classes/x-saherelm.x121.xea.class.ex5 | Bin 0 -> 11500 bytes .../Classes/x-saherelm.x121.xea.class.mq5 | 1711 ++++++ .../Classes/x-saherelm.xaccount.class.ex5 | Bin 0 -> 7224 bytes .../Classes/x-saherelm.xaccount.class.mq5 | 398 ++ .../14030217/Classes/x-saherelm.xea.class.ex5 | Bin 0 -> 11836 bytes .../14030217/Classes/x-saherelm.xea.class.mq5 | 1614 ++++++ .../Classes/x-saherelm.xhelper.class.ex5 | Bin 0 -> 6862 bytes .../Classes/x-saherelm.xhelper.class.mq5 | 209 + .../Classes/x-saherelm.xnotifier.class.ex5 | Bin 0 -> 6346 bytes .../Classes/x-saherelm.xprovider.class.ex5 | Bin 0 -> 7596 bytes .../Classes/x-saherelm.xprovider.class.mq5 | 304 + .../Classes/x-saherelm.xtrade.class.ex5 | Bin 0 -> 9048 bytes .../Classes/x-saherelm.xtrade.class.mq5 | 4538 +++++++++++++++ .../X121/14030217/Documents/.gitkeep | 0 .../Documents/JsModules/x-color.tools.js | 506 ++ .../Documents/JsModules/x-file.tools.js | 830 +++ .../Documents/JsModules/x-shell.tools.js | 219 + .../JsModules/x-type-detector.tools.js | 268 + .../Documents/JsModules/x-value.tools.js | 1528 +++++ .../Documents/Temp/multi.asset.configs.yml | 1 + .../X121/14030217/Experts/x-saherelm.xea.ex5 | Bin 0 -> 545088 bytes .../X121/14030217/Experts/x-saherelm.xea.mq5 | 366 ++ .../x-saherelm.x121.xman.helper.class.ex5 | Bin 0 -> 10470 bytes .../x-saherelm.x121.xman.helper.class.mq5 | 1814 ++++++ .../Indicators/x-saherelm.x121.xman.ex5 | Bin 0 -> 87504 bytes .../Indicators/x-saherelm.x121.xman.mq5 | 4627 +++++++++++++++ .../Libraries/x-saherelm.alert.lib.ex5 | Bin 0 -> 7466 bytes .../Libraries/x-saherelm.alert.lib.mq5 | 187 + .../Libraries/x-saherelm.common.lib.ex5 | Bin 0 -> 6308 bytes .../Libraries/x-saherelm.common.lib.mq5 | 5095 +++++++++++++++++ .../Libraries/x-saherelm.draw.lib.ex5 | Bin 0 -> 6322 bytes .../Libraries/x-saherelm.draw.lib.mq5 | 2462 ++++++++ .../Libraries/x-saherelm.http.lib.ex5 | Bin 0 -> 3554 bytes .../Libraries/x-saherelm.http.lib.mq5 | 177 + .../14030217/Libraries/x-saherelm.log.lib.ex5 | Bin 0 -> 5860 bytes .../14030217/Libraries/x-saherelm.log.lib.mq5 | 1088 ++++ .../Libraries/x-saherelm.models.lib.ex5 | Bin 0 -> 4868 bytes .../Libraries/x-saherelm.models.lib.mq5 | 303 + .../Libraries/x-saherelm.seriallizer.lib.ex5 | Bin 0 -> 9686 bytes .../Libraries/x-saherelm.seriallizer.lib.mq5 | 1273 ++++ .../x-saherelm.x121.condition.parser.lib.mq5 | 2475 ++++++++ .../Libraries/x-saherelm.x121.draw.lib.ex5 | Bin 0 -> 6864 bytes .../Libraries/x-saherelm.x121.draw.lib.mq5 | 276 + .../x-saherelm.x121.signaller.lib.ex5 | Bin 0 -> 10570 bytes .../Libraries/x-saherelm.x121.support.lib.ex5 | Bin 0 -> 11408 bytes .../Libraries/x-saherelm.xman.parser.lib.ex5 | Bin 0 -> 9680 bytes .../Libraries/x-saherelm.xman.parser.lib.mq5 | 1674 ++++++ 50 files changed, 36179 insertions(+) create mode 100644 MQLTestWorkspace/X121/14030217/Classes/x-saherelm.http.class.ex5 create mode 100644 MQLTestWorkspace/X121/14030217/Classes/x-saherelm.http.class.mq5 create mode 100644 MQLTestWorkspace/X121/14030217/Classes/x-saherelm.x121.provider.class.mq5 create mode 100644 MQLTestWorkspace/X121/14030217/Classes/x-saherelm.x121.xea.class.ex5 create mode 100644 MQLTestWorkspace/X121/14030217/Classes/x-saherelm.x121.xea.class.mq5 create mode 100644 MQLTestWorkspace/X121/14030217/Classes/x-saherelm.xaccount.class.ex5 create mode 100644 MQLTestWorkspace/X121/14030217/Classes/x-saherelm.xaccount.class.mq5 create mode 100644 MQLTestWorkspace/X121/14030217/Classes/x-saherelm.xea.class.ex5 create mode 100644 MQLTestWorkspace/X121/14030217/Classes/x-saherelm.xea.class.mq5 create mode 100644 MQLTestWorkspace/X121/14030217/Classes/x-saherelm.xhelper.class.ex5 create mode 100644 MQLTestWorkspace/X121/14030217/Classes/x-saherelm.xhelper.class.mq5 create mode 100644 MQLTestWorkspace/X121/14030217/Classes/x-saherelm.xnotifier.class.ex5 create mode 100644 MQLTestWorkspace/X121/14030217/Classes/x-saherelm.xprovider.class.ex5 create mode 100644 MQLTestWorkspace/X121/14030217/Classes/x-saherelm.xprovider.class.mq5 create mode 100644 MQLTestWorkspace/X121/14030217/Classes/x-saherelm.xtrade.class.ex5 create mode 100644 MQLTestWorkspace/X121/14030217/Classes/x-saherelm.xtrade.class.mq5 create mode 100644 MQLTestWorkspace/X121/14030217/Documents/.gitkeep create mode 100644 MQLTestWorkspace/X121/14030217/Documents/JsModules/x-color.tools.js create mode 100644 MQLTestWorkspace/X121/14030217/Documents/JsModules/x-file.tools.js create mode 100644 MQLTestWorkspace/X121/14030217/Documents/JsModules/x-shell.tools.js create mode 100644 MQLTestWorkspace/X121/14030217/Documents/JsModules/x-type-detector.tools.js create mode 100644 MQLTestWorkspace/X121/14030217/Documents/JsModules/x-value.tools.js create mode 100644 MQLTestWorkspace/X121/14030217/Documents/Temp/multi.asset.configs.yml create mode 100644 MQLTestWorkspace/X121/14030217/Experts/x-saherelm.xea.ex5 create mode 100644 MQLTestWorkspace/X121/14030217/Experts/x-saherelm.xea.mq5 create mode 100644 MQLTestWorkspace/X121/14030217/Helpers/x-saherelm.x121.xman.helper.class.ex5 create mode 100644 MQLTestWorkspace/X121/14030217/Helpers/x-saherelm.x121.xman.helper.class.mq5 create mode 100644 MQLTestWorkspace/X121/14030217/Indicators/x-saherelm.x121.xman.ex5 create mode 100644 MQLTestWorkspace/X121/14030217/Indicators/x-saherelm.x121.xman.mq5 create mode 100644 MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.alert.lib.ex5 create mode 100644 MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.alert.lib.mq5 create mode 100644 MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.common.lib.ex5 create mode 100644 MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.common.lib.mq5 create mode 100644 MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.draw.lib.ex5 create mode 100644 MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.draw.lib.mq5 create mode 100644 MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.http.lib.ex5 create mode 100644 MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.http.lib.mq5 create mode 100644 MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.log.lib.ex5 create mode 100644 MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.log.lib.mq5 create mode 100644 MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.models.lib.ex5 create mode 100644 MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.models.lib.mq5 create mode 100644 MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.seriallizer.lib.ex5 create mode 100644 MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.seriallizer.lib.mq5 create mode 100644 MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.x121.condition.parser.lib.mq5 create mode 100644 MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.x121.draw.lib.ex5 create mode 100644 MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.x121.draw.lib.mq5 create mode 100644 MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.x121.signaller.lib.ex5 create mode 100644 MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.x121.support.lib.ex5 create mode 100644 MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.xman.parser.lib.ex5 create mode 100644 MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.xman.parser.lib.mq5 diff --git a/MQLTestWorkspace/X121/14030217/Classes/x-saherelm.http.class.ex5 b/MQLTestWorkspace/X121/14030217/Classes/x-saherelm.http.class.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..57d5c70bf0b4051c31444d6c0354bf669a6ab621 GIT binary patch literal 6594 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 0; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Destintion Folder Path ... + string mPath; + + // + // WEB Request Timeout Value ... + int mTimeout; + + // + // WEB Request's Response ... + string mResponse; + + // + // Error Value ... + int mError; + + // + // Private ... +private: + // + // Reset Errors State ... + void ResetState() + { + // + // Reset Errors ... + mError = -1; + mResponse = ""; + ResetLastError(); + } + + // + // Generate Full File Path ... + string GetFilePath(string fileName) + { + // + string result = ""; + + // + result = + // + Path() + "\\" + fileName + // + ; + + // + return result; + } +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/X121/14030217/Classes/x-saherelm.x121.provider.class.mq5 b/MQLTestWorkspace/X121/14030217/Classes/x-saherelm.x121.provider.class.mq5 new file mode 100644 index 0000000..2b83bb3 --- /dev/null +++ b/MQLTestWorkspace/X121/14030217/Classes/x-saherelm.x121.provider.class.mq5 @@ -0,0 +1,1851 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCX121Provider +// Description: X121 Signal Provider ... +// +// +// 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 + +// +// START Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Classes/x-saherelm.xprovider.class.mq5" +#include "../Helpers/x-saherelm.x121.xman.helper.class.mq5" + +// +// Library ... +#include "../Libraries/x-saherelm.seriallizer.lib.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// Here we Have to Define an Input Structure Model +// for Provider Class to Handle Helpers Definitions ... +struct X121ProviderInputs +{ + // + // XMAN ... + XMANInputs xmanConfig; +}; + +// +// Model Market Sense based On Current Captured conditions ... +struct X121MarketConditions +{ + // + // Commonly Used Info ... + + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + XCandleRemains barRemains; + + // + // Bar Index ... + int barIndex; + + // + // Check Current Market Condition has Signal or not ... + bool hasSignal; + + // + // If has any Signal, Models it's related info here ... + XSignal signal; + + // + // Support and Resistances ... + // if provides Signal ... + XOHCLSupRes supportResistances; + + // + // Change Price Steps ... + double momentumStep; + + // + XOHCL candles[]; + + // + // INDICATORS Market Sense ... + + // + // XMAN ... + XMANInfo xmanInfo; +}; + +// +#include "../Libraries/x-saherelm.x121.condition.parser.lib.mq5" + +// +// Notified a Signal was Appears ... +typedef void (*TOnSignalConditions)( + X121MarketConditions &info); + +// +// All Available Signal Types ... +enum ENUM_X121_SIGNAL_PROVIDERS +{ + NONE, // NONE ... + XTEST, // TEST ... + X786, // Hadi Khazaee Asl ... + X92, // Hadi Khazaee Asl ... +}; + +// +// END Definitions ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Base Class for All of our EA's ... +class XSCX121Provider : public XSCEABaseProvider +{ + // + // Public ... +public: + // + // Props ... + X121ProviderInputs providedConfig; + X121ProviderInputs currentConfig; + X121ProviderInputs cleanConfig; + + // + // Indicator Helper Classes Instance ... + + // + // XMAN ... + XSCXMANHelper *mXManHelper; + + // + // Pivot Points ... + + // + // Hull and SSL Pivot Points ... + double upZonePivots[]; + double downZonePivots[]; + + // + // Peaks and Vales Verifications Number ... + double peakPivots[]; + double valePivots[]; + + // + double cyclesHHPivots[]; + double cyclesLLPivots[]; + + // + double fibPivots[]; + + // + int pivotsSequentialCount; + + // + // Constructor ... + void XSCX121Provider( + string symbol, // Trading Symbol ... + ENUM_TIMEFRAMES period // Trading Time Frame ... + ) : XSCEABaseProvider(symbol, period) + { + // + mMinPivots = 200; + pivotsSequentialCount = 35; + + // + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCX121Provider() + { + // + // De construct Helpers ... + delete mXManHelper; + } + + // + virtual void PrepareTag() + { + mTag = "X121Provider((" + mSymbol + ")(" + ToString(mPeriod) + ")"; + } + + // + virtual bool Init() + { + // + bool result = false; + + // + // Instantiate all Indicators Helper Classes ... + + // + // XMAN ... + mXManHelper = new XSCXMANHelper( + mSymbol, + mPeriod); + result = mXManHelper.SetConfig(currentConfig.xmanConfig); + + // + return result; + } + + // + virtual int GetMaxLength() + { + // + int result = -1; + + // + result = MathMax(result, mXManHelper.GetMaxLength()); + + // + return result; + } + + // + virtual int GetCalculatedBars() + { + // + int result = -1; + + // + int mXManBars = mXManHelper.GetCalculatedBars(); + + // + int min = MathMin(1, mXManBars); + + // + int max = MathMax(1, mXManBars); + + // + result = min; + + // + return result; + } + + // + virtual void ProcessBuffers() + { + UpdatePivotPoints(); + } + + // + virtual bool ProcessTick(X121MarketConditions &conditions) + { + // + if (CanIgnoreTick()) + { + return false; + } + + // + return ProcessSignals(conditions); + } + + // + int GetMinPivots() + { + return mMinPivots; + } + + // + X121ProviderInputs GetConfig() + { + // + X121ProviderInputs result; + + // + result = currentConfig; + + // + return result; + } + + // + // Set Available Signallers ... + bool SetSignallers( + string &signallers[]) + { + // + bool result = false; + + // + result = ArraySize(signallers) > 0; + if (!result) + { + return result; + } + + // + Copy( + signallers, + mSignallers); + + // + return result; + } + + // + bool SetConfig(X121ProviderInputs &config) + { + // + bool result = false; + + // + PrepareConfig(config); + + // + result = Init(); + + // + return result; + } + + // + bool ResetDefaultConfig() + { + // + bool result = SetConfig(providedConfig); + + // + return result; + } + + // + bool ShowCleanConfig() + { + // + currentConfig = cleanConfig; + + // + bool result = Init(); + + // + return result; + } + + // + bool ShowDefaultConfig() + { + // + currentConfig = providedConfig; + + // + bool result = Init(); + + // + return result; + } + + // + bool IsAllowedSignaller( + ENUM_X121_SIGNAL_PROVIDERS provider // Signal Provider + ) + { + // + bool result = false; + + // + string providerStr = ToString(provider); + + // + result = Contains( + providerStr, + mSignallers); + + // + return result; + } + + // + // Generate Market Sense ... + X121MarketConditions GetMarketConditions( + int barIndex // Specified Bar Index + ) + { + // + X121MarketConditions result; + + // + // Fill Common Data ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barIndex = barIndex; + + // + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + result.barTime = barTime; + + // + int remainedCandle = barIndex > 0 + ? barIndex - 1 + : barIndex; + GetCandleRemainsTime( + result.barRemains, + mSymbol, + mPeriod, + remainedCandle); + + // + // Attach Candles Info in XOHCL Model to Conditions ... + int mLoopBackBars = mXManHelper.Loopback(); + XOHCL candles[]; + GetCandles( + candles, + mSymbol, + mPeriod, + 0, + mLoopBackBars); + Copy( + candles, + result.candles); + Clean(candles); + + // + result.xmanInfo = mXManHelper.GetInfo(barIndex); + + // + return result; + } + + // + bool GuardCheck(XGuard &guards[]) + { + // + bool result = false; + + // + Clean(guards); + + // + // Implement Guards Check ... + X121MarketConditions mConditions = GetMarketConditions(1); + + // + // X786 ... + bool canCheckX786 = IsAllowedSignaller(X786); + if (canCheckX786) + { + // + } + + // + result = ArraySize(guards) > 0; + + // + return result; + } + + // + // Add Specific On SignalConditions Event Handler ... + int AddOnSignalConditionEventHandler(TOnSignalConditions handler) + { + // + ArrayResize( + mSignalConditionsEventHandlers, + ArraySize(mSignalConditionsEventHandlers) + 1); + + // + int result = ArraySize(mSignalConditionsEventHandlers) - 1; + mSignalConditionsEventHandlers[result] = handler; + + // + return result; + } + + // + // Remove All On Signal Event Handler ... + void ReoveOnSignalEventHandlers() + { + // + ArrayFree(mSignalConditionsEventHandlers); + } + + // + // Notify a Signal Found on all Event Listeners ... + void NotifyOnSignalConditionsEvent(X121MarketConditions &info) + { + // + int listenerCount = ArraySize(mSignalConditionsEventHandlers); + if (listenerCount <= 0) + { + return; + } + + // + // Loop Through Listeners ... + for (int i = 0; i < listenerCount; i++) + { + // + TOnSignalConditions listener = mSignalConditionsEventHandlers[i]; + + // + listener(info); + } + } + + // + // PIVOTS ... + + // + // Start Pivots Scanning on Instance Creation ... + void ProccessPivotPoints() + { + // + if (mStartPivotScan) + { + return; + } + + // + mStartPivotScan = true; + + // + int scanSize = iBars( + mSymbol, + mPeriod) - + 500; + + // + for (int i = 1; i < scanSize; i++) + { + // + UpdatePivotPoints(i); + + // + int pivotsCount = CountPivots(); + if (pivotsCount >= mMinPivots) + { + break; + } + } + } + + // + // Count Current Pivots ... + int CountPivots() + { + // + int pivotSizes[]; + + // + int upZoneCount = ArraySize(upZonePivots); + if (upZoneCount > 0) + { + // + Add( + upZoneCount, + pivotSizes); + } + + // + int downZoneCount = ArraySize(downZonePivots); + if (downZoneCount > 0) + { + // + Add( + downZoneCount, + pivotSizes); + } + + // + int peaksCount = ArraySize(peakPivots); + if (peaksCount > 0) + { + // + Add( + peaksCount, + pivotSizes); + } + + // + int valesCount = ArraySize(valePivots); + if (valesCount > 0) + { + // + Add( + valesCount, + pivotSizes); + } + + // + int fibsCount = ArraySize(fibPivots); + if (fibsCount > 0) + { + // + Add( + fibsCount, + pivotSizes); + } + + // + int cyclesHHsCount = ArraySize(cyclesHHPivots); + if (cyclesHHsCount > 0) + { + // + Add( + cyclesHHsCount, + pivotSizes); + } + + // + int cyclesLLsCount = ArraySize(cyclesLLPivots); + if (cyclesLLsCount > 0) + { + // + Add( + cyclesHHsCount, + pivotSizes); + } + + // + int result = ArraySize(pivotSizes) > 0 + ? pivotSizes[ArrayMaximum(pivotSizes)] + : 0; + + // + return result; + } + + // + // Generate Exists Support and Resistance based on Given Price ... + XOHCLSupRes GenerateSupportAndResistance( + double price, // Specified Price + int count = 10 // Number of Pivots in Each Side + ) + { + // + XOHCLSupRes result; + + // + UpdatePivotPoints(0); + + // + double pivots[]; + FillPivotPoints(pivots); + + // + // Generate Support and Resistances ... + result = ExtractSupportAndResistance( + price, + pivots, + count); + + // + return result; + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // CCandle Timer ... + int mCTimerHandler; + + // + // Signal Event Handlers ... + TOnSignalConditions mSignalConditionsEventHandlers[]; + + // + // Make Provided Config in Clean Style ... + void PrepareConfig(X121ProviderInputs &config) + { + // + cleanConfig = config; + + // + // XMAN ... + cleanConfig.xmanConfig.showCandleTimer = false; + cleanConfig.xmanConfig.showCandles = false; + cleanConfig.xmanConfig.showHKCandles = false; + cleanConfig.xmanConfig.showPeaksAndVales = false; + cleanConfig.xmanConfig.showTrends = false; + cleanConfig.xmanConfig.fillTrends = false; + cleanConfig.xmanConfig.showLevels = false; + cleanConfig.xmanConfig.showConsolidations = false; + cleanConfig.xmanConfig.showRibbons = false; + cleanConfig.xmanConfig.showHull = false; + cleanConfig.xmanConfig.showSSLChannel = false; + cleanConfig.xmanConfig.showFibo1Levels = false; + cleanConfig.xmanConfig.showFibo2Levels = false; + cleanConfig.xmanConfig.showFibo3Levels = false; + + // + providedConfig = config; + currentConfig = config; + } + + // + void Calculate(int barIndex) + { + // + mXManHelper.Calculate(barIndex); + } + + // + int mMinPivots; + bool mStartPivotScan; + double mLastMomentumStep; + + // + // Find Required Pivots for Support and Resistance ... + void UpdatePivotPoints( + int barIndex = 0 // Specified Candle ... + ) + { + // + Calculate(barIndex); + + // + // Detect Peask and Vales Pivots ... + + // + // Detect Hull Pivots ... + // find Hull Trend Changes ... + int idx = 0; + + // + // Retrieve XMan Info ... + // since it's the only one Indicator which provides Data here ... + XMANInfo info = mXManHelper.GetInfo(barIndex); + + // + // Define some Variable to count Verified Sequences ... + int fib1Verified = 0; + int fib2Verified = 0; + int fib3Verified = 0; + int peakVerified = 0; + int valeVerified = 0; + int scHHVerified = 0; + int scLLVerified = 0; + int mcHHVerified = 0; + int mcLLVerified = 0; + int lcHHVerified = 0; + int lcLLVerified = 0; + int hcHHVerified = 0; + int hcLLVerified = 0; + + // + // Here we have to select Points to verify their Sequential repeats ... + + // + // Slect Fibonacci Values ... + double selectedFib1 = info.fibLevel1s[idx]; + double selectedFib2 = info.fibLevel2s[idx]; + double selectedFib3 = info.fibLevel3s[idx]; + + // + // Select Peaks and Vales ... + double selectedPeak = info.peaks[idx]; + double selectedVale = info.vales[idx]; + + // + // Select Cycles Highest Highs ... + double selectedSCHH = info.sHHs[idx]; + double selectedMCHH = info.mHHs[idx]; + double selectedLCHH = info.lHHs[idx]; + double selectedHCHH = info.hHHs[idx]; + + // + // Select Cycles Lowest Lows ... + double selectedSCLL = info.sLLs[idx]; + double selectedMCLL = info.mLLs[idx]; + double selectedLCLL = info.lLLs[idx]; + double selectedHCLL = info.hLLs[idx]; + + // + // Now we Have to Loop Bars Until Fillup Required + // Pivots or END available Bars ... + int startIndex = idx; + int endIndex = pivotsSequentialCount + idx + 1; + for (int i = startIndex; i < endIndex; i++) + { + // + int idx = i - startIndex; + + // + // Now We Have to Compare each Selected Value with indexed value ... + + // + // Peaks ... + if (selectedPeak == info.peaks[i]) + { + peakVerified++; + } + else + { + peakVerified = 0; + } + + // + // Vales ... + if (selectedVale == info.vales[i]) + { + valeVerified++; + } + else + { + valeVerified = 0; + } + + // + // Fibo 1 ... + if (selectedFib1 == info.fibLevel1s[i]) + { + fib1Verified++; + } + else + { + fib1Verified = 0; + } + + // + // Fibo 2 ... + if (selectedFib2 == info.fibLevel2s[i]) + { + fib2Verified++; + } + else + { + fib2Verified = 0; + } + + // + // Fibo 3 ... + if (selectedFib3 == info.fibLevel3s[i]) + { + fib3Verified++; + } + else + { + fib3Verified = 0; + } + + // + // SCHH ... + if (selectedSCHH == info.sHHs[i]) + { + scHHVerified++; + } + else + { + scHHVerified = 0; + } + + // + // SCLL ... + if (selectedSCLL == info.sLLs[i]) + { + scLLVerified++; + } + else + { + scLLVerified = 0; + } + + // + // MCHH ... + if (selectedMCHH == info.mHHs[i]) + { + mcHHVerified++; + } + else + { + mcHHVerified = 0; + } + + // + // MCLL ... + if (selectedMCLL == info.mLLs[i]) + { + mcLLVerified++; + } + else + { + mcLLVerified = 0; + } + + // + // LCHH ... + if (selectedLCHH == info.lHHs[i]) + { + lcHHVerified++; + } + else + { + lcHHVerified = 0; + } + + // + // LCLL ... + if (selectedLCLL == info.lLLs[i]) + { + lcLLVerified++; + } + else + { + lcLLVerified = 0; + } + + // + // HCHH ... + if (selectedHCHH == info.hHHs[i]) + { + hcHHVerified++; + } + else + { + hcHHVerified = 0; + } + + // + // HCLL ... + if (selectedHCLL == info.hLLs[i]) + { + hcLLVerified++; + } + else + { + hcLLVerified = 0; + } + } + + // + // Now we Have to check Verifications of each + // Selected Values and if their Passed Sequential Count + // we add them as Pivot Points ... + + // + // Peaks ... + if (peakVerified >= pivotsSequentialCount) + { + // + AddIfNotExists( + selectedPeak, + peakPivots); + } + + // + // Vales ... + if (valeVerified >= pivotsSequentialCount) + { + // + AddIfNotExists( + selectedVale, + valePivots); + } + + // + // Fib 1 ... + if (fib1Verified >= pivotsSequentialCount) + { + // + AddIfNotExists( + selectedFib1, + fibPivots); + } + + // + // Fib 2 ... + if (fib2Verified >= pivotsSequentialCount) + { + // + AddIfNotExists( + selectedFib2, + fibPivots); + } + + // + // Fib 3 ... + if (fib3Verified >= pivotsSequentialCount) + { + // + AddIfNotExists( + selectedFib3, + fibPivots); + } + + // + // SCHH ... + if (scHHVerified >= pivotsSequentialCount) + { + // + AddIfNotExists( + selectedSCHH, + cyclesHHPivots); + } + + // + // SCLL ... + if (scLLVerified >= pivotsSequentialCount) + { + // + AddIfNotExists( + selectedSCLL, + cyclesLLPivots); + } + + // + // MCHH ... + if (mcHHVerified >= pivotsSequentialCount) + { + // + AddIfNotExists( + selectedMCHH, + cyclesHHPivots); + } + + // + // MCLL ... + if (mcLLVerified >= pivotsSequentialCount) + { + // + AddIfNotExists( + selectedMCLL, + cyclesLLPivots); + } + + // + // LCHH ... + if (lcHHVerified >= pivotsSequentialCount) + { + // + AddIfNotExists( + selectedLCHH, + cyclesHHPivots); + } + + // + // LCLL ... + if (lcLLVerified >= pivotsSequentialCount) + { + // + AddIfNotExists( + selectedLCLL, + cyclesLLPivots); + } + + // + // HCHH ... + if (hcHHVerified >= pivotsSequentialCount) + { + // + AddIfNotExists( + selectedHCHH, + cyclesHHPivots); + } + + // + // HCLL ... + if (hcLLVerified >= pivotsSequentialCount) + { + // + AddIfNotExists( + selectedHCLL, + cyclesLLPivots); + } + } + + // + // Fill Pivot Points ... + void FillPivotPoints( + double &result[]) + { + // + Clean(result); + + // + int pCount = CountPivots(); + if (pCount <= 0) + { + return; + } + + // + AddsIfNotExists( + upZonePivots, + result); + + // + AddsIfNotExists( + downZonePivots, + result); + + // + AddsIfNotExists( + peakPivots, + result); + + // + AddsIfNotExists( + valePivots, + result); + + // + AddsIfNotExists( + fibPivots, + result); + + // + AddsIfNotExists( + cyclesHHPivots, + result); + + // + AddsIfNotExists( + cyclesLLPivots, + result); + } + + // + // Available Signallers ... + string mSignallers[]; + + // + // Here we are Capture Conditions and Check Signals ... + // The Signals Must be Unique for each providers ... + bool ProcessSignals(X121MarketConditions &conditions) + { + // + X121MarketConditions mConditions = GetMarketConditions(1); + + // + // BUY ... + + // + Clean(mConditions.signal); + bool hasLongSignal = HasLongSignal(mConditions); + if (hasLongSignal) + { + // + NotifyOnSignalEvent( + mConditions.signal); + NotifyOnSignalConditionsEvent(mConditions); + mWaitUntilNewCandle = true; + + // + conditions = mConditions; + return true; + } + + // + // SELL ... + + // + Clean(mConditions.signal); + bool hasShortignal = HasShortSignal(mConditions); + if (hasShortignal) + { + // + NotifyOnSignalEvent( + mConditions.signal); + NotifyOnSignalConditionsEvent(mConditions); + mWaitUntilNewCandle = true; + + // + conditions = mConditions; + return true; + } + + // + return false; + } + + // + // Check has Long Signal on Each Strategies ... + bool HasLongSignal(X121MarketConditions &conditions) + { + // + bool result = false; + + // + // TODO: Remove ... + double xTPPoint = 30; + double xSLPoint = 20; + + // + // Retrieve Entry Price ... + double entry = GetEntry( + mSymbol, + POSITION_TYPE_BUY); + + // + // Retrieve Pivot Points ... + double pivots[]; + FillPivotPoints(pivots); + XOHCLSupRes supRes = ExtractSupportAndResistance( + entry, + pivots, + 15); + + // + // Cleaning Market Conditions Signal Structure ... + Clean(conditions.signal); + conditions.hasSignal = false; + + // + // X786 ... + bool x786HasSignal = false; + bool canCheckX786 = IsAllowedSignaller(X786); + if (canCheckX786) + { + // + x786HasSignal = + // + IsMarketBullish(conditions) && + IsBullishCandle(conditions.candles[1]) + // conditions.candles[0].low > conditions.candles[1].close + // + ; + + // + if (x786HasSignal) + { + // + Add( + ToString(X786), + conditions.signal.providers); + + // + double sl = conditions.xmanInfo.sLLs[0]; + + // + conditions.signal.r2r = 1; + conditions.signal.riskAmount = 0.01; + conditions.signal.mode = X_ORDER_MODE_MARKET; + conditions.signal.entry = entry; + conditions.signal.sl = sl; + conditions.signal.tp = 0; + + // + conditions.signal.calculateTP = true; + conditions.signal.useRiskAmountAsVolume = true; + + // // + // double supportFactor = ((MathAbs(entry - sl) / 2)); + // NormalizePrice( + // supportFactor, + // conditions.symbol); + + // // + // double supportVolume = 0.01; + + // // + // XSignal lSupport; + // Clean(lSupport); + + // // + // lSupport.r2r = 1; + // lSupport.sl = entry; + // lSupport.volume = supportVolume; + // lSupport.mode = X_ORDER_MODE_STOP; + // lSupport.type = POSITION_TYPE_SELL; + // lSupport.riskAmount = supportVolume; + // lSupport.symbol = conditions.symbol; + // lSupport.entry = entry - supportFactor; + // lSupport.tp = entry - (2 * supportFactor); + + // // + // Add( + // lSupport, + // conditions.signal.supports); + + // // + // // Check Support and Resistance ... + + // // + // Clean(lSupport); + + // // + // supportVolume = 0.01; + // supportFactor = ((MathAbs(entry - sl) / 2.3)); + + // // + // lSupport.r2r = 1; + // lSupport.sl = entry; + // lSupport.volume = supportVolume; + // lSupport.mode = X_ORDER_MODE_STOP; + // lSupport.type = POSITION_TYPE_SELL; + // lSupport.riskAmount = supportVolume; + // lSupport.symbol = conditions.symbol; + // lSupport.entry = entry - supportFactor; + // lSupport.tp = entry - (2 * supportFactor); + + // // + // Add( + // lSupport, + // conditions.signal.supports); + + // // + // // Check TP Calculate ... + + // // + // Clean(lSupport); + + // // + // supportVolume = 0.01; + // supportFactor = ((MathAbs(entry - sl) / 2.3)); + + // // + // lSupport.r2r = 1; + // lSupport.sl = entry; + // lSupport.volume = supportVolume; + // lSupport.mode = X_ORDER_MODE_STOP; + // lSupport.type = POSITION_TYPE_BUY; + // lSupport.riskAmount = supportVolume; + // lSupport.symbol = conditions.symbol; + // lSupport.entry = entry + supportFactor; + // lSupport.tp = entry + (2 * supportFactor); + + // // + // Add( + // lSupport, + // conditions.signal.supports); + } + } + + // + bool x92HasSignal = false; + bool canCheckX92 = IsAllowedSignaller(X92); + if (canCheckX92) + { + // + x92HasSignal = + // + false + // + ; + + // + if (x92HasSignal) + { + // + Add( + ToString(X92), + conditions.signal.providers); + + // + double sl = conditions.xmanInfo.mLLs[0]; + + // + conditions.signal.r2r = 1.5; + conditions.signal.riskAmount = 0.01; + conditions.signal.mode = X_ORDER_MODE_MARKET; + conditions.signal.entry = entry; + conditions.signal.sl = sl; + conditions.signal.tp = 0; + + // + conditions.signal.calculateTP = true; + conditions.signal.useRiskAmountAsVolume = true; + } + } + + // + result = + // + x786HasSignal + // + || + // + x92HasSignal + // + ; + + // + if (result) + { + // + conditions.supportResistances = supRes; + conditions.momentumStep = mLastMomentumStep; + + // + conditions.signal.symbol = mSymbol; + conditions.signal.period = mPeriod; + conditions.signal.type = POSITION_TYPE_BUY; + + // + conditions.hasSignal = true; + } + + // + return result; + } + + // + // Check has Short Signal on Each Strategies ... + bool HasShortSignal(X121MarketConditions &conditions) + { + // + bool result = false; + + // + // TODO: Remove this ... + double xTPPoint = 30; + double xSLPoint = 20; + + // + // Retrieve Entry Price ... + double entry = GetEntry( + mSymbol, + POSITION_TYPE_SELL); + + // + // Retrieve Pivot Points ... + double pivots[]; + FillPivotPoints(pivots); + XOHCLSupRes supRes = ExtractSupportAndResistance( + entry, + pivots, + 15); + + // + // Cleaning Market Conditions Signal Structure ... + Clean(conditions.signal); + conditions.hasSignal = false; + + // + // X786 ... + bool x786HasSignal = false; + bool canCheckX786 = IsAllowedSignaller(X786); + if (canCheckX786) + { + // + x786HasSignal = + // + false + // + ; + + // + if (x786HasSignal) + { + // + Add( + ToString(X786), + conditions.signal.providers); + + // + // double slPoint = xSLPoint; + // double slPrice = PointToPrice( + // conditions.symbol, + // slPoint); + // double sl = entry + slPrice; + + // // + // // TODO: Remove this to X121EA Class for Handling risk to reward and riskAmount and use risk amount as static volume + // // by access X121SignalProvider struture ... + // double tpPoint = xTPPoint; + // double tpPrice = PointToPrice( + // conditions.symbol, + // tpPoint); + // double tp = entry - tpPrice; + + // + double sl = conditions.xmanInfo.mHHs[0]; + + // + conditions.signal.r2r = 1.5; + conditions.signal.riskAmount = 0.01; + conditions.signal.mode = X_ORDER_MODE_MARKET; + conditions.signal.entry = entry; + conditions.signal.sl = sl; + conditions.signal.tp = 0; // tp; + + // + // conditions.signal.ignoreSL = false; + conditions.signal.calculateTP = true; + conditions.signal.useRiskAmountAsVolume = true; + } + } + + // + bool x92HasSignal = false; + bool canCheckX92 = IsAllowedSignaller(X92); + if (canCheckX92) + { + // + x92HasSignal = + // + false + // + // + ; + + // + if (x92HasSignal) + { + // + Add( + ToString(X92), + conditions.signal.providers); + + // + double sl = conditions.xmanInfo.mHHs[0]; + + // + conditions.signal.r2r = 1.5; + conditions.signal.riskAmount = 0.01; + conditions.signal.mode = X_ORDER_MODE_MARKET; + conditions.signal.entry = entry; + conditions.signal.sl = sl; + conditions.signal.tp = 0; + + // + conditions.signal.calculateTP = true; + conditions.signal.useRiskAmountAsVolume = true; + } + } + + // + result = + // + x786HasSignal + // + || + // + x92HasSignal + // + ; + + // + if (result) + { + // + conditions.supportResistances = supRes; + conditions.momentumStep = mLastMomentumStep; + + // + conditions.signal.symbol = mSymbol; + conditions.signal.period = mPeriod; + conditions.signal.type = POSITION_TYPE_SELL; + + // + conditions.hasSignal = true; + } + + // + return result; + } + + // + // SIGNALLER Tools ... + + // + double CalculateX786LognStop(const X121MarketConditions &conditions) + { + // + double result = 0; + + // + double val1 = conditions.xmanInfo.trends[0]; + double val2 = conditions.xmanInfo.sslcDowns[0]; + double val3 = conditions.xmanInfo.hullDowns[0]; + double val4 = conditions.xmanInfo.ribbon1s[0]; + double val5 = conditions.xmanInfo.ribbon2s[0]; + double val6 = conditions.xmanInfo.ribbon3s[0]; + double val7 = conditions.xmanInfo.ribbon4s[0]; + double val8 = conditions.xmanInfo.ribbon5s[0]; + double val9 = conditions.xmanInfo.ribbon6s[0]; + + // + double min = MathMin(val1, val2); + min = MathMin(min, val3); + min = MathMin(min, val4); + min = MathMin(min, val5); + min = MathMin(min, val6); + min = MathMin(min, val7); + min = MathMin(min, val8); + min = MathMin(min, val9); + + // + double max = MathMax(val1, val2); + max = MathMax(max, val3); + max = MathMax(max, val4); + max = MathMax(max, val5); + max = MathMax(max, val6); + max = MathMax(max, val7); + max = MathMax(max, val8); + max = MathMax(max, val9); + + // + return result; + } +}; + +// +// START Definitions ... +// + +// +// Model Signal Providers Definitions ... +struct X121SignalProvider +{ + // + // Provider use Which Symbol ... + string symbol; + + // + // Allowed Providers ... + string providers[]; + + // + // Provider use Which Time Frame ... + ENUM_TIMEFRAMES period; + + // + // Risk Amount Per Trades Related to Time Frames ... + // Percent of Available Balance ... + double riskAmount; + + // + // Use Provided Risk Amount as Static Volume ... + bool useRiskAmountAsStaticVolume; + + // + // Provider ... + XSCX121Provider *provider; +}; + +// +// END Definitions ... +// + +// +// START Usefull Functions ... +// + +// +// Add Specific Provider to List ... +void Add( + X121SignalProvider &item, // item want to add + X121SignalProvider &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} + +// +// Generate Identifier Tag ... +string GenerateTag(X121SignalProvider &descriptor) +{ + // + string result = ""; + + // + result = descriptor.symbol + "," + ToString(descriptor.period); + + // + return result; +} + +// +// Converts a Signal provider to String ... +string ToString(ENUM_X121_SIGNAL_PROVIDERS provider) +{ + return EnumToString(provider); +} + +// +// convert an String to Signal provider ... +ENUM_X121_SIGNAL_PROVIDERS ToProvider(string provider) +{ + // + ENUM_X121_SIGNAL_PROVIDERS result = NONE; + + // + if (ToString(NONE) == provider) + { + result = NONE; + } + else if (ToString(XTEST) == provider) + { + result = XTEST; + } + else if (ToString(X786) == provider) + { + result = X786; + } + else if (ToString(X92) == provider) + { + result = X92; + } + // else if (ToString(X110) == provider) + // { + // result = X110; + // } + // else if (ToString(X121) == provider) + // { + // result = X121; + // } + // else if (ToString(X128) == provider) + // { + // result = X128; + // } + + // + return result; +} + +// +// Extract Provider Type from Signal Commnet ... +ENUM_X121_SIGNAL_PROVIDERS ExtractPositionProvider(XPosition &position) +{ + // + ENUM_X121_SIGNAL_PROVIDERS result = NONE; + + // + string providerStr = + ExtractString( + position.comment, + XProviderToken + "(", + ")"); + if (StringLen(providerStr) <= 0) + { + return result; + } + + // + result = ToProvider(providerStr); + + // + return result; +} + +// +// List All Available Providers ... +void GetAllProviders( + ENUM_X121_SIGNAL_PROVIDERS &result[] // Hold Result ... +) +{ + // + Clean(result); + + // + // XTEST ... + ArrayResize( + result, + ArraySize(result) + 1); + result[ArraySize(result) - 1] = XTEST; + + // + // X786 ... + ArrayResize( + result, + ArraySize(result) + 1); + result[ArraySize(result) - 1] = X786; + + // + // X92 ... + ArrayResize( + result, + ArraySize(result) + 1); + result[ArraySize(result) - 1] = X92; + + // // + // // X110 ... + // ArrayResize( + // result, + // ArraySize(result) + 1); + // result[ArraySize(result) - 1] = X110; + + // // + // // X121 ... + // ArrayResize( + // result, + // ArraySize(result) + 1); + // result[ArraySize(result) - 1] = X121; + + // // + // // X128 ... + // ArrayResize( + // result, + // ArraySize(result) + 1); + // result[ArraySize(result) - 1] = X128; +} + +// +// Lis All Available Providers ... +void GetAllProviders( + string &result[] // Hold Result ... +) +{ + // + Clean(result); + + // + ENUM_X121_SIGNAL_PROVIDERS providers[]; + GetAllProviders(providers); + int providersCount = ArraySize(providers); + if (providersCount <= 0) + { + return; + } + + // + for (int i = 0; i < providersCount; i++) + { + // + ENUM_X121_SIGNAL_PROVIDERS iProvider = providers[i]; + + // + Add( + ToString(iProvider), + result); + } +} + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/X121/14030217/Classes/x-saherelm.x121.xea.class.ex5 b/MQLTestWorkspace/X121/14030217/Classes/x-saherelm.x121.xea.class.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..dfd424629ac9e4996fbc689a6725b42f740dca98 GIT binary patch literal 11500 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 CffZx` literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/X121/14030217/Classes/x-saherelm.x121.xea.class.mq5 b/MQLTestWorkspace/X121/14030217/Classes/x-saherelm.x121.xea.class.mq5 new file mode 100644 index 0000000..b5aed47 --- /dev/null +++ b/MQLTestWorkspace/X121/14030217/Classes/x-saherelm.x121.xea.class.mq5 @@ -0,0 +1,1711 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCX121EA +// Description: an Expert Class which +// used X121 Setup ... +// +// +// 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 + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Classes/x-saherelm.xea.class.mq5" +#include "../Libraries/x-saherelm.x121.draw.lib.mq5" +#include "../Classes/x-saherelm.x121.provider.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Definitions ... +// + +// +// END Definitions ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// an Expert Advisor Class by X121Provider ... +class XSCX121EA : public XSCBaseEA +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructor ... + void XSCX121EA( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Time Frame + ulong magic, // Magic Number + int slippage, // Slippgae + double minProfitPerTrade, // Min Profit Per Trade based On Volume Factor (Hedge) + double minProfitPerVolumeFactor, // Min Volume Factor for Calculating Profit (Hedge) + TOnStopLoss onStopLossTriggered = NULL, // On StopLoass Triggered Event Handler + TOnTakeProfit onTakeProfitTriggered = NULL, // On TakeProfit Triggered Event Handler + TOnDealsChanged onDealsChangedHandler = NULL, // On Deals Changed Event Handler + TOnOrdersChanged onOrdersChangedHandler = NULL, // On Orders Changed Event Handler + TOnPositionsChanged onPositionsChangedHandler = NULL, // On Positions Changed Event Handler + TOnTradeStateChanged onTradeStateChangedHandler = NULL, // On Trade State Changed Event Handler + TOnSignalConditions onSignalConditions = NULL // On SignalConditions Event Handler + ) : XSCBaseEA(symbol, + period, + magic, + slippage, + onStopLossTriggered, + onTakeProfitTriggered, + onDealsChangedHandler, + onOrdersChangedHandler, + onPositionsChangedHandler, + onTradeStateChangedHandler) + { + // + mOnSignalConditions = onSignalConditions; + + // + mMinProfitPerTrade = minProfitPerTrade; + mMinProfitPerVolumeFactor = minProfitPerVolumeFactor; + } + + // + // DeConstructor ... + void ~XSCX121EA() + { + // + // Delete All Registered Providers ... + int providersCount = ArraySize(mProviders); + if (providersCount > 0) + { + // + for (int i = 0; i < providersCount; i++) + { + // + X121SignalProvider iProvider = mProviders[i]; + + // + delete iProvider.provider; + } + } + } + + // + // START Properties ... + // + + // + // Min Profit Per Trade ... + + // + bool MinProfitPerTrade(double value) + { + // + bool result = false; + + // + if (value <= 0) + { + return result; + } + + // + result = value > 0; + if (value == mMinProfitPerTrade) + { + return result; + } + + // + mMinProfitPerTrade = value; + + // + return result; + } + + // + double MinProfitPerTrade() + { + return mMinProfitPerTrade; + } + + // + // Min Profit Per Volume Factor ... + + // + bool MinProfitPerVolumeFactor(double value) + { + // + bool result = false; + + // + if (value <= 0) + { + return result; + } + + // + result = value > 0; + if (value == mMinProfitPerVolumeFactor) + { + return result; + } + + // + mMinProfitPerVolumeFactor = value; + + // + return result; + } + + // + double MinProfitPerVolumeFactor() + { + return mMinProfitPerVolumeFactor; + } + + // + // Add Provider ... + bool AddProvider( + X121SignalProvider &provider // Specific Provider ... + ) + { + // + bool result = false; + + // + // Validate Provider ... + if (provider.symbol == NULL || + provider.period == NULL || + provider.riskAmount <= 0 || + StringLen(provider.symbol) == 0 || + ArraySize(provider.providers) == 0) + { + return result; + } + + // + // Check Exists or not ... + int idx = GetProviderIndex( + provider.symbol, + provider.period); + if (idx >= 0) + { + return result; + } + + // + PrepareProviderConfig(); + + // + // Make Instance of X121Provider Class ... + provider.provider = new XSCX121Provider( + provider.symbol, + provider.period); + + // + // Attach Event Listener ... + if (mOnSignalConditions != NULL) + { + // + // Attach Event Handlers ... + provider.provider.AddOnSignalConditionEventHandler(mOnSignalConditions); + } + + // + // Set Signallers to Provider Class ... + result = provider.provider.SetSignallers(provider.providers); + if (!result) + { + return result; + } + + // + // Initialize Provider ... + result = provider.provider.SetConfig(mProviderConfig); + + // + // Add Prepared Provider to Providers ... + Add( + provider, + mProviders); + + // + return result; + } + + // + // Add Providers ... + int AddProviders( + X121SignalProvider &providers[] // Specific Providers ... + ) + { + // + int result = 0; + + // + int providersCount = ArraySize(providers); + if (providersCount <= 0) + { + return result; + } + + // + for (int i = 0; i < providersCount; i++) + { + // + X121SignalProvider iProvider = providers[i]; + + // + bool isAdded = AddProvider(iProvider); + if (isAdded) + { + result++; + } + } + + // + return result; + } + + // + // END Properties ... + // + + // + // START Overrides ... + // + + // + void OnPositionsChangedHandler(int count) + { + } + + // + // Handle TakeProfit Event ... + void OnTakeProfitTriggered(const XDeal &deal) + { + // + // Since we Use Hedge in Min Profit ... + // Some times a Position Modified and SL Trails ... + // this Position closed through sl Event ... + // here we Must Close positions's Pack Orders ... + + // + // So We Have to Get Positions Pack ... + XPositionPack dealPack; + bool hasPack = mTrader.GetDealPack( + deal, + dealPack); + if (hasPack) + { + HandleClosePack(dealPack); + } + } + + // + // Handle StopLoss Event ... + void OnStopLossTriggered(const XDeal &deal) + { + // + // Since we Use Hedge in Min Profit ... + // Some times a Position Modified and SL Trails ... + // this Position closed through sl Event ... + // here we Must Close positions's Pack Orders ... + + // + // So We Have to Get Positions Pack ... + XPositionPack dealPack; + bool hasPack = mTrader.GetDealPack( + deal, + dealPack); + if (hasPack) + { + HandleClosePack(dealPack); + } + } + + // + // END Overrides ... + // + + // + // START Inheritance Functions ... + // + + // + void PrepareTag() + { + mTag = "X121EA:" + mSymbol + "," + ToString(mPeriod) + (string)mMagic; + } + + // + // Check Providers Guard States ... + bool CheckGuard(XGuard &guards[]) + { + // + bool result = false; + + // + Clean(guards); + + // + // Positions Management ... + HandlePositionManagement(); + + // + int providersCount = ArraySize(mProviders); + if (providersCount <= 0) + { + return result; + } + + // + for (int i = 0; i < providersCount; i++) + { + // + X121SignalProvider iProvider = mProviders[i]; + + // + XGuard iGuards[]; + bool iHasGuard = iProvider.provider.GuardCheck(iGuards); + if (iHasGuard) + { + // + Copy( + iGuards, + guards, + false); + } + } + + // + // Here we Can Implement Custom Guards Senario ... + + // + // Do Management Equity ... + HandleEquityManagement(); + + // + result = ArraySize(guards) > 0; + + // + return result; + } + + // + // Check Providers for Signals ... + bool SignalCheck(XSignal &signals[]) + { + // + bool result = false; + + // + Clean(signals); + + // + // Since We may have Custom Supporting Senarios for Positions + // if there is no Equity or Positions Count Passed ... + // we Clear Account Policies Check here and do it after + // recieveing Signals ... + + // + // Check Providers Count ... + int providersCount = ArraySize(mProviders); + if (providersCount <= 0) + { + return result; + } + + // + // Loop through Providers to Recieve Market Sence based on each them ... + for (int i = 0; i < providersCount; i++) + { + // + // Get provider Descriptor Struct ... + X121SignalProvider iProvider = mProviders[i]; + + // + // Check Provider Pivot Point Ready ... + int iFoundedPivots = iProvider.provider.CountPivots(); + int iReuiredPivots = iProvider.provider.GetMinPivots(); + if (iFoundedPivots < iReuiredPivots) + { + // + // Start Retrieveing Pivot Points ... + iProvider.provider.ProccessPivotPoints(); + + // + // ignore Calculating Signals since Pivot Points recieved ... + continue; + } + + // + // Retrieve Market Consitions from Specified Provider ... + X121MarketConditions iConditions; + bool iHasSignal = iProvider.provider.ProcessTick(iConditions); + + // + // Check there is Signal or not ... + if (iHasSignal && iConditions.hasSignal) + { + // + // Check Signalling is Enabled by Signal type ... + bool isiSignalLong = IsLong(iConditions.signal.type); + if ((isiSignalLong && !mEnableLongs) || + (!isiSignalLong && !mEnableShorts)) + { + continue; + } + + // + // Here we Calculate Signals tp/sl volume and etc based on given + // configurations ... + PrepareConditionsSignal(iConditions); + + // + // Add Signal to Retrieved Signals Collection ... + Add( + iConditions.signal, + signals); + } + } + + // + // Here we proccess all Exists Registered Providers and get + // probably signals and add them signals Array ... + + // + // Check Signals Exists for Processing ... + result = ArraySize(signals) > 0; + + // + // IMPORTANT: + // Since we have to Implement our Signal Execution Senario + // Ignore this here for Default behaviour and implememt or Execution ... + if (result) + { + // + // Create an Array for Holding Allowed To Execute Signals ... + // this filled by given Signals from all providers ... + XSignal allowedSignals[]; + + // + // Check Account has required Equity for open Trades or not ... + bool hasEquity = CheckEquityForTrade(); + if (hasEquity) + { + // + // if Equity Exists ... + + // + // Check Positions Count ... + XPosition positions[]; + int positionsCount = GetPositions(positions); + + // + // Calculate Remained Positions based on configurations ... + int remainedPositionsCount = mMaxAllowedPositions - positionsCount; + + // + int incommingSignalsCount = ArraySize(signals); + + // + // Check incomming signals and remained Positions count ... + if (remainedPositionsCount >= incommingSignalsCount) + { + // + // Since we have necessary Equity for Trade ... + // and also remainedPositions count is bigger than incomming signals ... + // Accept all incomming Signals ... + Copy( + signals, + allowedSignals); + } + else + { + // + // since we have necessary Equity for trade ... + // but incomming Signals count is bigger than Max allowed positions at same time ... + // we have to select only remains count ... + for (int i = 0; i < remainedPositionsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + Add( + iSignal, + allowedSignals); + } + } + } + else + { + // + // there isn't enough Equity for Trade ... + // How to Select Signals when there is no Equity for Trade ... + + // + // TODO: we can Implement Equity Management here ... + + // + LogMessage("No Equity ..."); + } + + // + // Check Allowed Signals Count ... + int allowedSignalsCount = ArraySize(allowedSignals); + if (allowedSignalsCount > 0) + { + // + // Prepare Allowed Signals for Execution ... + PrepareSignals(allowedSignals); + + // + // Execute Signals oly when allowed ... + int executed = mTrader.ExecuteSignals(allowedSignals); + if (executed > 0) + { + // + // Draw Signal ... + // On Chart ... + DrawSignals( + allowedSignals, + true); + } + } + + // + // Prevent Default Base Signal Execution ... + + // + Clean(signals); + + // + return false; + } + + // + return result; + } + + // + // END Inheritance Functions ... + // + + // + // START Provided Actions ... + // + + // + // END Provided Actions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + X121SignalProvider mProviders[]; + X121ProviderInputs mProviderConfig; + TOnSignalConditions mOnSignalConditions; + + // + double mMinProfitPerTrade; + double mMinProfitPerVolumeFactor; + + // + // Actions ... + + // + // Pepare a Collection Of Signals ... + void PrepareSignals(XSignal &signals[]) + { + // + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return; + } + + // + for (int i = 0; i < signalsCount; i++) + { + // + PrepareSignal(signals[i]); + } + } + + // + // POSITIONPACK ... + + // + // Check a Position Pack is Ready for Hedging ... + bool IsReadyForEQMHedge(XPositionPack &pack) + { + // + bool result = false; + + // + if (mMinProfitPerTrade <= 0 || + mMinProfitPerVolumeFactor <= 0) + { + return result; + } + + // + if (pack.supportPositionsCount <= 0) + { + return result; + } + + // + double profit = pack.position.profit; + double requiredProfit = + ((pack.position.volume / mMinProfitPerVolumeFactor) * + mMinProfitPerTrade) + + (-1 * pack.position.swap); + + // + for (int i = 0; i < pack.supportPositionsCount; i++) + { + // + XPosition iPosition = pack.supportPositions[i]; + + // + profit += iPosition.profit; + requiredProfit += + ((iPosition.volume / mMinProfitPerVolumeFactor) * + mMinProfitPerTrade) + + (-1 * iPosition.swap); + } + + // + result = profit >= requiredProfit; + + // + return result; + } + + // + // Close a Position Pack and Cancel All of it's Supports ... + bool HandleClosePack(XPositionPack &pack) + { + // + bool result = false; + + // + if (pack.ticket <= 0) + { + return result; + } + + // + XOrder orders[]; + XPosition positions[]; + + // + bool hasPos = pack.position.ticket > 0; + if (hasPos) + { + Add( + pack.position, + positions); + } + + // + bool hasSupportPos = pack.supportPositionsCount > 0; + if (hasSupportPos) + { + // + Copy( + pack.supportPositions, + positions, + false); + } + + // + bool hasSupportOrd = pack.supportOrdersCount > 0; + if (hasSupportOrd) + { + // + Copy( + pack.supportOrders, + orders); + } + + // + string comment = "EQM Close Pack"; + + // + int closed = mTrader.ClosePositions(positions, comment); + int canceled = mTrader.CancelOrders(orders); + + // + result = closed + canceled == ArraySize(orders) + ArraySize(positions); + if (result) + { + // + string message = "EQM Close Position(" + ToString(pack.ticket) + ")'s Pack ..."; + + // + LogMessage(message); + } + + // + return result; + } + + // + // POSITIONMANAGEMENT ... + // + + // + // Calculate Positions Profit Summary ... + double CalculatePositionsProfit( + XPosition &positions[] // Source + ) + { + // + double result = 0; + + // + int positionsCount = ArraySize(positions); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + result += iPosition.profit; + } + + // + return result; + } + + // + // Calculate Required Profit for Hedging ... + double CalculateRequiredProfitForHedge( + XPosition &positions[] // Source + ) + { + // + double result = 0; + + // + int positionsCount = ArraySize(positions); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + result += + ((iPosition.volume / mMinProfitPerVolumeFactor) * + mMinProfitPerTrade) + + (-1 * iPosition.swap); + } + + // + return result; + } + + // + // Manage Positions ... + void HandlePositionManagement() + { + // + // HandleHedgePositionPacks(); + + // + // HandleHedgePositions(); + + // + HandleCloseOrTrailStopMinProfitPositions(); + } + + // + void HandleHedgePositions() + { + // + bool isReady = IsPositionsReadyForEQMHedge(); + if (!isReady) + { + return; + } + + // + XPosition positions[]; + int positionsCount = GetPositions(positions); + + // + string comment = "EQM Hedge Positions ..."; + + // + int closed = mTrader.ClosePositions( + positions, + comment); + bool isClosed = closed == positionsCount; + if (isClosed) + { + // + LogMessage(comment); + } + } + + // + // Close a Position Pack Wen Reached to Specific Profit ... + void HandleHedgePositionPacks() + { + // + XPosition positions[]; + int positionsCount = GetPositions(positions); + if (positionsCount <= 0) + { + return; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + XPositionPack iPack; + bool hasPack = mTrader.GetPositionPack( + iPosition.ticket, + iPosition.symbol, + iPosition.period, + iPack); + if (!hasPack) + { + continue; + } + + // + // Check Pack for Open Positions ... + bool isValidPack = iPack.supportPositionsCount > 0; + if (!isValidPack) + { + continue; + } + + // + // we sure a Position has Support and it's support open ... + bool isReady = IsReadyForEQMHedge(iPack); + if (!isReady) + { + continue; + } + + // + bool isClosed = HandleClosePack(iPack); + } + } + + // + // Try to Trail StopLoss or Close Posititons + // when reached Min Profit ... + void HandleCloseOrTrailStopMinProfitPositions() + { + // + // Retrieve In Profit Positions ... + XPosition positions[]; + int positionsCount = GetInProfitPositions(positions); + if (positionsCount <= 0) + { + return; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + // Now we have to Calculate min Profit ... + double requiredProfit = + ((iPosition.volume / mMinProfitPerVolumeFactor) * + mMinProfitPerTrade) + + (-1 * iPosition.swap); + + // + // Now we Have to Check if Trailed Before or not ... + int trailLevel = ExtractSLTrailLevel(iPosition.comment); + if (trailLevel > 0) + { + requiredProfit *= (trailLevel + 1); + } + + // + // Check Can Trail or Close on Min Profit ... + bool conditionsPassed = iPosition.profit >= requiredProfit; + if (!conditionsPassed) + { + continue; + } + + // + // Now we have Sure iPosition is Ready for Trailing Stop or Close on Min Profit ... + bool isLong = IsLong(iPosition.type); + + // + // CASE A try to Trail Stop ... + double sl = 0; + double distance = 0; + if ((isLong && (iPosition.price > iPosition.entry && + iPosition.entry > iPosition.sl)) || + (!isLong && (iPosition.price < iPosition.entry && + iPosition.entry < iPosition.sl))) + { + // + // First Trail ... + + // + distance = isLong + ? iPosition.price - iPosition.entry + : iPosition.entry - iPosition.price; + + // + sl = iPosition.entry; + } + else if ((isLong && (iPosition.price > iPosition.sl && + iPosition.entry <= iPosition.sl)) || + (!isLong && (iPosition.price < iPosition.sl && + iPosition.entry >= iPosition.sl))) + { + // + // Trailed Before ... + + // + distance = isLong + ? iPosition.price - iPosition.entry + : iPosition.entry - iPosition.price; + + // + sl = isLong + ? iPosition.sl + distance + : iPosition.sl - distance; + } + + // + // Check Main Selected Position is Support of another Position or not ... + string params[]; + bool isSupport = ExtractSupportParams( + iPosition.comment, + params); + + // + bool isTrailed = false; + bool canTrail = !isSupport && sl > 0 && distance > 0; + if (canTrail) + { + // + string comment = PrepareSLTrailComment(iPosition.comment); + + // + isTrailed = mTrader.Modify( + iPosition.ticket, + sl, + iPosition.tp); + } + if (isTrailed) + { + // + string message = "EQM Trail Position(" + ToString(iPosition.ticket) + ")'s Stop Loss ..."; + + // + LogMessage(message); + + // + continue; + } + + // + // CASE B if not Trail, Close it in Min Profit ... + string comment = "EQM Close Min Profit ..."; + + // + // Check Position has Pack Or Not ... + // if has Pack must Close Pack ... + // if not, Close position itself ... + XPositionPack iPack; + bool hasPack = mTrader.GetPositionPack( + iPosition.ticket, + iPosition.symbol, + iPosition.period, + iPack); + if (hasPack) + { + // + HandleClosePack(iPack); + } + else + { + // + if (!isSupport) + { + // + bool isClosed = mTrader.Close( + iPosition.ticket, + comment); + if (isClosed) + { + // + string message = "EQM Close Position(" + ToString(iPosition.ticket) + ") In Min Profit: " + ToString(iPosition.profit); + + // + LogMessage(message); + } + } + } + } + } + + // + // Check Positions is Ready fro Hedging ... + bool IsPositionsReadyForEQMHedge() + { + // + bool result = false; + + // + if (mMinProfitPerTrade <= 0 || + mMinProfitPerVolumeFactor <= 0) + { + return result; + } + + // + double profit = 0; + double requiredProfit = 0; + + // + XPosition positions[]; + int positionsCount = GetPositions(positions); + if (positionsCount <= 1) + { + return result; + } + + // + profit = CalculatePositionsProfit(positions); + requiredProfit = CalculateRequiredProfitForHedge(positions); + + // + result = profit >= requiredProfit; + + // + return result; + } + + // + // EQUITYMANAGEMENT ... + // + + // + // All available Equity Actions Implemented here ... + void HandleEquityManagement() + { + // + // TODO: Complete this ... + } + + // + // Retrieve All EQM Placed Support Orders ... + int GetEQMOrders( + XOrder &orders[] // Hold Result + ) + { + // + int result = 0; + + // + XOrder allOrders[]; + int allOrdersCount = GetOrders(allOrders); + if (allOrdersCount <= 0) + { + return result; + } + + // + // Extract EQM Orders ... + result = GetEQMSupportOrders( + orders, + allOrders); + + // + return result; + } + + // + // Retrieve All EQM Support Positions ... + int GetEQMPositions( + XPosition &positions[] // Hold Result + ) + { + // + int result = 0; + + // + XPosition allPositions[]; + int allPositionsCount = GetPositions(allPositions); + if (allPositionsCount <= 0) + { + return result; + } + + // + // Extract EQM Positions ... + result = GetEQMSupportPositions( + positions, + allPositions); + + // + return result; + } + + // + // Cancel all EQM Placed Support Orders ... + bool CancelAllEQMOrders() + { + // + bool result = false; + + // + XOrder eqmOrders[]; + int eqmOrdersCount = GetEQMOrders(eqmOrders); + if (eqmOrdersCount <= 0) + { + return result; + } + + // + result = mTrader.CancelOrders(eqmOrders); + + // + return result; + } + + // + // Generate EQM Support Signals ... + int GenerateEQMSupports( + XSignal &supports[] // Holds Supports + ) + { + // + int result = 0; + + // + // Clean result Array ... + Clean(supports); + + // + // Since we Generate Support Signals based on Max In Drawdown Positions ... + // we hae to Find it and then find it's Related Provider ... + // then recieve Market Conditions based on it's Signaller's Provider ... + // then try to Generate Supports ... + XPosition inDrawdownPositions[]; + int inDrawdownPositionsCount = GetInDrawdownPositions( + inDrawdownPositions, + NULL, // All Symbols ... + NULL, // All TYpe Of Positions ... + NULL, // All Periods ... + NULL, // All Providers ... + X_POSITION_SELECT_MAX // we need Max InDrawdown ... + ); + if (inDrawdownPositionsCount <= 0) + { + return result; + } + + // + // Since We Select Max here ... + // and also check count ... + // just Recieve Max In DD Position ... + XPosition maxInDDPosition = inDrawdownPositions[0]; + + // + // Here we can Select Provider based on InDD Position ... + int providerIDX = GetProviderIndex( + maxInDDPosition.symbol, + maxInDDPosition.period); + + // + // Validate Index ... + if (providerIDX <= -1) + { + return result; + } + + // + // Retrieve Market Conditions Based on Specific Provider ... + X121MarketConditions conditions = mProviders[providerIDX] + .provider + .GetMarketConditions(0); + + // + // Here we have multiple Senarios for Supporting ... + + // + // Support Using Peaks and Vales ... + // in this Senario we Place Two Order on Peaks and Vales ... + + // + // Peaks ... + XSignal pSignal; + // TODO: Implwmwnr this ... + + // + // Vales ... + XSignal vSignal; + // TODO: Implwmwnr this ... + + // + result = ArraySize(supports); + + // + return result; + } + + // + // Count all open Positions Volume for supports ... + double GetEQMSupportVolume() + { + // + double result = 0; + + // + // Retrieve Positions ... + XPosition positions[]; + int positionsCount = GetPositions(positions); + if (positionsCount <= 0) + { + return result; + } + + // + // Retrieve EQM Positions and Check ... + // if it's count bigger than 0 means there are an Open + // EQM Support Position and we do not have to do anything ... + XPosition eqmPositions[]; + int eqmPositionsCount = GetEQMPositions(eqmPositions); + if (eqmPositionsCount > 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + result += iPosition.volume; + } + + // + // Multiply Volume Summary ... + // TODO: Make it Configurable ... + result *= 1.5; + + // + return result; + } + + // + // Check Account is Ready for EQM Hedge or not ... + bool IsReadyForEQMHedge() + { + // + bool result = false; + + // + // Check required Inputs ... + if (mMinProfitPerTrade <= 0 || + mMinProfitPerVolumeFactor <= 0) + { + return result; + } + + // + // Check at least One EQM Support Position must be Open ... + XPosition eqmPositions[]; + int eqmPositionsCount = GetEQMPositions(eqmPositions); + if (eqmPositionsCount <= 0) + { + return result; + } + + // + // Get All Open Positions for Calculate Account Profit ... + XPosition positions[]; + int positionsCount = GetPositions( + positions); + if (positionsCount <= 0) + { + return result; + } + + // + // Define Factor Variables ... + double profit = 0; + double requiredProfit = 0; + + // + // Calculate Account Profit Factors ... + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + profit += iPosition.profit; + requiredProfit += + ((iPosition.volume / mMinProfitPerVolumeFactor) * + mMinProfitPerTrade) + + (-1 * iPosition.swap); + } + + // + // Calculate the result ... + result = profit >= requiredProfit; + + // + return result; + } + + // + // PROVIDERS ... + // + + // + // Find Specific Provider Index by using give symbol and period ... + int GetProviderIndex( + string symbol, // Trading Symbol ... + ENUM_TIMEFRAMES period // Trading Time frame ... + ) + { + // + int result = -1; + + // + // Validate Args ... + if (period == NULL || + symbol == NULL || + StringLen(symbol) == 0) + { + return result; + } + + // + int providersCount = ArraySize(mProviders); + if (providersCount <= 0) + { + return result; + } + + // + for (int i = 0; i < providersCount; i++) + { + // + X121SignalProvider iProvider = mProviders[i]; + + // + if (iProvider.symbol == symbol && iProvider.period == period) + { + // + result = i; + break; + } + } + + // + return result; + } + + // + // Prepare Default Configurations for X121Provider Setup ... + void PrepareProviderConfig() + { + // + // Set Default X121 Provider Configurations ... + + // + // XMAN ... + + // + // Candle Timer ... + mProviderConfig.xmanConfig.candleTimerColor = clrGold; + mProviderConfig.xmanConfig.candleTimerCorner = CORNER_RIGHT_UPPER; + + // + // Chart Style ... + mProviderConfig.xmanConfig.upColor = clrLime; + mProviderConfig.xmanConfig.downColor = clrRed; + mProviderConfig.xmanConfig.lineColor = clrLime; + mProviderConfig.xmanConfig.bearishColor = clrRed; + mProviderConfig.xmanConfig.bullishColor = clrLime; + mProviderConfig.xmanConfig.volumesColor = clrGreen; + mProviderConfig.xmanConfig.chartMode = CHART_CANDLES; + + // + // Market Cycles ... + + // + // Level 1 ... + mProviderConfig.xmanConfig.l1Method = X_PERIOD_AUTO; + mProviderConfig.xmanConfig.l1Period = NULL; + + // + // Level 1 ... + mProviderConfig.xmanConfig.l2Method = X_PERIOD_AUTO; + mProviderConfig.xmanConfig.l2Period = NULL; + + // + // Level 1 ... + mProviderConfig.xmanConfig.l3Method = X_PERIOD_AUTO; + mProviderConfig.xmanConfig.l3Period = NULL; + + // + // Level 1 ... + mProviderConfig.xmanConfig.l4Method = X_PERIOD_AUTO; + mProviderConfig.xmanConfig.l4Period = NULL; + + // + // Fibonacci ... + mProviderConfig.xmanConfig.fiboLevel1 = 0.236; + mProviderConfig.xmanConfig.fiboLevel2 = 0.382; + mProviderConfig.xmanConfig.fiboLevel3 = 0.5; + mProviderConfig.xmanConfig.fiboLevel4 = 0.618; + mProviderConfig.xmanConfig.fiboLevel5 = 0.764; + + // + // Boundary Detection Modes ... + mProviderConfig.xmanConfig.hhMode = MODE_HIGH; + mProviderConfig.xmanConfig.llMode = MODE_LOW; + + // + // Trend Detection ... + mProviderConfig.xmanConfig.trendMultiplier = 3; + mProviderConfig.xmanConfig.trendPriceAppliedTo = PRICE_MEDIAN; + + // + // Ribbon Detection ... + mProviderConfig.xmanConfig.ribbonMode = X_MA_AMA; + + // + // Hull Trend Detection ... + mProviderConfig.xmanConfig.hullDivisor = 2.0; + mProviderConfig.xmanConfig.hullUpAppliedTo = PRICE_HIGH; + mProviderConfig.xmanConfig.hullDownAppliedTo = PRICE_LOW; + + // + // SSL Channel ... + mProviderConfig.xmanConfig.sslcMode = X_MA_SMA; + mProviderConfig.xmanConfig.sslcUpAppliedTo = PRICE_HIGH; + mProviderConfig.xmanConfig.sslcDownAppliedTo = PRICE_LOW; + + // + // Presentation ... + // NOTE: Since we Configure Presentation on PreDefine Section ... + // here we turn of all Presentations as Default ... + mProviderConfig.xmanConfig.showCandleTimer = false; + mProviderConfig.xmanConfig.showCandles = false; + mProviderConfig.xmanConfig.showHKCandles = false; + mProviderConfig.xmanConfig.showSMHKCandles = false; + mProviderConfig.xmanConfig.showPeaksAndVales = false; + mProviderConfig.xmanConfig.showTrends = false; + mProviderConfig.xmanConfig.fillTrends = false; + mProviderConfig.xmanConfig.showLevels = false; + mProviderConfig.xmanConfig.showConsolidations = false; + mProviderConfig.xmanConfig.showRibbons = false; + mProviderConfig.xmanConfig.showHull = false; + mProviderConfig.xmanConfig.showSSLChannel = false; + mProviderConfig.xmanConfig.showFibo1Levels = false; + mProviderConfig.xmanConfig.showFibo2Levels = false; + mProviderConfig.xmanConfig.showFibo3Levels = false; + mProviderConfig.xmanConfig.showFibo4Levels = false; + mProviderConfig.xmanConfig.showFibo5Levels = false; + + // + PreDefineProviderConfig(); + } + + // + // Config Representation of X121 Provider Setup ... + // for Specified Strategies ... + void PreDefineProviderConfig() + { + // + // Here we have to Name or Predefined Styles ... + bool x786Config = true; + + // + // by default we need to Show Candles and also Candle Timer ... + mProviderConfig.xmanConfig.showCandles = true; + mProviderConfig.xmanConfig.showCandleTimer = true; + + // + // now we act based on Predefined Variables ... + if (x786Config) + { + // + bool showHK = true; + bool showPVs = true; + bool showFibo = true; + bool showHull = false; + bool showSSLC = false; + bool showTrend = true; + bool showRibbon = false; + bool showPVLevels = false; + bool showPVLevelConsolidations = false; + + // + mProviderConfig.xmanConfig.showCandles = !showHK; + mProviderConfig.xmanConfig.showHKCandles = showHK; + mProviderConfig.xmanConfig.showSMHKCandles = showHK; + + // + mProviderConfig.xmanConfig.showHull = showHull; + mProviderConfig.xmanConfig.showTrends = showTrend; + mProviderConfig.xmanConfig.showRibbons = showRibbon; + mProviderConfig.xmanConfig.showSSLChannel = showSSLC; + + // + mProviderConfig.xmanConfig.showFibo1Levels = showFibo; + mProviderConfig.xmanConfig.showFibo2Levels = showFibo; + mProviderConfig.xmanConfig.showFibo3Levels = showFibo; + mProviderConfig.xmanConfig.showFibo4Levels = showFibo; + mProviderConfig.xmanConfig.showFibo5Levels = showFibo; + + // + mProviderConfig.xmanConfig.showPeaksAndVales = showPVs; + + // + mProviderConfig.xmanConfig.showLevels = showPVLevels; + mProviderConfig.xmanConfig.showConsolidations = showPVLevelConsolidations; + } + } + + // + // Prepare Signal ... + void PrepareConditionsSignal(X121MarketConditions &conditions) + { + // + if (!conditions.hasSignal) + { + return; + } + + // + bool isLong = IsLong(conditions.signal.type); + + // + // Check Calculate TP ... + if ( + conditions.signal.sl > 0 && + conditions.signal.r2r > 0 && + conditions.signal.entry > 0 && + conditions.signal.calculateTP) + { + // + double riskPrice = MathAbs(conditions.signal.entry - conditions.signal.sl); + double riskPoint = PriceToPoint( + conditions.signal.symbol, + riskPrice); + double rewardPoint = riskPoint * conditions.signal.r2r; + double rewardPrice = PointToPrice( + conditions.signal.symbol, + rewardPoint); + + // + double tp = + isLong + ? conditions.signal.entry + rewardPrice + : conditions.signal.entry - rewardPrice; + + // + conditions.signal.tp = tp; + } + + // + PrepareSignal(conditions.signal); + + // + conditions.signal.supportAndResistance = conditions.supportResistances; + } + + // + // TODO: Delete This ... + void DrawConditionsSignalOnChart(X121MarketConditions &conditions) + { + // + ulong mTicket = MathRand() * 100000; + + // + DrawSignal( + mTicket, + conditions.signal); + + // + DrawSupportResistance( + 0, + conditions.supportResistances, + conditions.signal.providers[0]); + } +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/X121/14030217/Classes/x-saherelm.xaccount.class.ex5 b/MQLTestWorkspace/X121/14030217/Classes/x-saherelm.xaccount.class.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..ff66151b94511df9f6c9ec561648a1a32ce8820f GIT binary patch literal 7224 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 literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/X121/14030217/Classes/x-saherelm.xaccount.class.mq5 b/MQLTestWorkspace/X121/14030217/Classes/x-saherelm.xaccount.class.mq5 new file mode 100644 index 0000000..4425f0b --- /dev/null +++ b/MQLTestWorkspace/X121/14030217/Classes/x-saherelm.xaccount.class.mq5 @@ -0,0 +1,398 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCAccount +// Description: provides all Account requirements ... +// +// +// 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 + +// +// START Definitions ... +// + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Manage Account ... +class XSCAccount +{ + // + // Public ... +public: + // + // Constructor ... + void XSCAccount() + { + // + mAccountInfo = new CAccountInfo(); + } + + // + // Deconstructor ... + void ~XSCAccount() + { + } + + // + // START Provided Functions ... + // + + // + // User Account ... + long GetUserAccount() + { + return mAccountInfo.Login(); + } + + // + // Account Leverage ... + long GetLeverage() + { + return mAccountInfo.Leverage(); + } + + // + // Get Trade Expert State ... + bool CanExpertTrade() + { + return mAccountInfo.TradeExpert(); + } + + // + // User Account Trade Mopde (ENUM_ACCOUNT_TRADE_MODE) ... + // -------------------------- + // ACCOUNT_TRADE_MODE_DEMO + // ACCOUNT_TRADE_MODE_CONTEST + // ACCOUNT_TRADE_MODE_REAL + ENUM_ACCOUNT_TRADE_MODE GetTradeMode() + { + return mAccountInfo.TradeMode(); + } + + // + // Get Account Balance ... + double GetBalance() + { + return mAccountInfo.Balance(); + } + + // + // Get the amount of give Credit ... + double GetCredit() + { + return mAccountInfo.Credit(); + } + + // + // Get the amount of current Profit on account ... + double GetProfit() + { + return mAccountInfo.Profit(); + } + + // + // Get the amount of current Equity on account ... + double GetEquity() + { + return mAccountInfo.Equity(); + } + + // + // Get the amount of reserved Margin ... + double GetMargin() + { + return mAccountInfo.Margin(); + } + + // + // Get the amount of free Margin ... + double GetFreeMargin() + { + return mAccountInfo.FreeMargin(); + } + + // + // Get the Level of Margin ... + double GetMarginLevel() + { + return mAccountInfo.MarginLevel(); + } + + // + // Get the Level Of Margin for a Deposit ... + double GetMarginCall() + { + return mAccountInfo.MarginCall(); + } + + // + // Get the Level of Margin for Stop out ... + double GetMarginStopOut() + { + return mAccountInfo.MarginStopOut(); + } + + // + // Get the Client Name ... + string GetName() + { + return mAccountInfo.Name(); + } + + // + // Get the Trade Server Name ... + string GetServerName() + { + return mAccountInfo.Server(); + } + + // + // Get deposit Currency Name ... + string GetCurrency() + { + return mAccountInfo.Currency(); + } + + // + // Get the Company Name that serves an Account ... + string GetCompany() + { + return mAccountInfo.Company(); + } + + // + // Calculate Profits for the current account based on passed parameters ... + double CalculateTradeProfit( + const string symbol, // trading symbol + ENUM_ORDER_TYPE type, // order type + double volume, // volume + double entry, // open price + double exit // close price + ) + { + // + double result = mAccountInfo.OrderProfitCheck( + symbol, + type, + volume, + entry, + exit); + + // + return result; + } + + // + // Calculate amount of margin which required for trade operation ... + double CalculateMarging( + const string symbol, // trading symbol + ENUM_ORDER_TYPE type, // order type + double volume, // volume + double entry // open price + ) + { + // + double result = mAccountInfo.MarginCheck( + symbol, + type, + volume, + entry); + + // + return result; + } + + // + // Calculate amount of free margin left after trade operation ... + double CalculateFreeMarging( + const string symbol, // trading symbol + ENUM_ORDER_TYPE type, // order type + double volume, // volume + double entry // open price + ) + { + // + double result = mAccountInfo.FreeMarginCheck( + symbol, + type, + volume, + entry); + + // + return result; + } + + // + // Calculate the Maximum possible volume of trade operation ... + double CalculateMaxVolume( + const string symbol, // trading symbol + ENUM_ORDER_TYPE type, // order type + double entry, // open price + double percent = 100 // percent of available margin + ) + { + // + double result = mAccountInfo.MaxLotCheck( + symbol, + type, + entry, + percent); + + // + return result; + } + + // + // Calculate Point Value for Given Symbol based on Account ... + double GetPointValue( + string symbol // trading symbol + ) + { + // + double result = 0; + + // + double tickSize = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE); + double tickValue = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_VALUE); + double point = SymbolInfoDouble(symbol, SYMBOL_POINT); + + // + double ticksPerPoint = tickSize / point; + + // + result = tickValue / ticksPerPoint; + + // + return result; + } + + // + // Calculate Risk Amount based on account Currency by Providing: + // Points and Volume ... + double CalculateRiskAmount( + string symbol, // trading symbol + double points, // amount of Risk Points + double volume // position Volume + ) + { + // + double result = 0; + + // + double pointValue = GetPointValue(symbol); + + // + result = pointValue * volume * points; + + // + return result; + } + + // + // Calculate Risk Points based on account Currency by Providing: + // Volume and Amount ... + double CalculateRiskPoints( + string symbol, // trading symbol + double volume, // position Volume + double amount // amount of Risk based on Account Currency + ) + { + // + double result = 0; + + // + double pointValue = GetPointValue(symbol); + + // + result = amount / (pointValue * volume); + + // + return result; + } + + // + // Calculate Volume based on account Currency by Providing: + // Amount and Risk Points ... + double CalculateVolume( + string symbol, // trading symbol + double amount, // amount of Risk based on Account Currency + double points // amount of Risk Points + ) + { + // + double result = 0; + + // + points = + points <= 0 + ? 10 + : points; + + // + double pointValue = GetPointValue(symbol); + + // + result = amount / (pointValue * points); + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Account Info ... + CAccountInfo mAccountInfo; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/X121/14030217/Classes/x-saherelm.xea.class.ex5 b/MQLTestWorkspace/X121/14030217/Classes/x-saherelm.xea.class.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..3407d03e9855ecc789f96fa20c5fac29c88b812d GIT binary patch literal 11836 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 ak)m2CB=GvhkkFG2`Xftk=SbCZEdDQbCBuaP literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/X121/14030217/Classes/x-saherelm.xea.class.mq5 b/MQLTestWorkspace/X121/14030217/Classes/x-saherelm.xea.class.mq5 new file mode 100644 index 0000000..f8f1ea9 --- /dev/null +++ b/MQLTestWorkspace/X121/14030217/Classes/x-saherelm.xea.class.mq5 @@ -0,0 +1,1614 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCBaseEA +// Description: provides all Base EA requirements ... +// +// +// 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 + +// +// START Definitions ... +// + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.alert.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xtrade.class.mq5" +#include "../Classes/x-saherelm.xaccount.class.mq5" +#include "../Classes/x-saherelm.xprovider.class.mq5" +#include "../Libraries/x-saherelm.seriallizer.lib.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Handle base requirements ... +// for indicators ... +class XSCBaseEA +{ + // + // Public ... +public: + // + // Props ... + XSCTrade *mTrader; + XSCAccount *mAccount; + + // + bool isNewHour; + bool isNewDay; + bool isNewWeek; + bool isNewMonth; + bool isNewCandle; + + // + bool isInTestMode; + + // + bool mWaitsUntilNewCandle; + + // + // Constructor ... + void XSCBaseEA( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Time Frame + ulong magic, // Magic Number + int slippage, // Slippgae + TOnStopLoss onStopLossTriggered = NULL, // On StopLoass Triggered Event Handler + TOnTakeProfit onTakeProfitTriggered = NULL, // On TakeProfit Triggered Event Handler + TOnDealsChanged onDealsChangedHandler = NULL, // On Deals Changed Event Handler + TOnOrdersChanged onOrdersChangedHandler = NULL, // On Orders Changed Event Handler + TOnPositionsChanged onPositionsChangedHandler = NULL, // On Positions Changed Event Handler + TOnTradeStateChanged onTradeStateChangedHandler = NULL // On Trade State Changed Event Handler + ) + { + // + mSymbol = symbol; + mPeriod = period; + + // + mMagic = magic; + mSlippage = slippage; + + // + mOnStopLossTriggered = onStopLossTriggered; + mOnTakeProfitTriggered = onTakeProfitTriggered; + mOnDealsChangedHandler = onDealsChangedHandler; + mOnOrdersChangedHandler = onOrdersChangedHandler; + mOnPositionsChangedHandler = onPositionsChangedHandler; + mOnTradeStateChangedHandler = onTradeStateChangedHandler; + + // + // Reset Timings ... + ResetTiming(); + + // + EnableLongs(true); + EnableShorts(true); + + // + MaxAllowedPositions(0); + MaxAllowedDrawDownFactor(0); + + // + InitRequirements(); + } + + // + // Deconstructor ... + void ~XSCBaseEA() + { + // + delete mTrader; + delete mAccount; + } + + // + // START Properties ... + // + + // + // Symbol ... + string GetSymbol() + { + return mSymbol; + } + + // + // Period ... + ENUM_TIMEFRAMES GetPeriod() + { + return mPeriod; + } + + // + // Tag ... + string GetTag() + { + return mTag; + } + + // + ulong GetMagic() + { + return mMagic; + } + + // + int GetSlippage() + { + return mSlippage; + } + + // + // Check Long Signalling State ... + bool EnableLongs() + { + return mEnableLongs; + } + + // + // Set Long Signalling State ... + void EnableLongs(bool enable) + { + // + if (enable == mEnableLongs) + { + return; + } + + // + mEnableLongs = enable; + } + + // + // Check Short Signalling State ... + bool EnableShorts() + { + return mEnableShorts; + } + + // + // Set Short Signalling State ... + void EnableShorts(bool enable) + { + // + if (enable == mEnableShorts) + { + return; + } + + // + mEnableShorts = enable; + } + + // + // Get Max Allowed Positions at Same Time ... + int MaxAllowedPositions() + { + return mMaxAllowedPositions; + } + + // + // Set Max Allowed Positions at Same Time ... + void MaxAllowedPositions(int value) + { + // + if (value < 0 || + value == mMaxAllowedPositions) + { + return; + } + + // + mMaxAllowedPositions = value; + } + + // + // Get Max Allowed DrawDown Factor ... + double MaxAllowedDrawDownFactor() + { + return mMaxAllowedDrawDownFactor; + } + + // + // Set Max Allowed Positions at Same Time ... + void MaxAllowedDrawDownFactor(double value) + { + // + if (value < 0 || + value == mMaxAllowedDrawDownFactor) + { + return; + } + + // + mMaxAllowedDrawDownFactor = value; + } + + // + // Check Acocunt Balance is Allow new Trades or not ... + bool CheckEquityForTrade() + { + // + bool result = false; + + // + if (mMaxAllowedDrawDownFactor <= 0) + { + // + result = true; + return result; + } + + // + double equity = mAccount.GetEquity(); + double balance = mAccount.GetBalance(); + + // + double selectedBalance = MathMax(equity, balance) - MathMin(equity, balance); + + // + double balanceForFactor = MathAbs(equity - balance); + if (balanceForFactor <= 0) + { + balanceForFactor = balance; + } + else + { + balanceForFactor = equity; + } + + // + double maxAllowedBalanceDrawDown = balanceForFactor * mMaxAllowedDrawDownFactor; + + // + result = equity > balance || + (equity <= balance && + selectedBalance <= maxAllowedBalanceDrawDown); + + // + return result; + } + + // + // Check Max Allowed Positions Policy for Trade ... + bool ChecPositionsForTrade() + { + // + bool result = false; + + // + if (mMaxAllowedPositions <= 0) + { + // + result = true; + return result; + } + + // + int positionsCount = mTrader.CountPositions(); + if (positionsCount <= 0) + { + // + result = true; + return result; + } + + // + result = positionsCount <= mMaxAllowedPositions; + + // + return result; + } + + // + // Check Account Policies ... + bool CheckAccountPolicies() + { + // + bool result = false; + + // + // Check Equity for Trade ... + result = CheckEquityForTrade(); + if (!result) + { + // + string message = "not enough Equity for Trade ..."; + + // + LogMessage(message); + + // // + // // Handle Force Close Positions on Max Drawdown ... + // HandleGuardForceCloseAction( + // NULL, // All Providers ... + // NULL, // All Symbols ... + // NULL, // All Type of Positions ... + // NULL // All Periods ... + // ); + + // + return result; + } + + // + // Check Max Allowed Position for Trade ... + result = ChecPositionsForTrade(); + if (!result) + { + // + string message = "max allowed Positions reached ..."; + + // + LogMessage(message); + + // // + // HandleGuardCloseInProfitAction( + // NULL, // All Providers ... + // NULL, // All Symbols ... + // NULL, // All Type of Positions ... + // NULL, // All Periods ... + // X_POSITION_SELECT_MAX // Select Max Position ... + // ); + + // // + // HandleGuardCloseInDrawdownAction( + // NULL, // All Providers ... + // NULL, // All Symbols ... + // NULL, // All Type of Positions ... + // NULL, // All Periods ... + // X_POSITION_SELECT_MAX // Select Max Position ... + // ); + + // + return result; + } + + // + return result; + } + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XEA" + mSymbol + "," + ToString(mPeriod) + (string)mMagic; + } + + // + // Handle Chart Events ... + virtual void OnChartEvent( + const int id, // event ID + const long &lparam, // long type event parameter + const double &dparam, // double type event parameter + const string &sparam // string type event parameter + ) + { + } + + // + // Check any Registered Providers Signalling ... + virtual bool SignalCheck(XSignal &signals[]) + { + return false; + } + + // + // Check for any Custom Guard Actions Guard Actions ... + virtual bool CheckGuard(XGuard &guards[]) + { + return false; + } + + // + // NOTE: you have to call these Functions on Static Classes to Handle Works ... + + // + // Handle StopLoss Event ... + virtual void OnStopLossTriggered(const XDeal &deal) {} + + // + // Handle TakeProfit Event ... + virtual void OnTakeProfitTriggered(const XDeal &deal) {} + + // + // Handle Deals Changed Event ... + virtual void OnDealsChangedHandler(int count) {} + + // + // Handle Order Changed Event ... + virtual void OnOrdersChangedHandler(int count) {} + + // + // Handle Position Changed Event ... + virtual void OnPositionsChangedHandler(int count) {} + + // + // Handle Trade State Changed ... + virtual void OnTradeStateChangedHandler(const XOnTradeHandlerState &state) {} + + // + // Implemented Actions ... + + // + // OnTick Handler ... + void OnTick() + { + // + // First Check Guards .... + // Only when Open Positions Exists or Has Pending Order ... + XGuard guards[]; + bool hasGuard = CheckGuard(guards); + if (hasGuard) + { + DoGuards(guards); + } + + // + // Check Account Policies ... + bool isAccountPassed = CheckAccountPolicies(); + if (!isAccountPassed) + { + return; + } + + // + XSignal signals[]; + bool hasSignal = SignalCheck(signals); + if (hasSignal) + { + // + // Here we have to Check Signals and also it's State ... + XSignal enabledSignals[]; + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return; + } + + // + // Filter Signals by their type and + // also Check EA Enable their type ... + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + bool isLong = IsLong(iSignal.type); + if ((isLong && mEnableLongs) || + (!isLong && mEnableShorts)) + { + // + PrepareSignal(iSignal); + + // + Add( + iSignal, + enabledSignals); + } + } + + // + int enabledSignalsCount = ArraySize(enabledSignals); + if (enabledSignalsCount <= 0) + { + return; + } + + // + // Check Trade Policies ... + + // + // Check Equity for Trade ... + bool canDoTrade = CheckEquityForTrade(); + if (!canDoTrade) + { + // + string message = "not enough Equity for Trade ..."; + + // + LogMessage(message); + return; + } + + // + // Check Max Allowed Position for Trade ... + canDoTrade = ChecPositionsForTrade(); + if (!canDoTrade) + { + // + string message = "max allowed Positions reached ..."; + + // + LogMessage(message); + + // + // Check How to Act with Signals if Max In Drawdown Reached ... + // TODO: Here we Have to Define Max In Draw Down Position type ... + return; + } + + // + mTrader.ExecuteSignals(enabledSignals); + } + } + + // + // Handle On Trade ... + void OnTrade() + { + // + XOnTradeHandlerState state = mTrader.HandleOnTrade(); + + // + if ( + !state.hasNewDeal && + !state.hasNewOrder && + !state.hasNewPosition && + !state.hasNewHistoryOrder) + { + return; + } + + // + // STATE ... + + // + // Notfy Trade State Changed Event ... + OnTradeStateChangedHandler(state); + + // + // DEALS ... + if (state.hasNewDeal) + { + // + // Notfy Deals Changed Event ... + OnDealsChangedHandler(state.newDeals); + + // + // Retrieve Last Deal ... + XDeal deals[]; + mTrader.GetDeals(deals); + int dealsCount = ArraySize(deals); + if (dealsCount > 0) + { + // + XDeal lastDeal = deals[0]; + + // + if (lastDeal.reason == DEAL_REASON_TP) + { + OnTakeProfitTriggered(lastDeal); + } + else if (lastDeal.reason == DEAL_REASON_SL) + { + OnStopLossTriggered(lastDeal); + } + } + } + + // + // ORDERS ... + if (state.hasNewOrder || state.hasNewHistoryOrder) + { + // + // Notfy Orders Changed Event ... + OnOrdersChangedHandler(state.newOrders + state.newHistoryOrders); + } + + // + // POSITIONS ... + if (state.hasNewPosition) + { + // + // Notfy Positions Changed Event ... + OnPositionsChangedHandler(state.newPositions); + } + } + + // + // Retrieve Dept Of Market ... + void OnBookEvent(const string &symbol) + { + // + // TODO: Implement this ... + } + + // + // TOOLS ... + + // + // Prepare a Signal and Do Calculations ... + void PrepareSignal( + XSignal &signal // a Signal for Preparation ... + ) + { + // + // Calculate Volume ... + if (signal.useRiskAmountAsVolume && signal.riskAmount > 0) + { + signal.volume = signal.riskAmount; + } + else if ( + signal.sl > 0 && + signal.tp > 0 && + signal.volume == 0 && + signal.riskAmount > 0 && + !signal.useSupportAndResistance) + { + // + // Calculate Risk Point ... + double riskPoint = MathAbs(signal.entry - signal.sl); + riskPoint = PriceToPoint( + signal.symbol, + riskPoint); + + // + double volume = mAccount.CalculateVolume( + signal.symbol, + signal.riskAmount, + riskPoint); + + // + signal.volume = volume; + } + else if (signal.useSupportAndResistance) + { + // + // Calculate Everything using Supports and Resistances ... + // TODO: Implement Later ... + } + + // + if (signal.ignoreTP) + { + signal.tp = 0; + } + + // + if (signal.ignoreSL) + { + signal.sl = 0; + } + + // + // Normalize Signal ... + NormalizeSignal(signal); + } + + // + // Get All Open Trades ... + int GetPositions( + XPosition &result[], // Hold Result ... + string symbol = NULL, // Trading Symbol ... + ENUM_POSITION_TYPE type = NULL, // Trading Type ... + ENUM_TIMEFRAMES period = NULL, // Trading Period ... + string provider = NULL // Signal Provider ... + ) + { + // + int mResult = 0; + + // + Clean(result); + + // + bool hasSymbol = !(symbol == NULL || StringLen(symbol) == 0); + bool hasProvider = !(provider == NULL || StringLen(provider) == 0); + + // + int positionsCount = mTrader.CountPositions(); + if (positionsCount <= 0) + { + return mResult; + } + + // + XPosition positions[]; + mTrader.GetPositions( + positions, + symbol, + period); + positionsCount = ArraySize(positions); + if (positionsCount <= 0) + { + return mResult; + } + + // + if (!hasProvider && type == NULL) + { + // + Copy( + positions, + result); + + // + return ArraySize(result); + } + + // + if (type == NULL) + { + // + ArrayResize( + result, + ArraySize(positions)); + + // + for (int i = 0; i < positionsCount; i++) + { + // + Add( + positions[i], + result); + } + + // + return ArraySize(result); + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + string iProvider = ExtractProvider(iPosition.comment); + if (hasProvider && iProvider != provider) + { + continue; + } + + // + if (type == NULL || iPosition.type == type) + { + // + Add( + iPosition, + result); + } + } + + // + mResult = ArraySize(result); + + // + return mResult; + } + + // + // Get All In Profit Trades ... + int GetInProfitPositions( + XPosition &result[], // Hold Result ... + string symbol = NULL, // Trading Symbol ... + ENUM_POSITION_TYPE type = NULL, // Trading Type ... + ENUM_TIMEFRAMES period = NULL, // Trading Period ... + string provider = NULL, // Signal Provider ... + ENUM_X_POSITION_SELECT_METHODS method = NULL // Select Method ... + ) + { + // + int mResult = 0; + + // + Clean(result); + + // + if (method == NULL) + { + method = X_POSITION_SELECT_ALL; + } + + // + // Prevent Going Forwars Since selection type is NONE ... + if (method == X_POSITION_SELECT_NONE) + { + return mResult; + } + + // + bool isMinSelectable = method == X_POSITION_SELECT_MIN; + bool isMaxSelectable = method == X_POSITION_SELECT_MAX; + + // + XPosition positions[]; + GetPositions( + positions, + symbol, + type, + period, + provider); + int positionsCount = ArraySize(positions); + if (positionsCount <= 0) + { + return mResult; + } + + // + // Define Temp Position for Selecting Max Position ... + XPosition maxPos; + maxPos.profit = INVALID_HANDLE; + + // + // Define Temp Position for Selecting Min Position ... + XPosition minPos; + minPos.profit = INVALID_HANDLE; + + // + // Loop through available Positions for Selecting Positions ... + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + // Check Profit State ... + if (iPosition.profit <= 0) + { + continue; + } + + // + // Check Selection State ... + if (isMinSelectable) + { + // + if (minPos.profit == INVALID_HANDLE || + minPos.profit > iPosition.profit) + { + minPos = iPosition; + } + + // + continue; + } + else if (isMaxSelectable) + { + // + if (maxPos.profit == INVALID_HANDLE || + maxPos.profit < iPosition.profit) + { + maxPos = iPosition; + } + + // + continue; + } + else + { + // + Add( + iPosition, + result); + } + } + + // + // Add Selected Position if Provided to Results ... + if (isMinSelectable) + { + // + Add( + minPos, + result); + } + else if (isMaxSelectable) + { + // + Add( + maxPos, + result); + } + + // + mResult = ArraySize(result); + + // + return mResult; + } + + // + // Get All In Drawdown Trades ... + int GetInDrawdownPositions( + XPosition &result[], // Hold Result ... + string symbol = NULL, // Trading Symbol ... + ENUM_POSITION_TYPE type = NULL, // Trading Type ... + ENUM_TIMEFRAMES period = NULL, // Trading Period ... + string provider = NULL, // Signal Provider ... + ENUM_X_POSITION_SELECT_METHODS method = NULL // Select Method ... + ) + { + // + int mResult = 0; + + // + Clean(result); + + // + if (method == NULL) + { + method = X_POSITION_SELECT_ALL; + } + + // + // Prevent Going Forwars Since selection type is NONE ... + if (method == X_POSITION_SELECT_NONE) + { + return mResult; + } + + // + bool isMinSelectable = method == X_POSITION_SELECT_MIN; + bool isMaxSelectable = method == X_POSITION_SELECT_MAX; + + // + XPosition positions[]; + GetPositions( + positions, + symbol, + type, + period, + provider); + int positionsCount = ArraySize(positions); + if (positionsCount <= 0) + { + return mResult; + } + + // + // Define Temp Position for Selecting Max Position ... + XPosition maxPos; + maxPos.profit = INVALID_HANDLE; + + // + // Define Temp Position for Selecting Min Position ... + XPosition minPos; + minPos.profit = INVALID_HANDLE; + + // + // Loop through available Positions for Selecting Positions ... + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + // Check Profit State ... + if (iPosition.profit >= 0) + { + continue; + } + + // + // Check Selection State ... + if (isMinSelectable) + { + // + if (minPos.profit == INVALID_HANDLE || + minPos.profit < iPosition.profit) + { + minPos = iPosition; + } + + // + continue; + } + else if (isMaxSelectable) + { + // + if (maxPos.profit == INVALID_HANDLE || + maxPos.profit > iPosition.profit) + { + maxPos = iPosition; + } + + // + continue; + } + else + { + // + Add( + iPosition, + result); + } + } + + // + // Add Selected Position if Provided to Results ... + if (isMinSelectable) + { + // + Add( + minPos, + result); + } + else if (isMaxSelectable) + { + // + Add( + maxPos, + result); + } + + // + mResult = ArraySize(result); + + // + return mResult; + } + + // + // Retrieve Orders ... + int GetOrders( + XOrder &result[], // Hold Result ... + string symbol = NULL, // Trading Symbol ... + ENUM_ORDER_TYPE type = NULL, // Trading Type ... + ENUM_ORDER_STATE state = NULL, // Trading State ... + ENUM_TIMEFRAMES period = NULL, // Trading Period ... + string provider = NULL // Signal Provider ... + ) + { + // + int mResult = 0; + + // + Clean(result); + + // + XOrder orders[]; + mTrader.GetOrders( + orders, + symbol, + period, + state); + int ordersCount = ArraySize(orders); + if (ordersCount <= 0) + { + return mResult; + } + + // + if (type == NULL && + (provider == NULL || + StringLen(provider) == 0)) + { + // + Copy( + orders, + result); + + // + mResult = ArraySize(result); + + // + return mResult; + } + + // + for (int i = 0; i < ordersCount; i++) + { + // + XOrder iOrder = orders[i]; + + // + if (type != NULL && iOrder.type != type) + { + continue; + } + + // + if (provider != NULL && + StringLen(provider) > 0) + { + // + // Generate Order Provider ... + string iProvider = ExtractProvider(iOrder.comment); + if (iProvider != provider) + { + continue; + } + } + + // + Add( + iOrder, + result); + } + + // + mResult = ArraySize(result); + + // + return mResult; + } + + // + // GUARD Handlers ... + + // + // Parse Recievd Guards and Do them ... + void DoGuards(XGuard &guards[]) + { + // + int guardsCount = ArraySize(guards); + if (guardsCount <= 0) + { + return; + } + + // + for (int i = 0; i < guardsCount; i++) + { + // + XGuard iGuard = guards[i]; + + // + switch (iGuard.action) + { + // + // Hedge In Profit Specified Positions ... + case X_GUARD_ACTION_HEDGE: + HandleGuardHedgeAction( + iGuard.provider, + iGuard.symbol, + iGuard.type, + iGuard.period); + break; + + // + // Trail Stop Loss in Specified Positions ... + case X_GUARD_ACTION_TRAIL_STOP: + HandleGuardTrailingStopAction( + iGuard.provider, + iGuard.symbol, + iGuard.type, + iGuard.period, + iGuard.dblPayLoad); + break; + + // + // Force Close Specified Positions ... + case X_GUARD_ACTION_FORCE_CLOSE: + HandleGuardForceCloseAction( + iGuard.provider, + iGuard.symbol, + iGuard.type, + iGuard.period); + break; + + // + // Generate and Place Support Signals ... + case X_GUARD_ACTION_ADD_SUPPORT_SIGNAL: + HandleGuardAddSupportPositionAction( + iGuard.provider, + iGuard.symbol, + iGuard.type, + iGuard.period); + break; + + // + // Delete All Placed Pending Orders ... + case X_GUARD_ACTION_CANCEL_PENDING_ORDERS: + HandleGuardCancelPendingOrdersAction( + iGuard.provider, + iGuard.symbol, + iGuard.type, + iGuard.period); + break; + } + } + } + + // + // Close All Specified Provider's Positions in Profit Summary ... + void HandleGuardHedgeAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_POSITION_TYPE type, // Trading Type + ENUM_TIMEFRAMES period, // Specified Time Frame + double minProfitForHedging = 1 // Specified Profit for Hedge + ) + { + // + // TODO: Implement this ... + } + + // + // Close Max In Profit Trade Guard Action ... + void HandleGuardCloseInProfitAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_POSITION_TYPE type, // Trading Type + ENUM_TIMEFRAMES period, // Specified Time Frame + ENUM_X_POSITION_SELECT_METHODS method = NULL // Select Method + ) + { + // + XPosition positions[]; + GetInProfitPositions( + positions, + symbol, + type, + period, + provider, + method); + int positionsCount = ArraySize(positions); + if (positionsCount <= 0) + { + return; + } + + // + string comment = "Close InProfit ..."; + mTrader.ClosePositions( + positions, + comment); + + // + string message = "Guard Close (" + ToString(positionsCount) + ") Postion(s) In Profit ..."; + LogMessage(message); + } + + // + // Close Max In Drawdown Trade Guard Action ... + void HandleGuardCloseInDrawdownAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_POSITION_TYPE type, // Trading Type + ENUM_TIMEFRAMES period, // Specified Time Frame + ENUM_X_POSITION_SELECT_METHODS method = NULL // Select Method + ) + { + // + XPosition positions[]; + GetInDrawdownPositions( + positions, + symbol, + type, + period, + provider, + method); + int positionsCount = ArraySize(positions); + if (positionsCount <= 0) + { + return; + } + + // + string comment = "Close InDrawdown ..."; + mTrader.ClosePositions( + positions, + comment); + + // + string message = "Guard Close (" + ToString(positionsCount) + ") Position(s) In Drawdown ..."; + LogMessage(message); + } + + // + // Force Close Specified Set Of Position ... + void HandleGuardForceCloseAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_POSITION_TYPE type, // Trading Type + ENUM_TIMEFRAMES period, // Specified Time Frame + ulong ticket = 0 // Specific Ticket + ) + { + // + string comment = ""; + + // + // Close All Positions ... + if (ticket == 0) + { + // + XPosition positions[]; + GetPositions( + positions, + symbol, + type, + period, + provider); + if (ArraySize(positions) <= 0) + { + return; + } + + // + comment = provider + " Force Close Guard ..."; + + // + mTrader.ClosePositions( + positions, + comment); + } + // + // Close Specific Position ... + else + { + // + XPosition position; + bool hasPosition = mTrader.GetPosition( + position, + ticket); + + // + if (hasPosition) + { + // + comment = provider + "(" + ToString(ticket) + ")" + " Force Close Guard ..."; + + // + mTrader.Close( + ticket, + comment); + } + } + + // + if (StringLen(comment) > 0) + { + LogMessage(comment); + } + } + + // + // Trailing Specified Set Of Positions Stop Losses ... + void HandleGuardTrailingStopAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_POSITION_TYPE type, // Trading Type + ENUM_TIMEFRAMES period, // Specified Time Frame + double sl // Desired SL Value ... + ) + { + // + if (sl <= 0) + { + return; + } + + // + NormalizePrice( + sl, + symbol); + + // + XPosition positions[]; + GetPositions( + positions, + symbol, + type, + period, + provider); + int positionsCount = ArraySize(positions); + if (positionsCount <= 0) + { + return; + } + + // + int modified = 0; + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + string comment = PrepareSLTrailComment(iPosition.comment); + + // + bool isModified = mTrader.Modify( + iPosition.ticket, + sl, + iPosition.tp, + comment); + if (isModified) + { + modified++; + } + } + + // + if (modified > 0) + { + // + string msg = "(" + ToString(modified) + ") Position's Stop Trailed Successfully ..."; + + // + LogMessage(msg); + } + } + + // + // Add Support Signal for Specified Positions ... + void HandleGuardAddSupportPositionAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_POSITION_TYPE type, // Trading Type + ENUM_TIMEFRAMES period // Specified Time Frame + ) + { + // + // TODO: Implement this ... + } + + // + // Cancel all Placed Orders ... + void HandleGuardCancelPendingOrdersAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_POSITION_TYPE type, // Trading Type + ENUM_TIMEFRAMES period // Specified Time Frame + ) + { + // + // TODO: Implement this ... + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + string GetTagPrefix() + { + // + string result = "(" + mSymbol + ")(" + ToString(mPeriod) + ")"; + + // + return result; + } + + // + // Symbol ... + string mSymbol; + + // + // Period ... + ENUM_TIMEFRAMES mPeriod; + + // + // ExpertAdviser MAgic Number ... + ulong mMagic; + + // + // Slipppage ... + int mSlippage; + + // + // Tag Identifier ... + string mTag; + + // + bool mEnableLongs; + bool mEnableShorts; + + // + int mMaxAllowedPositions; + double mMaxAllowedDrawDownFactor; + + // + // Private ... +private: + // + // Define Requirements ... + + // + // XSCTrade Event Handlers ... + TOnStopLoss mOnStopLossTriggered; + TOnTakeProfit mOnTakeProfitTriggered; + TOnDealsChanged mOnDealsChangedHandler; + TOnOrdersChanged mOnOrdersChangedHandler; + TOnPositionsChanged mOnPositionsChangedHandler; + TOnTradeStateChanged mOnTradeStateChangedHandler; + + // + // Initi Requirements ... + void InitRequirements() + { + // + // Account Manager ... + mAccount = new XSCAccount(); + + // + // Trader ... + mTrader = new XSCTrade( + mSlippage, + mMagic); + + // + // Attach Event Handlers ... + + // + if (mOnStopLossTriggered != NULL) + { + mTrader.AddOnStopLossEventHandler(mOnStopLossTriggered); + } + + // + if (mOnTakeProfitTriggered != NULL) + { + mTrader.AddOnTakeProfitEventHandler(mOnTakeProfitTriggered); + } + + // + if (mOnDealsChangedHandler != NULL) + { + mTrader.AddOnDealsChangedEventHandler(mOnDealsChangedHandler); + } + + // + if (mOnOrdersChangedHandler != NULL) + { + mTrader.AddOnOrdersChangedEventHandler(mOnOrdersChangedHandler); + } + + // + if (mOnPositionsChangedHandler != NULL) + { + mTrader.AddOnPositionsChangedEventHandler(mOnPositionsChangedHandler); + } + + // + if (mOnTradeStateChangedHandler != NULL) + { + mTrader.AddOnTradeStateChangedEventHandler(mOnTradeStateChangedHandler); + } + } +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/X121/14030217/Classes/x-saherelm.xhelper.class.ex5 b/MQLTestWorkspace/X121/14030217/Classes/x-saherelm.xhelper.class.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..f2f0d424c6866c362a4f626403128373d0343464 GIT binary patch literal 6862 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 literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/X121/14030217/Classes/x-saherelm.xhelper.class.mq5 b/MQLTestWorkspace/X121/14030217/Classes/x-saherelm.xhelper.class.mq5 new file mode 100644 index 0000000..d9cea8b --- /dev/null +++ b/MQLTestWorkspace/X121/14030217/Classes/x-saherelm.xhelper.class.mq5 @@ -0,0 +1,209 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCBaseHelper +// Description: provides all Base Indicator +// Helper requirements ... +// +// +// 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 + +// +// START Definitions ... +// + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Handle base requirements ... +// for indicators ... +class XSCBaseHelper +{ + // + // Public ... +public: + // + // Constructor ... + void XSCBaseHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading Time Frame + ) + { + // + mSymbol = symbol; + mPeriod = period; + + // + LoopBack(52); + } + + // + // Deconstructor ... + void ~XSCBaseHelper() + { + IndicatorRelease(mHandler); + } + + // + // START Properties ... + // + + // + // Loopback Bars ... + void LoopBack(int value) + { + mLoopbackBars = value; + } + + int Loopback() + { + return mLoopbackBars; + } + + // + // Symbol ... + string GetSymbol() + { + return mSymbol; + } + + // + // Period ... + ENUM_TIMEFRAMES GetPeriod() + { + return mPeriod; + } + + // + // Tag ... + string GetTag() + { + return mTag; + } + + // + // Retrieve Bars ... + int GetBars() + { + // + int result = + Bars( + mSymbol, + mPeriod); + + // + return result; + } + + // + int GetCalculatedBars() + { + return BarsCalculated(mHandler); + } + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() {} + + // + // Reading Buffers based on Given Bar Index ... + virtual void Calculate( + int barIndex // Given Bar Index + ); + + // + // Retrieve MAx Required Length for Calculations ... + virtual int GetMaxLength(); + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + string GetTagPrefix() + { + // + string result = "(" + mSymbol + ")(" + ToString(mPeriod) + ")"; + + // + return result; + } + + // + // Symbol ... + string mSymbol; + + // + // Period ... + ENUM_TIMEFRAMES mPeriod; + + // + // Indicator Handler ... + int mHandler; + + // + // Number Of Items Read Per Tick ... + int mLoopbackBars; + + // + // Tag Identifier ... + string mTag; + + // + // Private ... +private: + // +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/X121/14030217/Classes/x-saherelm.xnotifier.class.ex5 b/MQLTestWorkspace/X121/14030217/Classes/x-saherelm.xnotifier.class.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..6dbc041bc700b5645b073803c81b160b3562cd34 GIT binary patch literal 6346 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 literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/X121/14030217/Classes/x-saherelm.xprovider.class.ex5 b/MQLTestWorkspace/X121/14030217/Classes/x-saherelm.xprovider.class.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..c295f28d64fca22eac9afc4b4cc22938244bab37 GIT binary patch literal 7596 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 Buy ... + // DEAL_TYPE_SELL => Sell ... + // DEAL_TYPE_BUY_CANCELED => Canceled buy deal ... + // There can be a situation when a previously executed buy deal is canceled. In this case, + // the type of the previously executed deal (DEAL_TYPE_BUY) is changed to DEAL_TYPE_BUY_CANCELED, + // and its profit/loss is zeroized. Previously obtained profit/loss is charged/withdrawn using a separated balance operation ... + // + // DEAL_TYPE_SELL_CANCELED => Canceled sell deal ... + // There can be a situation when a previously executed sell deal is canceled. In this case, + // the type of the previously executed deal (DEAL_TYPE_SELL) is changed to DEAL_TYPE_SELL_CANCELED, + // and its profit/loss is zeroized. Previously obtained profit/loss is charged/withdrawn using a separated balance operation + // + // DEAL_TYPE_BALANCE => Balance ... + // DEAL_TYPE_CREDIT => Credit ... + // DEAL_TYPE_CHARGE => Additional charge ... + // DEAL_TYPE_CORRECTION => Correction ... + // DEAL_TAX => Tax charges ... + // DEAL_TYPE_BONUS => Bonus ... + // DEAL_TYPE_INTEREST => Interest rate ... + // DEAL_DIVIDEND => Dividend operations... + // DEAL_DIVIDEND_FRANKED => Franked (non-taxable) dividend operations ... + // DEAL_TYPE_COMMISSION => Additional commission ... + // DEAL_TYPE_COMMISSION_DAILY => Daily commission ... + // DEAL_TYPE_COMMISSION_MONTHLY => Monthly commission ... + // DEAL_TYPE_COMMISSION_AGENT_DAILY => Daily agent commission ... + // DEAL_TYPE_COMMISSION_AGENT_MONTHLY => Monthly agent commission + ENUM_DEAL_TYPE type; + + // + // the deal direction ... + // ---------------------------------- + // DEAL_ENTRY_IN => Entry in ... + // DEAL_ENTRY_OUT => Entry out ... + // DEAL_ENTRY_INOUT => Reverse ... + // DEAL_ENTRY_OUT_BY => Close a position by an opposite one ... + ENUM_DEAL_ENTRY entry; + + // + // deal reson ... + // --------------------- + // DEAL_REASON_SL => The deal was executed as a result of Stop Loss activation ... + // DEAL_REASON_TP => The deal was executed as a result of Take Profit activation ... + // DEAL_REASON_SO => The deal was executed as a result of the Stop Out event ... + // DEAL_REASON_WEB => The deal was executed as a result of activation of an order placed from the web platform ... + // DEAL_REASON_SPLIT => The deal was executed after the split (price reduction) of an instrument, which had an open position during split announcement ... + // DEAL_REASON_CLIENT => The deal was executed as a result of activation of an order placed from a desktop terminal ... + // DEAL_REASON_MOBILE => The deal was executed as a result of activation of an order placed from a mobile application ... + // DEAL_REASON_EXPERT => The deal was executed as a result of activation of an order placed from an MQL5 program, i.e. an Expert Advisor or a script ... + // DEAL_REASON_VMARGIN => The deal was executed after charging the variation margin ... + // DEAL_REASON_ROLLOVER => The deal was executed due to a rollover ... + ENUM_DEAL_REASON reason; +}; + +// +// Model a Position with all of it's Supports ... +struct XPositionPack +{ + // + ulong ticket; + + // + XPosition position; + + // + int supportOrdersCount; + int supportPositionsCount; + + // + XOrder supportOrders[]; + XPosition supportPositions[]; +}; + +// +// Model OnTrade Event Handler Result on XCTrade Class ... +struct XOnTradeHandlerState +{ + // + bool hasNewDeal; + int newDeals; + + // + bool hasNewOrder; + int newOrders; + + // + bool hasNewPosition; + int newPositions; + + // + bool hasNewHistoryOrder; + int newHistoryOrders; +}; + +// +typedef void (*TOnDealsChanged)(int count); + +// +typedef void (*TOnOrdersChanged)(int count); + +// +typedef void (*TOnPositionsChanged)(int count); + +// +typedef void (*TOnStopLoss)(const XDeal &deal); +typedef void (*TOnTakeProfit)(const XDeal &deal); + +// +typedef void (*TOnTradeStateChanged)(const XOnTradeHandlerState &state); + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Libraries/x-saherelm.seriallizer.lib.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// XCTrade Base Class ... +class XSCTradeBase : public CTrade +{ +public: + // + // Modify Specific Position, by Specific Comment ... + bool PositionModify( + const string symbol, // Symbol + const double sl, // Stop Loss + const double tp, // Take Profit + const string comment = "" // Comment For Modify + ) + { + // + // check stopped + if (IsStopped(__FUNCTION__)) + { + return (false); + } + + // + // check position existence + if (!SelectPosition(symbol)) + { + return (false); + } + + // + // clean + ClearStructures(); + + // + // setting request + m_request.action = TRADE_ACTION_SLTP; + m_request.symbol = symbol; + m_request.magic = m_magic; + m_request.sl = sl; + m_request.tp = tp; + m_request.position = PositionGetInteger(POSITION_TICKET); + + // + // Specified Comment ... + if (StringLen(comment) > 0) + { + m_request.comment = comment; + } + + // + // action and return the result + return (OrderSend(m_request, m_result)); + } + bool PositionModify( + const ulong ticket, // Position Ticket + const double sl, // Stop Loss + const double tp, // Take Profit + const string comment = "" // Comment For Modify + ) + { + // + // check stopped + if (IsStopped(__FUNCTION__)) + { + return (false); + } + + // + // check position existence + if (!PositionSelectByTicket(ticket)) + { + return (false); + } + + // + // clean + ClearStructures(); + + // + // setting request + m_request.action = TRADE_ACTION_SLTP; + m_request.position = ticket; + m_request.symbol = PositionGetString(POSITION_SYMBOL); + m_request.magic = m_magic; + m_request.sl = sl; + m_request.tp = tp; + + // + // Specified Comment ... + if (StringLen(comment) > 0) + { + m_request.comment = comment; + } + + // + // action and return the result + return (OrderSend(m_request, m_result)); + } + + // + // Close Specific Position, by Specific Comment ... + bool PositionClose( + const string symbol, // Symbol + const ulong deviation, // Deviation + const string comment = "" // Comment For Close + ) + { + // + bool partial_close = false; + int retry_count = 10; + uint retcode = TRADE_RETCODE_REJECT; + + // + // check stopped + if (IsStopped(__FUNCTION__)) + { + return (false); + } + + // + // clean + ClearStructures(); + + // + // check filling + if (!FillingCheck(symbol)) + { + return (false); + } + + // + do + { + // + // check + if (SelectPosition(symbol)) + { + // + if ((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) + { + // + // prepare request for close BUY position + m_request.type = ORDER_TYPE_SELL; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_BID); + } + else + { + // + // prepare request for close SELL position + m_request.type = ORDER_TYPE_BUY; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_ASK); + } + } + else + { + // + // position not found + m_result.retcode = retcode; + return (false); + } + + // + // setting request + m_request.action = TRADE_ACTION_DEAL; + m_request.symbol = symbol; + m_request.volume = PositionGetDouble(POSITION_VOLUME); + m_request.magic = m_magic; + m_request.deviation = (deviation == ULONG_MAX) ? m_deviation : deviation; + m_request.position = PositionGetInteger(POSITION_TICKET); + + // + // Specify Comment ... + m_request.comment = comment; + + // + // check volume + double max_volume = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX); + if (m_request.volume > max_volume) + { + // + m_request.volume = max_volume; + partial_close = true; + } + else + { + partial_close = false; + } + + // + // hedging? just send order + if (IsHedging()) + { + return (OrderSend(m_request, m_result)); + } + + // + // order send + if (!OrderSend(m_request, m_result)) + { + // + if (--retry_count != 0) + { + continue; + } + + // + if (retcode == TRADE_RETCODE_DONE_PARTIAL) + { + m_result.retcode = retcode; + } + + // + return (false); + } + + // + //--- WARNING. If position volume exceeds the maximum volume allowed for deal, + //--- and when the asynchronous trade mode is on, for safety reasons, position is closed not completely, + //--- but partially. It is decreased by the maximum volume allowed for deal. + if (m_async_mode) + { + break; + } + + // + retcode = TRADE_RETCODE_DONE_PARTIAL; + if (partial_close) + { + Sleep(1000); + } + } while (partial_close); + + // + // succeed + return (true); + } + bool PositionClose( + const ulong ticket, // Position Ticket + const ulong deviation, // Deviation + const string comment = "" // Comment For Close + ) + { + // + // check stopped + if (IsStopped(__FUNCTION__)) + { + return (false); + } + + // + // check position existence + if (!PositionSelectByTicket(ticket)) + { + return (false); + } + + // + string symbol = PositionGetString(POSITION_SYMBOL); + + // + // clean + ClearStructures(); + + // + // check filling + if (!FillingCheck(symbol)) + { + return (false); + } + + // + // check + if ((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) + { + // + // prepare request for close BUY position + m_request.type = ORDER_TYPE_SELL; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_BID); + } + else + { + // + // prepare request for close SELL position + m_request.type = ORDER_TYPE_BUY; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_ASK); + } + + // + // setting request + m_request.action = TRADE_ACTION_DEAL; + m_request.position = ticket; + m_request.symbol = symbol; + m_request.volume = PositionGetDouble(POSITION_VOLUME); + m_request.magic = m_magic; + m_request.deviation = (deviation == ULONG_MAX) ? m_deviation : deviation; + + // + // Specify Comment ... + m_request.comment = comment; + + // + // close position + return (OrderSend(m_request, m_result)); + } + + // + // Partial Close Specific Position, by Specific Comment ... + bool PositionClosePartial( + const string symbol, // Symbol + const double volume, // Partial Closing Volume + const ulong deviation, // Deviation + const string comment = "" // Comment For Close + ) + { + // + uint retcode = TRADE_RETCODE_REJECT; + + // + // check stopped + if (IsStopped(__FUNCTION__)) + { + return (false); + } + + // + // for hedging mode only + if (!IsHedging()) + { + return (false); + } + + // + // clean + ClearStructures(); + + // + // check filling + if (!FillingCheck(symbol)) + { + return (false); + } + + // + // check + if (SelectPosition(symbol)) + { + // + if ((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) + { + // + // prepare request for close BUY position + m_request.type = ORDER_TYPE_SELL; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_BID); + } + else + { + // + // prepare request for close SELL position + m_request.type = ORDER_TYPE_BUY; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_ASK); + } + } + else + { + // + // position not found + m_result.retcode = retcode; + return (false); + } + + // + // check volume + double position_volume = PositionGetDouble(POSITION_VOLUME); + if (position_volume > volume) + { + position_volume = volume; + } + + // + // setting request + m_request.action = TRADE_ACTION_DEAL; + m_request.symbol = symbol; + m_request.volume = position_volume; + m_request.magic = m_magic; + m_request.deviation = (deviation == ULONG_MAX) ? m_deviation : deviation; + m_request.position = PositionGetInteger(POSITION_TICKET); + + // + // Specifieng Comment ... + m_request.comment = comment; + + // + // hedging? just send order + return (OrderSend(m_request, m_result)); + } + bool PositionClosePartial( + const ulong ticket, // Position Ticket + const double volume, // Partial Closing Volume + const ulong deviation, // Deviation + const string comment = "" // Comment For Close + ) + { + // + // check stopped + if (IsStopped(__FUNCTION__)) + { + return (false); + } + + // + // for hedging mode only + if (!IsHedging()) + { + return (false); + } + + // + // check position existence + if (!PositionSelectByTicket(ticket)) + { + return (false); + } + + // + string symbol = PositionGetString(POSITION_SYMBOL); + + // + // clean + ClearStructures(); + + // + // check filling + if (!FillingCheck(symbol)) + { + return (false); + } + + // + // check + if ((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) + { + // + // prepare request for close BUY position + m_request.type = ORDER_TYPE_SELL; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_BID); + } + else + { + // + // prepare request for close SELL position + m_request.type = ORDER_TYPE_BUY; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_ASK); + } + + // + // check volume + double position_volume = PositionGetDouble(POSITION_VOLUME); + if (position_volume > volume) + { + position_volume = volume; + } + + // + // setting request + m_request.action = TRADE_ACTION_DEAL; + m_request.position = ticket; + m_request.symbol = symbol; + m_request.volume = position_volume; + m_request.magic = m_magic; + m_request.deviation = (deviation == ULONG_MAX) ? m_deviation : deviation; + + // + // Specifieng Comment ... + m_request.comment = comment; + + // + // close position + return (OrderSend(m_request, m_result)); + } +}; + +// +// END Overrides ... +// + +// +// a Class for Manage Trades ... +class XSCTrade +{ + // + // Public ... +public: + // + // Constructor ... + void XSCTrade( + int slippage, // Specify Slippage + ulong magicNumber // Specify Magic Number + ) + { + // + mSlippage = slippage; + mMagicNumber = magicNumber; + + // + mPeriodPrefix = "PR"; + + // + mTrader = new XSCTradeBase(); + + // + mTrader.SetAsyncMode(false); + mTrader.SetDeviationInPoints(mSlippage); + mTrader.SetExpertMagicNumber(mMagicNumber); + + // + // Setting Log Level ... + mTrader.LogLevel(LOG_LEVEL_ERRORS); + + // + // Prepare Trade Event Materials ... + // + mDaysForRead = 1; + mScanStarted = false; + + // + // Reset On Trade Counter ... + ResetOnTradeContext(); + + // + // Init On Trade Context ... + InitOnTradeContext(); + } + + // + // Deconstructor ... + void ~XSCTrade() + { + } + + // + // START Event Processing ... + // + + // + // This Must be Called Every time OnTrade Event Happening ... + XOnTradeHandlerState HandleOnTrade() + { + // + // Handle OnTrade Event ... + XOnTradeHandlerState state = {}; + HandleOnTradeEvent(state); + if ( + !state.hasNewDeal && + !state.hasNewOrder && + !state.hasNewPosition && + !state.hasNewHistoryOrder) + { + return state; + } + + // + // STATE ... + + // + // Notfy Trade State Changed Event ... + NotifyTradeStateChangeEvent(state); + + // + // DEALS ... + if (state.hasNewDeal) + { + // + // Notfy Deals Changed Event ... + NotifyDealsChangeEvent(state.newDeals); + + // + // Retrieve Last Deal ... + XDeal deals[]; + GetDeals(deals); + int dealsCount = ArraySize(deals); + if (dealsCount > 0) + { + // + XDeal lastDeal = deals[0]; + + // + if (lastDeal.reason == DEAL_REASON_TP) + { + NotifyTakeProfitEvent(lastDeal); + } + else if (lastDeal.reason == DEAL_REASON_SL) + { + NotifyStopLossEvent(lastDeal); + } + } + } + + // + // ORDERS ... + if (state.hasNewOrder || state.hasNewHistoryOrder) + { + // + // Notfy Orders Changed Event ... + NotifyOrdersChangeEvent(state.newOrders + state.newHistoryOrders); + } + + // + // POSITIONS ... + if (state.hasNewPosition) + { + // + // Notfy Positions Changed Event ... + NotifyPositionsChangeEvent(state.newPositions); + } + + // + return state; + } + + // + // Process On Trade Requirement + void HandleOnTradeEvent( + XOnTradeHandlerState &result // Hold's Result + ) + { + // + if (mScanStarted) + { + ProcessOnTradeContext(result); + } + else + { + InitOnTradeContext(); + } + } + + // + // Event Emitters ... + + // + // STATE Changed ... + + // + // Clear Trade State Changed Event Handlers ... + void ClearOnTradeStateChangedEventHandlers() + { + // + ArrayFree(mTradeStateChangedEventHandlers); + + // + ArrayResize(mTradeStateChangedEventHandlers, 0); + } + + // + // Add New Deals Changed Event Handler ... + void AddOnTradeStateChangedEventHandler(TOnTradeStateChanged handler) + { + // + ArrayResize( + mTradeStateChangedEventHandlers, + ArraySize(mTradeStateChangedEventHandlers) + 1); + + // + mTradeStateChangedEventHandlers[ArraySize(mTradeStateChangedEventHandlers) - 1] = handler; + } + + // + // DEALS ... + + // + // Clear Deals Changed Event Handlers ... + void ClearOnDealsChangedEventHandlers() + { + // + ArrayFree(mDealsChangedEventHandlers); + + // + ArrayResize(mDealsChangedEventHandlers, 0); + } + + // + // Add New Deals Changed Event Handler ... + void AddOnDealsChangedEventHandler(TOnDealsChanged handler) + { + // + ArrayResize( + mDealsChangedEventHandlers, + ArraySize(mDealsChangedEventHandlers) + 1); + + // + mDealsChangedEventHandlers[ArraySize(mDealsChangedEventHandlers) - 1] = handler; + } + + // + // ORDERS ... + + // + // Clear Orders Changed Event Handlers ... + void ClearOnOrdersChangedEventHandlers() + { + // + ArrayFree(mOrdersChangedEventHandlers); + + // + ArrayResize(mOrdersChangedEventHandlers, 0); + } + + // + // Add New Orders Changed Event Handler ... + void AddOnOrdersChangedEventHandler(TOnOrdersChanged handler) + { + // + ArrayResize( + mOrdersChangedEventHandlers, + ArraySize(mOrdersChangedEventHandlers) + 1); + + // + mOrdersChangedEventHandlers[ArraySize(mOrdersChangedEventHandlers) - 1] = handler; + } + + // + // POSITIONS ... + + // + // Clear Positions Changed Event Handlers ... + void ClearOnPositionsChangedEventHandlers() + { + // + ArrayFree(mPositionsChangedEventHandlers); + + // + ArrayResize(mPositionsChangedEventHandlers, 0); + } + + // + // Add New Positions Changed Event Handler ... + void AddOnPositionsChangedEventHandler(TOnPositionsChanged handler) + { + // + ArrayResize( + mPositionsChangedEventHandlers, + ArraySize(mPositionsChangedEventHandlers) + 1); + + // + mPositionsChangedEventHandlers[ArraySize(mPositionsChangedEventHandlers) - 1] = handler; + } + + // + // TPSL ... + + // + // Clear Stop Loss Event Handlers ... + void ClearOnStopLossEventHandlers() + { + // + ArrayFree(mStopLossEventHandlers); + + // + ArrayResize(mStopLossEventHandlers, 0); + } + + // + // Add New Stop Loss Event Handler ... + void AddOnStopLossEventHandler(TOnStopLoss handler) + { + // + ArrayResize( + mStopLossEventHandlers, + ArraySize(mStopLossEventHandlers) + 1); + + // + mStopLossEventHandlers[ArraySize(mStopLossEventHandlers) - 1] = handler; + } + + // + // Clear Take Profit Event Handlers ... + void ClearOnTakeProfitEventHandlers() + { + // + ArrayFree(mTakeProfitEventHandlers); + + // + ArrayResize(mTakeProfitEventHandlers, 0); + } + + // + // Add New Stop Loss Event Handler ... + void AddOnTakeProfitEventHandler(TOnTakeProfit handler) + { + // + ArrayResize( + mTakeProfitEventHandlers, + ArraySize(mTakeProfitEventHandlers) + 1); + + // + mTakeProfitEventHandlers[ArraySize(mTakeProfitEventHandlers) - 1] = handler; + } + + // + // END Event Processing ... + // + + // + // START Provided Functions ... + // + + // + // Count Currently Open Positions ... + int CountPositions( + string symbol = "", // Specified Symbol + ENUM_POSITION_TYPE type = NULL // Specified Type + ) + { + // + int result = 0; + + // + int allPositions = 0; + int longPositions = 0; + int shortPositions = 0; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + string positionSymbol = mPositionInfo.Symbol(); + + // + ENUM_POSITION_TYPE positionType = mPositionInfo.PositionType(); + + // + if ( + type == NULL && + StringLen(symbol) <= 0) + { + // + allPositions++; + + // + continue; + } + else if ( + type != NULL && + StringLen(symbol) > 0) + { + // + if (type == positionType && + symbol == positionSymbol) + { + // + if (type == POSITION_TYPE_BUY) + { + longPositions++; + } + else + { + shortPositions++; + } + + // + continue; + } + } + else if (StringLen(symbol) > 0) + { + // + if (positionSymbol == symbol) + { + // + allPositions++; + + // + continue; + } + } + else if (type != NULL) + { + // + if (type == positionType) + { + // + if (type == POSITION_TYPE_BUY) + { + longPositions++; + } + else + { + shortPositions++; + } + + // + continue; + } + } + } + + // + // Specify Result ... + if ( + type == NULL && + StringLen(symbol) <= 0) + { + // + result = allPositions; + } + else if ( + type != NULL && + StringLen(symbol) > 0) + { + // + if (type == POSITION_TYPE_BUY) + { + result = longPositions; + } + else + { + result = shortPositions++; + } + } + else if (StringLen(symbol) > 0) + { + // + result = allPositions; + } + else if (type != NULL) + { + // + if (type == POSITION_TYPE_BUY) + { + result = longPositions; + } + else + { + result = shortPositions; + } + } + + // + return result; + } + + // + // Retrieve Max In Profit Position Ticket ... + ulong GetMaxInProfitPosition( + string symbol = "", // Specified Symbol + ENUM_POSITION_TYPE type = NULL // Specified Type + ) + { + // + ulong result = -1; + + // + double profit = 0; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong positionTicket = mPositionInfo.Ticket(); + + // + string positionSymbol = mPositionInfo.Symbol(); + + // + double positionProfit = mPositionInfo.Profit(); + double positionAbsProfit = MathAbs(positionProfit); + if (positionProfit <= 0) + { + continue; + } + + // + ENUM_POSITION_TYPE positionType = mPositionInfo.PositionType(); + + // + if ( + type == NULL && + StringLen(symbol) <= 0) + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + + // + continue; + } + else if ( + type != NULL && + StringLen(symbol) > 0) + { + // + if (type == positionType && + symbol == positionSymbol) + { + // + if (type == POSITION_TYPE_BUY) + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + } + else + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + } + + // + continue; + } + } + else if (StringLen(symbol) > 0) + { + // + if (positionSymbol == symbol) + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + + // + continue; + } + } + else if (type != NULL) + { + // + if (type == positionType) + { + // + if (type == POSITION_TYPE_BUY) + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + } + else + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + } + + // + continue; + } + } + } + + // + return result; + } + + // + // Retrieve Max In DrawDown Position Ticket ... + ulong GetMaxInDrawDownPosition( + string symbol = "", // Specified Symbol + ENUM_POSITION_TYPE type = NULL // Specified Type + ) + { + // + ulong result = -1; + + // + double profit = 0; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong positionTicket = mPositionInfo.Ticket(); + + // + string positionSymbol = mPositionInfo.Symbol(); + + // + double positionProfit = mPositionInfo.Profit(); + double positionAbsProfit = MathAbs(positionProfit); + if (positionProfit >= 0) + { + continue; + } + + // + ENUM_POSITION_TYPE positionType = mPositionInfo.PositionType(); + + // + if ( + type == NULL && + StringLen(symbol) <= 0) + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + + // + continue; + } + else if ( + type != NULL && + StringLen(symbol) > 0) + { + // + if (type == positionType && + symbol == positionSymbol) + { + // + if (type == POSITION_TYPE_BUY) + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + } + else + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + } + + // + continue; + } + } + else if (StringLen(symbol) > 0) + { + // + if (positionSymbol == symbol) + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + + // + continue; + } + } + else if (type != NULL) + { + // + if (type == positionType) + { + // + if (type == POSITION_TYPE_BUY) + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + } + else + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + } + + // + continue; + } + } + } + + // + return result; + } + + // + // Retrieve Specific Position's Profit ... + double GetPositionProfit( + const ulong ticket // Specified Position Ticket + ) + { + // + double result = 0; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong positionTicket = mPositionInfo.Ticket(); + if (positionTicket != ticket) + { + continue; + } + + // + result = mPositionInfo.Profit(); + break; + } + + // + return result; + } + + // + // Retrieve Specific Position's OpenDate ... + datetime GetPositionOpenDate( + const ulong ticket // Specified Position Ticket + ) + { + // + datetime result = 0; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong positionTicket = mPositionInfo.Ticket(); + if (positionTicket != ticket) + { + continue; + } + + // + result = mPositionInfo.Time(); + break; + } + + // + return result; + } + + // + // Retrieve Specific Position's Comment ... + string GetPositionComment( + const ulong ticket // Specified Position Ticket + ) + { + // + string result = ""; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong positionTicket = mPositionInfo.Ticket(); + if (positionTicket != ticket) + { + continue; + } + + // + result = mPositionInfo.Comment(); + break; + } + + // + return result; + } + + // + // Retrieve All Open Positions Profit ... + double GetPositionsProfit( + string symbol = "", // Specified Symbol + ENUM_POSITION_TYPE type = NULL // Specified Type + ) + { + // + double result = 0; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong positionTicket = mPositionInfo.Ticket(); + + // + string positionSymbol = mPositionInfo.Symbol(); + + // + double positionProfit = mPositionInfo.Profit(); + + // + ENUM_POSITION_TYPE positionType = mPositionInfo.PositionType(); + + // + if ( + type == NULL && + StringLen(symbol) <= 0) + { + // + result += positionProfit; + + // + continue; + } + else if ( + type != NULL && + StringLen(symbol) > 0) + { + // + if (type == positionType && + symbol == positionSymbol) + { + // + if (type == POSITION_TYPE_BUY) + { + result += positionProfit; + } + else + { + result += positionProfit; + } + + // + continue; + } + } + else if (StringLen(symbol) > 0) + { + // + if (positionSymbol == symbol) + { + result += positionProfit; + + // + continue; + } + } + else if (type != NULL) + { + // + if (type == positionType) + { + // + if (type == POSITION_TYPE_BUY) + { + result += positionProfit; + } + else + { + result += positionProfit; + } + + // + continue; + } + } + } + + // + return result; + } + + // + // Find Oldes Position ... + ulong GetOldestPosition( + string symbol = "", // Specified Symbol + ENUM_POSITION_TYPE type = NULL // Specified Type + ) + { + // + ulong result = 0; + + // + int age = 0; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong positionTicket = mPositionInfo.Ticket(); + + // + string positionSymbol = mPositionInfo.Symbol(); + + // + double positionProfit = mPositionInfo.Profit(); + double positionAbsProfit = MathAbs(positionProfit); + if (positionProfit >= 0) + { + continue; + } + + // + ENUM_POSITION_TYPE positionType = mPositionInfo.PositionType(); + + // + string positionComment = mPositionInfo.Comment(); + ENUM_TIMEFRAMES positionPeriod = ExtractPositionPeriod(positionComment); + + // + // Calculate Position's Age ... + datetime positionOpenTime = mPositionInfo.Time(); + + // + // Retrieve Trade Open Bar Index based on Current Period ... + int positionOpenBarIndex = iBarShift( + positionSymbol, + positionPeriod, + positionOpenTime); + + // + // Calculate Trade Life ... + int positionAge = MathAbs(0 - positionOpenBarIndex); + + // + if ( + type == NULL && + StringLen(symbol) <= 0) + { + // + if (age < positionAge) + { + // + age = positionAge; + result = positionTicket; + } + + // + continue; + } + else if ( + type != NULL && + StringLen(symbol) > 0) + { + // + if (type == positionType && + symbol == positionSymbol) + { + // + if (type == POSITION_TYPE_BUY) + { + // + if (age < positionAge) + { + // + age = positionAge; + result = positionTicket; + } + } + else + { + // + if (age < positionAge) + { + // + age = positionAge; + result = positionTicket; + } + } + + // + continue; + } + } + else if (StringLen(symbol) > 0) + { + // + if (positionSymbol == symbol) + { + // + if (age < positionAge) + { + // + age = positionAge; + result = positionTicket; + } + + // + continue; + } + } + else if (type != NULL) + { + // + if (type == positionType) + { + // + if (type == POSITION_TYPE_BUY) + { + // + if (age < positionAge) + { + // + age = positionAge; + result = positionTicket; + } + } + else + { + // + if (age < positionAge) + { + // + age = positionAge; + result = positionTicket; + } + } + + // + continue; + } + } + } + + // + return result; + } + + // + // Force Open a Buy/Long Position ... + bool Buy( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES period, // Specified Trade's Period + double volume, // position volume + double price, // execution price + double sl = 0, // stop loss price + double tp = 0, // take profit price + string comment = "" // comment + ) + { + // + bool result = false; + + // + string mPeriodStr = GeneratePositionPeriodComment(period); + + // + comment += mPeriodStr; + + // + result = mTrader.Buy( + volume, + symbol, + price, + sl, + tp, + comment); + + // + return result; + } + + // + // Send BUY LIMIT order ... + bool BuyLimit( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES period, // Specified Trade's Period + double volume, // order volume + double price, // order price + double sl = 0.0, // stop loss price + double tp = 0.0, // take profit price + ENUM_ORDER_TYPE_TIME typeTime = ORDER_TIME_GTC, // order lifetime + datetime expiration = 0, // order expiration time + string comment = "" // comment + ) + { + // + bool result = false; + + // + string mPeriodStr = GeneratePositionPeriodComment(period); + + // + comment += mPeriodStr; + + // + result = mTrader.BuyLimit( + volume, + price, + symbol, + sl, + tp, + typeTime, + expiration, + comment); + + // + return result; + } + + // + // Send BUY STOP order ... + bool BuyStop( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES period, // Specified Trade's Period + double volume, // order volume + double price, // order price + double sl = 0.0, // stop loss price + double tp = 0.0, // take profit price + ENUM_ORDER_TYPE_TIME typeTime = ORDER_TIME_GTC, // order lifetime + datetime expiration = 0, // order expiration time + string comment = "" // comment + ) + { + // + bool result = false; + + // + string mPeriodStr = GeneratePositionPeriodComment(period); + + // + comment += mPeriodStr; + + // + result = mTrader.BuyStop( + volume, + price, + symbol, + sl, + tp, + typeTime, + expiration, + comment); + + // + return result; + } + + // + // Force Open a Sell/Short Position ... + bool Sell( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES period, // Specified Trade's Period + double volume, // position volume + double price, // execution price + double sl = 0, // stop loss price + double tp = 0, // take profit price + string comment = "" // comment + ) + { + // + bool result = false; + + // + string mPeriodStr = GeneratePositionPeriodComment(period); + + // + comment += mPeriodStr; + + // + result = mTrader.Sell( + volume, + symbol, + price, + sl, + tp, + comment); + + // + return result; + } + + // + // Send SELL LIMIT order ... + bool SellLimit( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES period, // Specified Trade's Period + double volume, // order volume + double price, // order price + double sl = 0.0, // stop loss price + double tp = 0.0, // take profit price + ENUM_ORDER_TYPE_TIME typeTime = ORDER_TIME_GTC, // order lifetime + datetime expiration = 0, // order expiration time + string comment = "" // comment + ) + { + // + bool result = false; + + // + string mPeriodStr = GeneratePositionPeriodComment(period); + + // + comment += mPeriodStr; + + // + result = mTrader.SellLimit( + volume, + price, + symbol, + sl, + tp, + typeTime, + expiration, + comment); + + // + return result; + } + + // + // Send SELL STOP order ... + bool SellStop( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES period, // Specified Trade's Period + double volume, // order volume + double price, // order price + double sl = 0.0, // stop loss price + double tp = 0.0, // take profit price + ENUM_ORDER_TYPE_TIME typeTime = ORDER_TIME_GTC, // order lifetime + datetime expiration = 0, // order expiration time + string comment = "" // comment + ) + { + // + bool result = false; + + // + string mPeriodStr = GeneratePositionPeriodComment(period); + + // + comment += mPeriodStr; + + // + result = mTrader.SellStop( + volume, + price, + symbol, + sl, + tp, + typeTime, + expiration, + comment); + + // + return result; + } + + // + // Modify Position ... + bool Modify( + const ulong ticket, // position ticket + double sl = 0, // stop loss price + double tp = 0, // take profit + string comment = "" // comment + ) + { + // + bool result = false; + + // + // Validate Args ... + if (tp <= 0 && sl <= 0) + { + result = false; + return result; + } + + // + // Use Position Comment when there isn't new One ... + if (StringLen(comment) == 0) + { + comment = GetPositionComment(ticket); + } + + // + result = mTrader.PositionModify( + ticket, + sl, + tp, + comment); + + // + return result; + } + + // + // Close Position By Ticket ... + bool Close( + ulong ticket, // Position Ticket + string comment = "" // Close Position By Specific Comment + ) + { + // + bool result = false; + + // + // Try to Select Position ... + if (!mPositionInfo.SelectByTicket(ticket)) + { + return result; + } + + // + // Close Position By Specific Comment ... + result = mTrader.PositionClose( + ticket, + mSlippage, + comment); + + // + return result; + } + + // + // Close All Positions ... + void CloseAllPositions( + string comment = "" // Close Position By Specific Comment + ) + { + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong positionTicket = mPositionInfo.Ticket(); + Close( + positionTicket, + comment); + } + } + + // + // Close Partial By Ticket ... + bool ClosePartial( + ulong ticket, // Position Ticket + double volume, // Volume Size for Partial Closing + string comment = "" // Close Position By Specific Comment + ) + { + // + bool result = false; + + // + if (!mPositionInfo.SelectByTicket(ticket)) + { + return result; + } + + // + result = mTrader.PositionClosePartial( + ticket, + volume, + mSlippage, + comment); + + // + return result; + } + + // + // Find Position Open Bar Index ... + int GetPositionOpenBarIndex( + const ulong ticket // position ticket + ) + { + // + int result = -1; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong positionTicket = mPositionInfo.Ticket(); + if (positionTicket != ticket) + { + continue; + } + + // + string symbol = mPositionInfo.Symbol(); + datetime openAt = mPositionInfo.Time(); + string comment = mPositionInfo.Comment(); + ENUM_TIMEFRAMES period = ExtractPositionPeriod(comment); + + // + result = iBarShift( + symbol, + period, + openAt); + } + + // + return result; + } + + // + bool GetPosition( + XPosition &position, // Holds result ... + ulong ticket // Required Position Ticket ... + ) + { + // + bool result = false; + + // + XPosition positions[]; + GetPositions(positions); + int positionsCount = ArraySize(positions); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + result = iPosition.ticket == ticket; + if (!result) + { + continue; + } + + // + position = iPosition; + break; + } + + // + return result; + } + + // + // Retrieve Positions as an Array ... + void GetPositions( + XPosition &result[] // Hold Result ... + ) + { + // + Clean(result); + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong magic = mPositionInfo.Magic(); + ulong ticket = mPositionInfo.Ticket(); + string symbol = mPositionInfo.Symbol(); + datetime openAt = mPositionInfo.Time(); + double swap = mPositionInfo.Swap(); + double sl = mPositionInfo.StopLoss(); + double tp = mPositionInfo.TakeProfit(); + double profit = mPositionInfo.Profit(); + double volume = mPositionInfo.Volume(); + string comment = mPositionInfo.Comment(); + double entry = mPositionInfo.PriceOpen(); + double price = mPositionInfo.PriceCurrent(); + double commission = mPositionInfo.Commission(); + ENUM_POSITION_TYPE type = mPositionInfo.PositionType(); + ENUM_TIMEFRAMES period = ExtractPositionPeriod(comment); + + // + XPosition iPosition = {}; + + // + iPosition.tp = tp; + iPosition.sl = sl; + iPosition.swap = swap; + iPosition.type = type; + iPosition.magic = magic; + iPosition.entry = entry; + iPosition.price = price; + iPosition.ticket = ticket; + iPosition.symbol = symbol; + iPosition.period = period; + iPosition.volume = volume; + iPosition.openAt = openAt; + iPosition.profit = profit; + iPosition.comment = comment; + iPosition.commission = commission; + + // + Add( + iPosition, + result); + } + } + + // + void GetPositions( + XPosition &result[], // Hold Result ... + string symbol, // Trading Symbol ... + ENUM_TIMEFRAMES period // Trading Period ... + ) + { + // + Clean(result); + + // + bool hasPeriod = period != NULL; + bool hasSymbol = symbol != NULL && StringLen(symbol) > 0; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return; + } + + // + XPosition allPositions[]; + GetPositions(allPositions); + + // + if (!hasPeriod && !hasSymbol) + { + // + Copy( + allPositions, + result); + + // + return; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = allPositions[i]; + + // + if (hasSymbol && + symbol != iPosition.symbol) + { + continue; + } + + // + ENUM_TIMEFRAMES positionPeriod = ExtractPositionPeriod(iPosition.comment); + if (hasPeriod && + period != positionPeriod) + { + continue; + } + + // + Add( + iPosition, + result); + } + } + + // + // Execute a Signal ... + bool ExecuteSignal( + XSignal &signal, // Signal ... + string comment = "", // Position Comment ... + ENUM_ORDER_TYPE_TIME lifetime = ORDER_TIME_GTC, // Order LifeTime ... + datetime expiration = 0 // order expiration time + ) + { + // + bool result = false; + + // + double currentEntry = GetEntry( + signal.symbol, + signal.type); + bool isLong = IsLong(signal.type); + + // + ResetLastError(); + + // + if (signal.mode == X_ORDER_MODE_MARKET) + { + // + // Execute MArket Orders ... + if (isLong) + { + // + result = Buy( + signal.symbol, + signal.period, + signal.volume, + signal.entry, + signal.sl, + signal.tp, + comment); + } + else + { + // + result = Sell( + signal.symbol, + signal.period, + signal.volume, + signal.entry, + signal.sl, + signal.tp, + comment); + } + } + else if (signal.mode == X_ORDER_MODE_LIMIT) + { + // + // Execute Limit Orders ... + + // + // Check Conditions ... + + // + // Check Price ... + result = isLong + ? signal.entry < currentEntry + : signal.entry > currentEntry; + if (!result) + { + return result; + } + + // + // Check Expiration Date ... + result = (lifetime == ORDER_TIME_SPECIFIED || lifetime == ORDER_TIME_SPECIFIED_DAY) + ? expiration > 0 + : true; + if (!result) + { + return result; + } + + // + if (isLong) + { + // + result = BuyLimit( + signal.symbol, + signal.period, + signal.volume, + signal.entry, + signal.sl, + signal.tp, + lifetime, + expiration, + comment); + } + else + { + // + result = SellLimit( + signal.symbol, + signal.period, + signal.volume, + signal.entry, + signal.sl, + signal.tp, + lifetime, + expiration, + comment); + } + } + else if (signal.mode == X_ORDER_MODE_STOP) + { + // + // Execute Stop Orders ... + + // + // Check Conditions ... + + // + // Check Price ... + result = isLong + ? signal.entry > currentEntry + : signal.entry < currentEntry; + if (!result) + { + return result; + } + + // + // Check Expiration Date ... + result = (lifetime == ORDER_TIME_SPECIFIED || lifetime == ORDER_TIME_SPECIFIED_DAY) + ? expiration > 0 + : true; + if (!result) + { + return result; + } + + // + if (isLong) + { + // + result = BuyStop( + signal.symbol, + signal.period, + signal.volume, + signal.entry, + signal.sl, + signal.tp, + lifetime, + expiration, + comment); + } + else + { + // + result = SellStop( + signal.symbol, + signal.period, + signal.volume, + signal.entry, + signal.sl, + signal.tp, + lifetime, + expiration, + comment); + } + } + + // + if (!result) + { + LogMessage("Error: " + (string)GetLastError() + ", " + GetErrorDescription(GetLastError())); + } + else + { + // + // Retrieve Last Position Ticket ... + ulong ticket = GetLastOpenPositionTicket(); + + // + // Check Position have Support Signals or not ... + int supportsCount = ArraySize(signal.supports); + if (supportsCount > 0) + { + // + int executed = 0; + for (int i = 0; i < supportsCount; i++) + { + // + XSignal iSupport = signal.supports[i]; + + // + int supIndex = i + 1; + string iComment = GenerateSupportSignalComment( + ticket, + supIndex); + + // + bool isExecuted = ExecuteSignal( + iSupport, + iComment); + if (isExecuted) + { + executed++; + } + } + + // + result = executed == supportsCount; + } + } + + // + return result; + } + + // + // Execute a Collection of Signals ... + int ExecuteSignals( + const XSignal &signals[], // an Array of Signals ... + string comment = "", // Position Comment ... + ENUM_ORDER_TYPE_TIME lifetime = ORDER_TIME_GTC, // Order LifeTime ... + datetime expiration = 0 // order expiration time + ) + { + // + int result = 0; + + // + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + if (StringLen(comment) == 0) + { + comment = GenerateProvidersString(iSignal); + } + + // + bool isExecuted = ExecuteSignal( + iSignal, + comment, + lifetime, + expiration); + + // + if (isExecuted) + { + result++; + } + } + + // + return result; + } + + // + // Retrieve in Profit Positions ... + void GetInProfitPositions( + XPosition &result[] // Hold Result ... + ) + { + // + Clean(result); + + // + XPosition allPositions[]; + GetPositions(allPositions); + int positionsCount = ArraySize(allPositions); + if (positionsCount <= 0) + { + return; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = allPositions[i]; + + // + if (iPosition.profit > 0) + { + Add( + iPosition, + result); + } + } + } + + // + // Retrieve in Drawdown Positions ... + void GetInDrawdownPositions( + XPosition &result[] // Hold Result ... + ) + { + // + Clean(result); + + // + XPosition allPositions[]; + GetPositions(allPositions); + int positionsCount = ArraySize(allPositions); + if (positionsCount <= 0) + { + return; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = allPositions[i]; + + // + if (iPosition.profit < 0) + { + Add( + iPosition, + result); + } + } + } + + // + // Close a Collection Of Positions ... + int ClosePositions( + XPosition &positions[], // Positions to Close ... + string comment = "" // Specified Comment ... + ) + { + // + int result = 0; + int positionsCount = ArraySize(positions); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + bool isClosed = Close( + iPosition.ticket, + comment); + if (isClosed) + { + result++; + } + } + + // + return result; + } + + // + // Retrieve All Orders ... + void GetOrders( + XOrder &result[], // Holdes Result .... + string symbol, // Trading Symbol ... + ENUM_TIMEFRAMES period, // Trading TimeFrame ... + ENUM_ORDER_STATE state = NULL // Order State ... + ) + { + // + Clean(result); + + // + int ordersCount = OrdersTotal(); + if (ordersCount <= 0) + { + return; + } + + // + // Since Orders may be so more than positions ... + // start Orders Collectiong Loops reverse ... + for (int i = ordersCount - 1; i >= 0; i--) + { + // + if (!mOrderInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mOrderInfo.Magic() != mMagicNumber) + { + continue; + } + + // + // Reading Order Info ... + long magic = mOrderInfo.Magic(); + double sl = mOrderInfo.StopLoss(); + ulong ticket = mOrderInfo.Ticket(); + double tp = mOrderInfo.TakeProfit(); + string oSymbol = mOrderInfo.Symbol(); + string comment = mOrderInfo.Comment(); + long pocitionID = mOrderInfo.PositionId(); + double openPrice = mOrderInfo.PriceOpen(); + datetime setupAt = mOrderInfo.TimeSetup(); + datetime executedAt = mOrderInfo.TimeDone(); + ENUM_ORDER_STATE oState = mOrderInfo.State(); + ENUM_ORDER_TYPE type = mOrderInfo.OrderType(); + double currentPrice = mOrderInfo.PriceCurrent(); + datetime expiredAt = mOrderInfo.TimeExpiration(); + double initialVolume = mOrderInfo.VolumeInitial(); + double currentVolume = mOrderInfo.VolumeCurrent(); + double stopLimitPrice = mOrderInfo.PriceStopLimit(); + ENUM_ORDER_TYPE_TIME lifetime = mOrderInfo.TypeTime(); + ENUM_ORDER_TYPE_FILLING filling = mOrderInfo.TypeFilling(); + + // + if (StringLen(symbol) > 0 && symbol != oSymbol) + { + continue; + } + + // + ENUM_TIMEFRAMES oPeriod = ExtractPositionPeriod(comment); + if (period != NULL && period != oPeriod) + { + continue; + } + + // + if (state != NULL && oState != state) + { + continue; + } + + // + // Now Create an instance of XOrder struct and fill it by + // retrieved data, and add it to results ... + XOrder iOrder = {}; + + // + iOrder.sl = sl; + iOrder.tp = tp; + iOrder.type = type; + iOrder.magic = magic; + iOrder.state = oState; + iOrder.ticket = ticket; + iOrder.smybol = oSymbol; + iOrder.period = oPeriod; + iOrder.setupAt = setupAt; + iOrder.comment = comment; + iOrder.filling = filling; + iOrder.lifetime = lifetime; + iOrder.expiredAt = expiredAt; + iOrder.openPrice = openPrice; + iOrder.pocitionID = pocitionID; + iOrder.executedAt = executedAt; + iOrder.currentPrice = currentPrice; + iOrder.initialVolume = initialVolume; + iOrder.currentVolume = currentVolume; + iOrder.stopLimitPrice = stopLimitPrice; + + // + Add( + iOrder, + result); + } + } + + // + int CountOrders() + { + return OrdersTotal(); + } + + // + // Cancel Specific Order ... + bool CancelOrder(ulong ticket) + { + return mTrader.OrderDelete(ticket); + } + + // + // Cancel Specific Orders ... + bool CancelOrders( + XOrder &orders[]) + { + // + bool result = false; + + // + int ordersCount = ArraySize(orders); + if (ordersCount <= 0) + { + return result; + } + + // + for (int i = 0; i < ordersCount; i++) + { + // + XOrder iOrder = orders[i]; + + // + bool isDeleted = mTrader.OrderDelete(iOrder.ticket); + if (isDeleted && !result) + { + result = isDeleted; + } + } + + // + return result; + } + + // + // Retrieve All Deals ... + void GetDeals(XDeal &result[]) + { + // + Clean(result); + + // + int dealsCount = HistoryDealsTotal(); + if (dealsCount <= 0) + { + return; + } + + // + for (int i = dealsCount - 1; i >= 0; i--) + { + // + if (!mDealInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mDealInfo.Magic() != mMagicNumber) + { + continue; + } + + // + // Reading Order Info ... + double swap = mDealInfo.Swap(); + ulong magic = mDealInfo.Magic(); + ulong order = mDealInfo.Order(); + ulong ticket = mDealInfo.Ticket(); + datetime time = mDealInfo.Time(); + double price = mDealInfo.Price(); + string symbol = mDealInfo.Symbol(); + double profit = mDealInfo.Profit(); + double volume = mDealInfo.Volume(); + string comment = mDealInfo.Comment(); + ulong positionId = mDealInfo.PositionId(); + ENUM_DEAL_ENTRY entry = mDealInfo.Entry(); + double commission = mDealInfo.Commission(); + ENUM_DEAL_TYPE type = mDealInfo.DealType(); + ENUM_DEAL_REASON reason = (ENUM_DEAL_REASON)HistoryDealGetInteger( + ticket, + DEAL_REASON); + + // + XDeal iDeal = {}; + + // + iDeal.swap = swap; + iDeal.time = time; + iDeal.type = type; + iDeal.magic = magic; + iDeal.entry = entry; + iDeal.order = order; + iDeal.price = price; + iDeal.ticket = ticket; + iDeal.symbol = symbol; + iDeal.profit = profit; + iDeal.volume = volume; + iDeal.reason = reason; + iDeal.comment = comment; + iDeal.positionId = positionId; + iDeal.commission = commission; + + // + Add( + iDeal, + result); + } + } + + // + // Retrieve all History Orders of Specific Deal ... + int GetDealHistory( + const XDeal &deal, // Specified Deal + XOrder &history[] // Hold Result + ) + { + // + int result = 0; + + // + Clean(history); + + // + bool isHistorySelected = HistorySelectByPosition(deal.positionId); + if (!isHistorySelected) + { + return result; + } + + // + int ordersCount = HistoryOrdersTotal(); + if (ordersCount <= 0) + { + return result; + } + + // + for (int i = 0; i < ordersCount; i++) + { + // + if (!mHistoryOrderInfo.SelectByIndex(i)) + { + continue; + } + + // + ulong ticket = mHistoryOrderInfo.Ticket(); + + // + long positionId = mHistoryOrderInfo.PositionId(); + if (positionId != deal.positionId) + { + continue; + } + + // + // Reading Order Info ... + long magic = mHistoryOrderInfo.Magic(); + double sl = mHistoryOrderInfo.StopLoss(); + double tp = mHistoryOrderInfo.TakeProfit(); + string oSymbol = mHistoryOrderInfo.Symbol(); + string comment = mHistoryOrderInfo.Comment(); + double openPrice = mHistoryOrderInfo.PriceOpen(); + datetime setupAt = mHistoryOrderInfo.TimeSetup(); + datetime executedAt = mHistoryOrderInfo.TimeDone(); + ENUM_ORDER_STATE oState = mHistoryOrderInfo.State(); + ENUM_ORDER_TYPE type = mHistoryOrderInfo.OrderType(); + double currentPrice = mHistoryOrderInfo.PriceCurrent(); + datetime expiredAt = mHistoryOrderInfo.TimeExpiration(); + double initialVolume = mHistoryOrderInfo.VolumeInitial(); + double currentVolume = mHistoryOrderInfo.VolumeCurrent(); + double stopLimitPrice = mHistoryOrderInfo.PriceStopLimit(); + ENUM_ORDER_TYPE_TIME lifetime = mHistoryOrderInfo.TypeTime(); + ENUM_ORDER_TYPE_FILLING filling = mHistoryOrderInfo.TypeFilling(); + + // + ENUM_TIMEFRAMES oPeriod = ExtractPositionPeriod(comment); + + // + // Now Create an instance of XOrder struct and fill it by + // retrieved data, and add it to results ... + XOrder iOrder = {}; + + // + iOrder.sl = sl; + iOrder.tp = tp; + iOrder.type = type; + iOrder.magic = magic; + iOrder.state = oState; + iOrder.ticket = ticket; + iOrder.smybol = oSymbol; + iOrder.period = oPeriod; + iOrder.setupAt = setupAt; + iOrder.comment = comment; + iOrder.filling = filling; + iOrder.lifetime = lifetime; + iOrder.expiredAt = expiredAt; + iOrder.openPrice = openPrice; + iOrder.pocitionID = positionId; + iOrder.executedAt = executedAt; + iOrder.currentPrice = currentPrice; + iOrder.initialVolume = initialVolume; + iOrder.currentVolume = currentVolume; + iOrder.stopLimitPrice = stopLimitPrice; + + // + Add( + iOrder, + history); + } + + // + result = ArraySize(history); + + // + return result; + } + + // + // Find Deal Period ... + ENUM_TIMEFRAMES GetDealPeriod(const XDeal &deal) + { + // + ENUM_TIMEFRAMES result = NULL; + + // + XOrder history[]; + int historyCount = GetDealHistory( + deal, + history); + if (historyCount <= 0) + { + return result; + } + + // + for (int i = 0; i < historyCount; i++) + { + // + XOrder iOrder = history[i]; + + // + if (StringLen(iOrder.comment) == 0) + { + continue; + } + + // + string periodStr = ExtractPositionPeriodString(iOrder.comment); + if (StringLen(periodStr) > 0) + { + // + result = ToPeriod(periodStr); + break; + } + } + + // + return result; + } + + // + // Generate String Representation Of Position's Time Frame ... + string GeneratePositionPeriodComment(ENUM_TIMEFRAMES period) + { + // + string result = mPeriodPrefix + "(" + ToString(period) + ")"; + + // + return result; + } + + // + string ExtractPositionPeriodString(string comment) + { + // + string result = ""; + + // + if (StringLen(comment) <= 0) + { + return result; + } + + // + result = ExtractString( + comment, + mPeriodPrefix + "(", + ")"); + + // + return result; + } + + // + // Extract Position Time Frame From it's Comment ... + ENUM_TIMEFRAMES ExtractPositionPeriod(string comment) + { + // + ENUM_TIMEFRAMES result = NULL; + + // + string periodStr = ExtractPositionPeriodString(comment); + if (StringLen(periodStr) <= 0) + { + return result; + } + + // + result = ToPeriod(periodStr); + + // + return result; + } + + // + // Retrieve Last Open Position Ticket ... + ulong GetLastOpenPositionTicket() + { + // + ulong result = 0; + + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + result = PositionGetTicket(PositionsTotal() - 1); + + // + return result; + } + + // + // Retrieve Last Placed Order Ticket ... + ulong GetLastPlacedOrderTicket() + { + // + ulong result = 0; + + int ordersCount = OrdersTotal(); + if (ordersCount <= 0) + { + return result; + } + + // + if (mOrderInfo.SelectByIndex(ordersCount - 1)) + { + result = mOrderInfo.Ticket(); + } + + // + return result; + } + + // + // SUPPORT Signals ... + + // + // Retrieve a Position if Exists + // by all of it's Supported Positon/Order (s) ... + bool GetPositionPack( + ulong ticket, // Sepcified Position's Ticket + XPositionPack &pack // Hold Result ... + ) + { + // + bool result = false; + + // + int positionsCount = CountPositions(); + int ordersCount = CountOrders(); + if (ordersCount <= 0 && positionsCount <= 0) + { + return result; + } + + // + XPosition position; + result = GetPosition( + position, + ticket); + if (!result) + { + return result; + } + + // + XOrder supportOrders[]; + XPosition supportPositions[]; + + // + XOrder orders[]; + GetOrders( + orders, + position.symbol, + position.period, + ORDER_STATE_PLACED); + ordersCount = ArraySize(orders); + + // + // Select Orders ... + if (ordersCount > 0) + { + // + for (int i = 0; i < ordersCount; i++) + { + // + XOrder iOrder = orders[i]; + + // + string params[]; + bool hasSupport = ExtractSupportParams( + iOrder.comment, + params); + if (hasSupport) + { + // + ulong parentTicket = ExtractParentTicket(iOrder.comment); + if (parentTicket == ticket) + { + // + Add( + iOrder, + supportOrders); + } + } + } + } + + // + XPosition positions[]; + GetPositions( + positions, + position.symbol, + position.period); + positionsCount = ArraySize(positions); + + // + // Select Positions ... + if (positionsCount > 0) + { + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + string params[]; + bool hasSupport = ExtractSupportParams( + iPosition.comment, + params); + if (hasSupport) + { + // + ulong parentTicket = ExtractParentTicket(iPosition.comment); + if (parentTicket == ticket) + { + // + Add( + iPosition, + supportPositions); + } + } + } + } + + // + int supportOrdersCount = ArraySize(supportOrders); + int supportPositionsCount = ArraySize(supportPositions); + + // + pack.ticket = ticket; + pack.position = position; + + // + Copy(supportOrders, + pack.supportOrders); + Copy(supportPositions, + pack.supportPositions); + + // + pack.supportOrdersCount = supportOrdersCount; + pack.supportPositionsCount = supportPositionsCount; + + // + result = true; + + // + return result; + } + + // + // Extract specific Positions Pack ... + // in this senario there is no need to Position exists itself ... + bool GetPositionPack( + ulong ticket, // Specified Positions Ticket ... + string symbol, // Specified Position Symbol ... + ENUM_TIMEFRAMES period, // Specified Position Period ... + XPositionPack &pack // Hold Result ... + ) + { + // + bool result = false; + + // + // NOTE: We Have to Force Retrieve Position's pack event + // it's parent Position not Eists ... + pack.ticket = ticket; + pack.supportOrdersCount = 0; + Clean(pack.supportOrders); + pack.supportPositionsCount = 0; + Clean(pack.supportPositions); + + // + XPosition position; + bool hasPosition = GetPosition( + position, + ticket); + if (hasPosition) + { + pack.position = position; + } + + // + XOrder supportOrders[]; + XPosition supportPositions[]; + + // + XOrder orders[]; + GetOrders( + orders, + symbol, // Specified Symbol ... + period, // Specified Period + ORDER_STATE_PLACED // Just UnTriggered Orders ... + ); + int ordersCount = ArraySize(orders); + + // + // Select Orders ... + if (ordersCount > 0) + { + // + for (int i = 0; i < ordersCount; i++) + { + // + XOrder iOrder = orders[i]; + + // + string params[]; + bool hasSupport = ExtractSupportParams( + iOrder.comment, + params); + if (hasSupport) + { + // + ulong parentTicket = ExtractParentTicket(iOrder.comment); + if (parentTicket == ticket) + { + // + Add( + iOrder, + supportOrders); + } + } + } + } + + // + int supportOrdersCount = ArraySize(supportOrders); + if (supportOrdersCount > 0) + { + // + pack.supportOrdersCount = supportOrdersCount; + + // + Copy( + supportOrders, + pack.supportOrders); + } + + // + XPosition positions[]; + GetPositions( + positions, + symbol, // Specified Symbol ... + period // Specified Period ... + ); + int positionsCount = ArraySize(positions); + + // + // Select Positions ... + if (positionsCount > 0) + { + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + string params[]; + bool hasSupport = ExtractSupportParams( + iPosition.comment, + params); + if (hasSupport) + { + // + ulong parentTicket = ExtractParentTicket(iPosition.comment); + if (parentTicket == ticket) + { + // + Add( + iPosition, + supportPositions); + } + } + } + } + + // + int supportPositionsCount = ArraySize(supportPositions); + if (supportPositionsCount > 0) + { + // + pack.supportPositionsCount = supportPositionsCount; + + // + Copy( + supportPositions, + pack.supportPositions); + } + + // + result = supportOrdersCount > 0 || supportPositionsCount > 0; + + // + return result; + } + + // + // Extract Specific Deals Position's Pack ... + // this used when a Position SL or TP triggered and we want to close + // all it's Supported Packs ... + bool GetDealPack( + const XDeal &deal, + XPositionPack &pack) + { + // + bool result = false; + + // + ulong ticket = deal.positionId; + ENUM_TIMEFRAMES dealPeriod = GetDealPeriod(deal); + string dealSymbol = deal.symbol; + + // + // So We Have to Get Positions Pack ... + result = GetPositionPack( + ticket, + dealSymbol, + dealPeriod, + pack); + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... + + // + // EVENTS Handlers Notifiers ... + + // + // STATE ... + void NotifyTradeStateChangeEvent(const XOnTradeHandlerState &state) + { + // + int count = ArraySize(mTradeStateChangedEventHandlers); + if (count <= 0) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + TOnTradeStateChanged iHandler = mTradeStateChangedEventHandlers[i]; + iHandler(state); + } + } + + // + // DEALS ... + void NotifyDealsChangeEvent(int changes) + { + // + int count = ArraySize(mDealsChangedEventHandlers); + if (count <= 0) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + TOnDealsChanged iHandler = mDealsChangedEventHandlers[i]; + iHandler(changes); + } + } + + // + // ORDERS ... + void NotifyOrdersChangeEvent(int changes) + { + // + int count = ArraySize(mOrdersChangedEventHandlers); + if (count <= 0) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + TOnOrdersChanged iHandler = mOrdersChangedEventHandlers[i]; + iHandler(changes); + } + } + + // + // POSITIONS ... + void NotifyPositionsChangeEvent(int changes) + { + // + int count = ArraySize(mPositionsChangedEventHandlers); + if (count <= 0) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + TOnPositionsChanged iHandler = mPositionsChangedEventHandlers[i]; + iHandler(changes); + } + } + + // + // TPSL ... + + // + void NotifyStopLossEvent(const XDeal &deal) + { + // + int count = ArraySize(mStopLossEventHandlers); + if (count <= 0) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + TOnStopLoss iHandler = mStopLossEventHandlers[i]; + iHandler(deal); + } + } + + // + void NotifyTakeProfitEvent(const XDeal &deal) + { + // + int count = ArraySize(mTakeProfitEventHandlers); + if (count <= 0) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + TOnTakeProfit iHandler = mTakeProfitEventHandlers[i]; + iHandler(deal); + } + } + +private: + // + // using deviation, it must be in Point ... + int mSlippage; + + // + // using magic number ... + ulong mMagicNumber; + + // + // using CTrade instance ... + XSCTradeBase mTrader; + + // + // Deals Info ... + CDealInfo mDealInfo; + + // + // Order Info ... + COrderInfo mOrderInfo; + + // + // using PositionInfo instance ... + CPositionInfo mPositionInfo; + + // + // History Orders ... + CHistoryOrderInfo mHistoryOrderInfo; + + // + // ADDITIONAL Data ... + + // + string mPeriodPrefix; + + // + // START Trade Processing ... + // + + // + int mDaysForRead; + + // + // set the limits of the trade history on the global scope ... + + // + // // start date for trade history in cache ... + datetime mStartDate; + + // + // end date for trade history in cache ... + datetime mEndDate; + + // + // global OnTrade counters ... + + // + // number of active orders ... + int mOrdersCount; + + // + // number of open positions ... + int mPositionsCount; + + // + // number of deals in the trade history cache ... + int mDealsCount; + + // + // number of orders in the trade history cache ... + int mHistoryOrdersCount; + + // + // flag of counter relevance ... + bool mScanStarted; + + // + // Check Statrt Date In Trade History ... + void CheckStartDateInTradeHistory() + { + // + // initial interval, if we were to start working right now .. + datetime currStart = TimeCurrent() - (mDaysForRead * PeriodSeconds(PERIOD_D1)); + + // + // make sure that the start limit of the trade history has not gone + // more than 1 day over the intended date ... + if (currStart - mStartDate > PeriodSeconds(PERIOD_D1)) + { + // + // correct the start date of history to be loaded in the cache ... + mStartDate = currStart; + + // + // now reload the trade history for the updated interval ... + HistorySelect(mStartDate, mEndDate); + + // + // correct the deal and order counters in history for further comparison + mHistoryOrdersCount = HistoryOrdersTotal(); + mDealsCount = HistoryDealsTotal(); + } + } + + // + // Process On Trade Context ... + void ProcessOnTradeContext( + XOnTradeHandlerState &result // Hold's Result + ) + { + // + mEndDate = TimeCurrent(); + + // + ResetLastError(); + + // + // download trading history from the specified interval to the program cache ... + bool selected = HistorySelect(mStartDate, mEndDate); + if (!selected) + { + return; + } + + // + // get the current values ... + int currOrders = OrdersTotal(); + int currPositions = PositionsTotal(); + int currDeals = HistoryDealsTotal(); + int currHistoryOrders = HistoryOrdersTotal(); + + // + // Orders ... + // check if the number of active orders has been changed ... + if (currOrders != mOrdersCount) + { + // + // number of active orders has been changed ... + result.hasNewOrder = true; + result.newOrders = currOrders - mOrdersCount; + + // + // update the value ... + mOrdersCount = currOrders; + } + + // + // Positions ... + // changes in the number of open positions ... + if (currPositions != mPositionsCount) + { + // + // number of open positions has been changed ... + result.hasNewPosition = true; + result.newPositions = currPositions - mPositionsCount; + + // + // update the value ... + mPositionsCount = currPositions; + } + + // + // Deals ... + // changes in the number of deals in the trade history cache ... + if (currDeals != mDealsCount) + { + // + // number of deals in the trade history cache has been changed ... + result.hasNewDeal = true; + result.newDeals = currDeals - mDealsCount; + + // + // update the value ... + mDealsCount = currDeals; + } + + // + // History Orders ... + // changes in the number of history orders in the trade history cache ... + if (currHistoryOrders != mHistoryOrdersCount) + { + // + // number of history orders in the trade history cache has been changed ... + result.hasNewHistoryOrder = true; + result.newHistoryOrders = currHistoryOrders - mHistoryOrdersCount; + + // + // update the value ... + mHistoryOrdersCount = currHistoryOrders; + } + + // + // checking if it is necessary to change the limits of the trade history to be requested in cache ... + CheckStartDateInTradeHistory(); + } + + // + // Reset On Trade Scanner Context ... + void ResetOnTradeContext() + { + // + mEndDate = TimeCurrent(); + mStartDate = mEndDate - (mDaysForRead * PeriodSeconds(PERIOD_D1)); + } + + // + // Initial Context Of Trade Scanner ... + void InitOnTradeContext() + { + // + ResetLastError(); + + // + mOrdersCount = OrdersTotal(); + mPositionsCount = PositionsTotal(); + + // + // load history ... + bool selected = HistorySelect(mStartDate, mEndDate); + if (!selected) + { + return; + } + + // + // get the current value ... + mDealsCount = HistoryDealsTotal(); + mHistoryOrdersCount = HistoryOrdersTotal(); + + // + mScanStarted = true; + } + + // + // Deals Changed Event Handlers ... + TOnDealsChanged mDealsChangedEventHandlers[]; + + // + // Orders Changed Event Handlers ... + TOnOrdersChanged mOrdersChangedEventHandlers[]; + + // + // Positions Changed Event Handlers ... + TOnPositionsChanged mPositionsChangedEventHandlers[]; + + // + // Trade State Changed Event Handlers ... + TOnTradeStateChanged mTradeStateChangedEventHandlers[]; + + // + // TPSL ... + TOnStopLoss mStopLossEventHandlers[]; + TOnTakeProfit mTakeProfitEventHandlers[]; + + // + // END Trade Processing ... + // +}; + +// +// START Usefull Functions ... +// + +// +// Add Specific XPosition to Specified Array ... +void Add( + XDeal &item, + XDeal &buffer[]) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + XOrder &item, + XOrder &buffer[]) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + XPosition &item, + XPosition &buffer[]) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} + +// +// Clear All Items Inside Array ... +void Clean(XDeal &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} +void Clean(XOrder &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} +void Clean(XPosition &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} + +// +// Generate Identifier Tag ... +string GenerateTag(XSignal &info) +{ + // + string result = ""; + + // + result = info.symbol + "," + ToString(info.period); + + // + return result; +} + +// +// Convert Position to Signal ... +XSignal ToSignalInfo( + XPosition &position) +{ + // + XSignal result; + + // + result.tp = position.tp; + result.sl = position.sl; + result.type = position.type; + result.entry = position.entry; + result.symbol = position.symbol; + result.period = position.period; + result.volume = position.volume; + + // + return result; +} + +// +// AGE Calculations ... +// + +// +// Retrieve a Position Age ... +int GetAge( + XPosition &position, // Selected Position ... + ENUM_TIMEFRAMES period = NULL // Dest Time Frame ... +) +{ + // + int result = -1; + + // + if (period == NULL) + { + period = _Period; + } + + // + result = iBarShift( + position.symbol, + period, + position.openAt); + + // + return result; +} + +// +// Retrieve an Order Age ... +int GetAge( + XOrder &order, // Selected Order ... + ENUM_TIMEFRAMES period = NULL // Dest Time Frame ... +) +{ + // + int result = -1; + + // + if (period == NULL) + { + period = _Period; + } + + // + result = iBarShift( + order.smybol, + period, + order.setupAt); + + // + return result; +} + +// +// Retrieve a Deal Age ... +int GetAge( + XDeal &deal, // Selected Deal ... + ENUM_TIMEFRAMES period = NULL // Dest Time Frame ... +) +{ + // + int result = -1; + + // + if (period == NULL) + { + period = _Period; + } + + // + result = iBarShift( + deal.symbol, + period, + deal.time); + + // + return result; +} + +// +// OLDEST Detection ... + +// +// Get Oldest Deal ... +int GetOldest( + XDeal &item, // Hold Result ... + XDeal &items[] // Source Array ... +) +{ + // + int result = 0; + + // + int itemsCount = ArraySize(items); + if (itemsCount <= 0) + { + return result; + } + + // + int tmpAge = 0; + XDeal tmpItem; + for (int i = 0; i < itemsCount; i++) + { + // + XDeal iItem = items[i]; + + // + int iAge = GetAge(iItem); + if (iAge > 0 && + (tmpAge == 0 || tmpAge < iAge)) + { + // + tmpAge = iAge; + tmpItem = iItem; + } + } + + // + if (tmpAge > 0) + { + // + result = tmpAge; + item = tmpItem; + } + + // + return result; +} + +// +// Get Oldest Order ... +int GetOldest( + XOrder &item, // Hold Result ... + XOrder &items[] // Source Array ... +) +{ + // + int result = 0; + + // + int itemsCount = ArraySize(items); + if (itemsCount <= 0) + { + return result; + } + + // + int tmpAge = 0; + XOrder tmpItem; + for (int i = 0; i < itemsCount; i++) + { + // + XOrder iItem = items[i]; + + // + int iAge = GetAge(iItem); + if (iAge > 0 && + (tmpAge == 0 || tmpAge < iAge)) + { + // + tmpAge = iAge; + tmpItem = iItem; + } + } + + // + if (tmpAge > 0) + { + // + result = tmpAge; + item = tmpItem; + } + + // + return result; +} + +// +// Get Oldes Position ... +int GetOldest( + XPosition &item, // Hold Result ... + XPosition &items[] // Source Array ... +) +{ + // + int result = 0; + + // + int itemsCount = ArraySize(items); + if (itemsCount <= 0) + { + return result; + } + + // + int tmpAge = 0; + XPosition tmpItem; + for (int i = 0; i < itemsCount; i++) + { + // + XPosition iItem = items[i]; + + // + int iAge = GetAge(iItem); + if (iAge > 0 && + (tmpAge == 0 || tmpAge < iAge)) + { + // + tmpAge = iAge; + tmpItem = iItem; + } + } + + // + if (tmpAge > 0) + { + // + result = tmpAge; + item = tmpItem; + } + + // + return result; +} + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/X121/14030217/Documents/.gitkeep b/MQLTestWorkspace/X121/14030217/Documents/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/MQLTestWorkspace/X121/14030217/Documents/JsModules/x-color.tools.js b/MQLTestWorkspace/X121/14030217/Documents/JsModules/x-color.tools.js new file mode 100644 index 0000000..c3ac5f9 --- /dev/null +++ b/MQLTestWorkspace/X121/14030217/Documents/JsModules/x-color.tools.js @@ -0,0 +1,506 @@ +/** + * XColor Tools Module ... + * a module for handle colorify text contents in node js ... + * + * Maintainer + * + * Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) + */ + +// +//#region Module Imports ... +const XValueTools = require("./x-value.tools"); +//#endregion + +// +//#region Constants ... +/** + * these are available style which can applied to an string ... + */ +const AVAILABLE_STYLES = { + // + Bold: "\x1b[1m", + Dim: "\x1b[2m", + Underlined: "\x1b[4m", + Blink: "\x1b[5m", + ReverseFandB: "\x1b[7m", + Hidden: "\x1b[8m", + // + // Commonly used for reset all Styles ... + Reset: "\x1b[0m" +}; + +/** + * these are available foreground colors which can applied to an string ... + */ +const AVAILABLE_FOREGROUND_COLORS = { + Default: "\x1b[39m", + Black: "\x1b[30m", + Red: "\x1b[31m", + Green: "\x1b[32m", + Yellow: "\x1b[33m", + Blue: "\x1b[34m", + Magenta: "\x1b[35m", + Cyan: "\x1b[36m", + LightGray: "\x1b[37m", + DarkGray: "\x1b[90m", + LightRed: "\x1b[91m", + LightGreen: "\x1b[92m", + LightYellow: "\x1b[93m", + LightBlue: "\x1b[94m", + LightMagenta: "\x1b[95m", + LightCyan: "\x1b[96m", + White: "\x1b[97m", +}; + +/** + * these are available background colors which can applied to an string ... + */ +const AVAILABLE_BACKGROUND_COLORS = { + Default: "\x1b[49m", + Black: "\x1b[40m", + Red: "\x1b[41m", + Green: "\x1b[42m", + Yellow: "\x1b[43m", + Blue: "\x1b[44m", + Magenta: "\x1b[45m", + Cyan: "\x1b[46m", + LightGray: "\x1b[47m", + DarkGray: "\x1b[100m", + LightRed: "\x1b[101m", + LightGreen: "\x1b[102m", + LightYellow: "\x1b[103m", + LightBlue: "\x1b[104m", + LightMagenta: "\x1b[105m", + LightCyan: "\x1b[106m", + White: "\x1b[107m", +}; + +/** + * these are available style names, which exports from module and + * users can use them ... + */ +const STYLE_NAMES = { + Bold: "Bold", + Dim: "Dim", + Underlined: "Underlined", + Blink: "Blink", + ReverseFandB: "ReverseFandB", + Hidden: "Hidden", + Reset: "Reset", +}; + +/** + * these are available color names, which exports from module and + * users can use them ... + */ +const COLOR_NAMES = { + Default: "Default", + Black: "Black", + Red: "Red", + Green: "Green", + Yellow: "Yellow", + Blue: "Blue", + Magenta: "Magenta", + Cyan: "Cyan", + LightGray: "LightGray", + DarkGray: "DarkGray", + LightRed: "LightRed", + LightGreen: "LightGreen", + LightYellow: "LightYellow", + LightBlue: "LightBlue", + LightMagenta: "LightMagenta", + LightCyan: "LightCyan", + White: "White", +}; +//#endregion + +// +//#region Actions ... +/** + * apply specified style and color on a content ... + * + * @param {string} content specified content for styling ... + * @param {string} color specific color name for using to styling ... + * @param {string} style soecufic style name to use ... + * @param {boolean} toForeground apply specified color as foreground ... + * @param {boolean} toBackground apply specified color as background ... + * @returns {string} styled content ... + */ +function apply( + content, + color, + style, + toForeground = true, + toBackground = false +) { + // + let result = content; + + // + // Validate Arg ... + if (!XValueTools.isValidArg(content)) { + return result; + } + + // + // Detect and Validate Style and Apply it ... + let eStyle = AVAILABLE_STYLES[style]; + if (XValueTools.isValidArg(eStyle)) { + result = `${eStyle}${result}${AVAILABLE_STYLES.Reset}`; + } + + // + // Detect and Validate Foreground Color and Apply it ... + let eFColor = AVAILABLE_FOREGROUND_COLORS[color]; + if ( + !!toForeground + && XValueTools.isValidArg(eFColor) + ) { + result = `${eFColor}${result}${AVAILABLE_STYLES.Reset}`; + } + + // + // Detect and Validate Background Color and Apply it ... + let eBColor = AVAILABLE_BACKGROUND_COLORS[color]; + if ( + !!toBackground + && XValueTools.isValidArg(eBColor) + ) { + result = `${eBColor}${result}${AVAILABLE_STYLES.Reset}`; + } + +} + +/** + * apply specific style on a content ... + * + * @param {string} content specific content which going to styled ... + * @param {string} style a member of STYLE_NAMES which specified that which style going to applied to content ... + * @returns {string} styled content ... + */ +function applyStyle(content, style) { + // + // Validate Arg ... + if (!XValueTools.isValidArg(content)) { + return content; + } + + // + let eStyle = AVAILABLE_STYLES[style]; + if (eStyle === undefined) { + return content; + } + + // + return `${eStyle}${content}${AVAILABLE_STYLES.Reset}`; +} + +/** + * apply specific foreground color on a content ... + * + * @param {string} content specific content which going to colorified ... + * @param {string} color a member of COLOR_NAMES which specified that which color going to applied to content ... + * @returns {string} colorified content ... + */ +function applyForegroundColor(content, color) { + // + // Validate Arg ... + if (!XValueTools.isValidArg(content)) { + return content; + } + + // + let eColor = AVAILABLE_FOREGROUND_COLORS[color]; + if (eColor === undefined) { + return content; + } + + // + return `${eColor}${content}${AVAILABLE_STYLES.Reset}`; +} + +/** + * apply specific background color on a content ... + * + * @param {string} content specific content which going to colorified ... + * @param {string} color a member of COLOR_NAMES which specified that which color going to applied to content ... + * @returns {string} colorified content ... + */ +function applyBackgroundColor(content, color) { + // + // Validate Arg ... + if (!XValueTools.isValidArg(content)) { + return content; + } + + // + let eColor = AVAILABLE_BACKGROUND_COLORS[color]; + if (eColor === undefined) { + return content; + } + + // + return `${eColor}${content}${AVAILABLE_STYLES.Reset}`; +} + +/** + * generate style and color applier expression ... + * + * @param {string} color specific color name for using to styling ... + * @param {string} style soecufic style name to use ... + * @param {boolean} reset close applier string by reset styles ... + * @param {boolean} toForeground apply specified color as foreground ... + * @param {boolean} toBackground apply specified color as background ... + * @returns {string} style and color applier string ... + */ +function getApplier( + style = "", + color = "", + reset = false, + toForeground = true, + toBackground = false +) { + // + let result = ""; + + // + // Detect and Validate Style and Apply it ... + let eStyle = AVAILABLE_STYLES[style]; + if (XValueTools.isValidArg(eStyle)) { + result = `${eStyle}`; + } + + // + // Detect and Validate Foreground Color and Apply it ... + let eFColor = AVAILABLE_FOREGROUND_COLORS[color]; + if ( + !!toForeground + && XValueTools.isValidArg(eFColor) + ) { + result = `${eFColor}`; + } + + // + // Detect and Validate Background Color and Apply it ... + let eBColor = AVAILABLE_BACKGROUND_COLORS[color]; + if ( + !!toBackground + && XValueTools.isValidArg(eBColor) + ) { + result = `${eBColor}`; + } + + // + if ( + !!reset && + result.length > 0 + ) { + result = `${result}${AVAILABLE_STYLES.Reset}`; + } + + // + return result; +} + +/** + * generate style applier expression ... + * + * @param {string} style soecufic style name to use ... + * @param {boolean} reset close applier string by reset styles ... + * @returns {string} style applier string ... + */ +function getStyleApplier( + style = "", + reset = false +) { + // + let result = ""; + + // + // Detect and Validate Style and Apply it ... + let eStyle = AVAILABLE_STYLES[style]; + if (XValueTools.isValidArg(eStyle)) { + result = `${eStyle}`; + } + + // + if ( + !!reset && + result.length > 0 + ) { + result = `${result}${AVAILABLE_STYLES.Reset}`; + } + + // + return result; +} + +/** + * generate color applier expression ... + * + * @param {string} color specific color name for using to styling ... + * @param {boolean} reset close applier string by reset styles ... + * @param {boolean} toForeground apply specified color as foreground ... + * @param {boolean} toBackground apply specified color as background ... + * @returns {string} color applier string ... + */ +function getColorApplier( + color = "", + reset = false, + toForeground = true, + toBackground = false +) { + // + let result = ""; + + // + // Detect and Validate Foreground Color and Apply it ... + let eFColor = AVAILABLE_FOREGROUND_COLORS[color]; + if ( + !!toForeground + && XValueTools.isValidArg(eFColor) + ) { + result = `${eFColor}`; + } + + // + // Detect and Validate Background Color and Apply it ... + let eBColor = AVAILABLE_BACKGROUND_COLORS[color]; + if ( + !!toBackground + && XValueTools.isValidArg(eBColor) + ) { + result = `${eBColor}`; + } + + // + if ( + !!reset && + result.length > 0 + ) { + result = `${result}${AVAILABLE_STYLES.Reset}`; + } + + // + return result; +} + +/** + * colorified specific content ... + * + * @param {string} content specified content for styling ... + * @param {string} color specific color name for using to styling ... + * @param {boolean} toForeground apply specified color as foreground ... + * @param {boolean} toBackground apply specified color as background ... + * @returns {string} + */ +function colorifyContent( + content = "", + color = "", + toForeground = true, + toBackground = false +) { + // + let result = content; + + // + if (!XValueTools.isValidArg(content)) { + return result; + } + + // + // Finde Colors ... + + // + // Detect and Validate Foreground Color and Apply it ... + let eFColor = AVAILABLE_FOREGROUND_COLORS[color]; + if ( + !!toForeground + && XValueTools.isValidArg(eFColor) + ) { + result = `${eFColor}${result}`; + } + + // + // Detect and Validate Background Color and Apply it ... + let eBColor = AVAILABLE_BACKGROUND_COLORS[color]; + if ( + !!toBackground + && XValueTools.isValidArg(eBColor) + ) { + result = `${eBColor}${result}`; + } + + // + if ( + result.length > 0 + && ( + XValueTools.isValidArg(eFColor) || + XValueTools.isValidArg(eBColor) + ) + ) { + result = `${result}${AVAILABLE_STYLES.Reset}`; + } + + // + return result; +} + +/** + * apply style on specific content ... + * + * @param {string} content specified content for styling ... + * @param {string} style soecufic style name to use ... + * @returns {string} + */ +function stylifiyContent( + content = "", + style = "", +) { + // + let result = content; + + // + if (!XValueTools.isValidArg(content)) { + return result; + } + + // + // Detect and Validate Style and Apply it ... + let eStyle = AVAILABLE_STYLES[style]; + if (XValueTools.isValidArg(eStyle)) { + result = `${eStyle}${result}`; + } + + // + if ( + result.length > 0 + && XValueTools.isValidArg(eStyle) + ) { + result = `${result}${AVAILABLE_STYLES.Reset}`; + } + + // + return result; +} +//#endregion + +// +//#region Module Exports ... +module.exports = { + // + STYLE_NAMES, + COLOR_NAMES, + // + apply, + applyStyle, + getApplier, + getColorApplier, + getStyleApplier, + colorifyContent, + stylifiyContent, + applyForegroundColor, + applyBackgroundColor, +} +//#endregion \ No newline at end of file diff --git a/MQLTestWorkspace/X121/14030217/Documents/JsModules/x-file.tools.js b/MQLTestWorkspace/X121/14030217/Documents/JsModules/x-file.tools.js new file mode 100644 index 0000000..a1642a4 --- /dev/null +++ b/MQLTestWorkspace/X121/14030217/Documents/JsModules/x-file.tools.js @@ -0,0 +1,830 @@ +/** + * XFile Tools Module ... + * a module for handle all file/folder manipulating task in node js ... + * + * Maintainer + * + * Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) + */ + +// +//#region Module Imports ... +const fs = require('fs'); +const os = require('os'); +const Path = require('path'); +const http = require('http'); +const https = require('https'); +const XValueTools = require('./x-value.tools'); +//#endregion + +// +//#region Constants ... +/** + * current os path separators ... + */ +const PathSeparator = Path.sep; + +/** + * current directory ... + */ +const CurrentDir = __dirname; +//#endregion + +// +//#region Actions ... +// +//#region Global ... +/** + * retrieve a path status ... + * + * @param {string} path a path value to check ... + * @returns an stat object ... + */ +function getStatus(path = '') { + // + if (!XValueTools.isValidArg(path)) { + return undefined; + } + + // + return fs.statSync(path); +} + +/** + * retrieve user's Home path ... + * + * @returns {string} a path ... + */ +function getHomePath() { + return os.homedir(); +} +//#endregion + +// +//#region Path ... +/** + * retrieve the base name of specific address path ... + * + * @param {string} path address of file or folder ... + * @returns string ... + */ +function basename(path = '') { + // + if (!XValueTools.isValidArg(path)) { + return ''; + } + + // + const result = Path.basename(path); + return result; +} + +/** + * join several path segments together ... + * + * @param {...string} path path params ... + * @returns a joined paths ... + */ +function joinPath(...path) { + return Path.join(...path); +} + +/** + * resolve a relative path to absolute ... + * + * @param {string[]} path a path value to check ... + * @returns {string} + */ +function resolvePath(...path) { + return Path.resolve(...path); +} +//#endregion + +// +//#region File ... +/** + * determines a path destination is a file or not ... + * + * @param {string} path a path value to check ... + * @returns a boolean value ... + */ +function isFileExists(path = '') { + // + if (!XValueTools.isValidArg(path)) { + return false; + } + + // + try { + const stat = getStatus(path); + if (!stat) { + return false; + } + + // + return stat.isFile(); + } catch { + return false; + } +} + +/** + * remove a file ... + * + * @param {string} path a file path ... + * @returns {Promise} action done or not ... + */ +function removeFile(path = '') { + return new Promise((resolve) => { + // + if (!isFileExists(path)) { + resolve(false); + } + + // + fs.unlink(path, (err) => { + // + if (err) { + resolve(false); + return; + } + + // + resolve(true); + }); + }); +} + +/** + * copy a file to destination path ... + * + * @param {string} source source file path ... + * @param {string} dest dest folder path ... + * @returns {Promise} action done or not ... + */ +function copyFile( + source = '', + dest = '' +) { + return new Promise((resolve) => { + // + if ( + !isFileExists(source) || + !isDirectoryExists(dest) + ) { + resolve(false); + return; + } + + // + const destFilePath = Path.join(dest, Path.basename(source)); + fs.copyFile(source, destFilePath, (err) => { + // + if (err) { + resolve(false); + return; + } + + // + resolve(true); + }); + }); +} + +/** + * reading specified file content ... + * + * @param {string} path a file path ... + * @returns {Promise} file content ... + */ +function readFile(path = '') { + return new Promise((resolve) => { + // + if (!isFileExists(path)) { + resolve(''); + return; + } + + // + fs.readFile(path, 'utf8', (err, content) => { + // + if (err) { + resolve(undefined); + return; + } + + // + resolve(content); + }); + }); +} + +/** + * write content to a file ... + * + * @param {string} path a file path ... + * @param {string} content the content which going to write to the file ... + * @param {bool} overwrite determines file overwrite if exists ... + * @returns {Promise} action done or not ... + */ +function writeFile( + path = '', + content = '', + overwrite = true +) { + return new Promise((resolve) => { + // + if (isFileExists(path) && !overwrite) { + // + resolve(false); + return; + } + + // + // Normalize Content ... + content = XValueTools.isValidArg(content) ? + content : + ''; + + // + fs.writeFile(path, content, (err) => { + // + if (err) { + // + resolve(false); + return; + } + + // + resolve(true); + }); + }); +} + +/** + * create a file ... + * + * @param {string} path file path ... + * @param {string} fileName file name ... + * @returns {Promise} action done or not ... + */ +function createFile( + path = '', + fileName = '' +) { + return new Promise((resolve) => { + // + const filePath = Path.join(path, fileName); + if ( + isFileExists(filePath) || + !XValueTools.isValidArg(path) || + !XValueTools.isValidArg(fileName) + ) { + // + resolve(false); + return; + } + + // + fs.writeFile(filePath, '', (err) => { + // + if (err) { + // + resolve(false); + return; + } + + // + resolve(true); + }); + }); +} + +/** + * remove a file name extension ... + * + * @param {string} name + * @returns {string} name without extension ... + */ +function removeFileExtension(name = '') { + return name.substring(0, name.lastIndexOf('.')) || name; +} + +/** + * retrieve a file extension ... + * + * @param {string} path a path which locate a file ... + * @returns {string} + */ +function getFileExtension(path = '') { + // + let result = ""; + + // + // Validate Arg ... + if ( + !XValueTools.isValidArg(path) + || !isFileExists(path) + ) { + return result; + } + + // + // Retrieve just file name ... + const fileName = basename(path); + result = fileName.replace( + removeFileExtension(fileName), + "" + ); + + // + return result; +} + +/** + * retrieve all files list recursively from specific path ... + * + * @param {string} path a source folder path ... + * @param {string[]} extensions which file extensions need to be listed, live empty for all files ... + * @returns {Promise} + */ +async function getRecursiveFilesList( + path = "", + extensions = [] +) { + // + let result = []; + + // + // Validate Args ... + if ( + !XValueTools.isValidArg(path) + || !isDirectoryExists(path) + ) { + return result; + } + + // + const contents = await getDirectoryContents(path); + for(const item of contents) { + // + const itemPath = joinPath( + path, + item + ); + + // + const isItemFile = isFileExists(itemPath); + if (isItemFile) { + // + const itemFileExtension = getFileExtension(itemPath); + const isFileInSupportedExtensions = + extensions === undefined || extensions.length === 0 + ? true + : extensions.includes(itemFileExtension) + ; + if (isFileInSupportedExtensions) { + result.push(itemPath); + } + } else if (isDirectoryExists(itemPath)) { + // + const itemPathFiles = await getRecursiveFilesList(itemPath, extensions); + result.push(...itemPathFiles); + } + } + + // + return result; +} +//#endregion + +// +//#region Directory ... +/** + * create a directory ... + * + * @param {string} path destination path including dir name ... + * @param {boolean} recursive create directories recursively ... + * @returns action done or not ... + */ +function createDirectory( + path = '', + recursive = true +) { + // + let result = false; + + // + if ( + isDirectoryExists(path) || + !XValueTools.isValidArg(path) + ) { + return false; + } + + // + try { + // + fs.mkdirSync(path, { recursive: recursive }); + result = true; + return result; + } catch { + return false; + } +} + +/** + * remove a directory ... + * + * @param {string} path destination path including dir name ... + * @param {boolean} recursive removes directories recursively ... + * @returns {Promise} action done or not ... + */ +function removeDirectory( + path = '', + recursive = false +) { + return new Promise((resolve) => { + // + if (!isDirectoryExists(path)) { + resolve(false); + return; + } + + // + fs.rm(path, { + recursive + }, (err) => { + // + if (err) { + resolve(false); + return; + } + + // + resolve(true); + }); + }); +} + +/** + * determines a path destination is a directory or not ... + * + * @param {string} path a folder path ... + * @returns represent destnation path is Directory or not ... + */ +function isDirectoryExists(path = '') { + // + if (!XValueTools.isValidArg(path)) { + return false; + } + + // + try { + // + const isExists = fs.existsSync(path); + if (!isExists) { + return false; + } + + // + const stat = getStatus(path); + if (!stat) { + return false; + } + + // + const result = stat.isDirectory(); + return result; + } catch { + return false; + } +} + +/** + * retrieve a directory content ... + * + * @param {string} path a folder path ... + * @returns {Promise} a collection of folder files ... + */ +function getDirectoryContents(path = '') { + return new Promise((resolve) => { + // + if (!isDirectoryExists(path)) { + resolve([]); + return; + } + + // + fs.readdir(path, (err, content) => { + // + if (err) { + resolve([]); + return; + } + + // + resolve(content); + }); + }); +} + +/** + * retrieve a directory files ... + * + * @param {string} path a folder path ... + * @returns {Promise} a collection of folder files ... + */ +function getDirectoryFiles( + path = '', + containsHiddenFiles = false +) { + return new Promise((resolve) => { + // + if (!isDirectoryExists(path)) { + resolve([]); + return; + } + + // + fs.readdir(path, (err, content) => { + // + if (err) { + resolve([]); + return; + } + + // + if (!containsHiddenFiles) { + content = content.filter(c => !c.startsWith('.')); + } + + // + const result = []; + content + .forEach(c => { + // + const cPath = Path.join(path, c); + if (isFileExists(cPath)) { + result.push(c); + } + }); + + // + resolve(result); + }); + }); +} + +/** + * retrieve a directory folders ... + * + * @param {string} path a folder path ... + * @returns {Promise} a collection of folder names ... + */ +function getDirectoryFolders(path = '') { + return new Promise((resolve) => { + // + if (!isDirectoryExists(path)) { + resolve([]); + return; + } + + // + fs.readdir(path, (err, content) => { + // + if (err) { + resolve([]); + return; + } + + // + const result = []; + content.forEach(c => { + // + const cPath = Path.join(path, c); + if (isDirectoryExists(cPath)) { + result.push(c); + } + }); + + // + resolve(result); + }); + }); +} + +/** + * copy a folder with all of it's content to dest ... + * + * @param {string} source source folder path ... + * @param {string} dest dest folder path ... + * @returns {Promise} action done or not ... + */ +async function copyFolder( + source = '', + dest = '' +) { + // + if ( + !isDirectoryExists(source) || + !XValueTools.isValidArg(dest) || + !XValueTools.isValidArg(source) + ) { + return false; + } + + // + const folderName = Path.basename(source); + const destPath = Path.join(dest, folderName); + + // + // Create Dest Path folder if not exists ... + if (!isDirectoryExists(destPath)) { + // + let result = createDirectory(destPath, true); + if (!result) { + return false; + } + } + + // + // Files ... + const files = await getDirectoryFiles(source); + if (files && files.constructor === Array && files.length > 0) { + // + const filesPromises = files.map(file => copyFile(Path.join(source, file), destPath)); + const filesResult = (await Promise.all(filesPromises)).every(r => !!r); + if (!filesResult) { + return false; + } + } + + // + // Folders ... + const folders = await getDirectoryFolders(source); + if (folders && folders.constructor === Array && folders.length > 0) { + // + const folderPromises = folders.map(folder => copyFolder(Path.join(source, folder), destPath)); + const filesResult = (await Promise.all(folderPromises)).every(r => !!r); + if (!filesResult) { + return false; + } + } + + // + return true; +} +//#endregion + +// +//#region Downloader ... +/** + * download a file from specific url and store it ... + * + * @param {string} filepath the file name and path which required to put download file on it ... + * @param {string} url the web url for downloading ... + */ +function download(filepath, url) { + // + // Validate Args ... + if ( + !XValueTools.isValidArg(url) + || !XValueTools.isValidURL(url) + || !XValueTools.isValidArg(filepath) + ) { + return; + } + + // + var file = fs.createWriteStream(filepath); + + // + if (url.startsWith('https:')) { + https.get(url, function (response) { + response.pipe(file); + }); + } else if (url.startsWith('http:')) { + http.get(url, function (response) { + response.pipe(file); + }); + } +} +//#endregion + +// +//#region JSON ... +/** + * read and parse a JSON content from a file ... + * + * @param {string} path source file path ... + * @returns {any} + */ +function readJSON(path = "") { + // + // Validate Args ... + if (!isFileExists(path)) { + return undefined; + } + + // + let result = undefined; + try { + result = require(path); + } catch { + result = undefined; + } + + // + return result; +} + +/** + * write a JSON Object content into a file ... + * + * @param {string} path dest file path ... + * @param {any} content an object which required to write to file ... + * @returns {Promise} + */ +async function writeJSON( + path = "", + content = undefined +) { + // + let result = false; + + // + // Validate Args ... + if (!XValueTools.isValidArg(path)) { + return result; + } + + // + // Normallize Content ... + if (content === undefined) { + content = {}; + } + + // + const contentString = XValueTools.beautifyJSON(content); + + // + result = await writeFile( + path, + contentString, + true + ); + + // + return result; +} +//#endregion +//#endregion + +// +//#region Module Exports ... +module.exports = { + // + CurrentDir, + PathSeparator, + + // + getStatus, + getHomePath, + + // + basename, + joinPath, + resolvePath, + + // + download, + + // + readJSON, + writeJSON, + + // + copyFile, + readFile, + writeFile, + createFile, + removeFile, + isFileExists, + getFileExtension, + removeFileExtension, + getRecursiveFilesList, + + // + copyFolder, + createDirectory, + removeDirectory, + createDirectory, + removeDirectory, + isDirectoryExists, + isDirectoryExists, + getDirectoryFiles, + getDirectoryFolders, + getDirectoryContents, +} +//#endregion \ No newline at end of file diff --git a/MQLTestWorkspace/X121/14030217/Documents/JsModules/x-shell.tools.js b/MQLTestWorkspace/X121/14030217/Documents/JsModules/x-shell.tools.js new file mode 100644 index 0000000..0ee13de --- /dev/null +++ b/MQLTestWorkspace/X121/14030217/Documents/JsModules/x-shell.tools.js @@ -0,0 +1,219 @@ +/** + * XShell Tools Module ... + * a module for handling shell actions and retrieve OS Info in node js ... + * + * Maintainer + * + * Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) + */ + +// +//#region Imports ... +const os = require('os'); +const process = require('process'); +const { exec } = require("child_process"); +const XFileTools = require('./x-file.tools'); +//#endregion + +// +//#region Constants ... +// +const OS = { + Aix: 'aix', + Darwin: 'darwin', + FreeBSD: 'freebsd', + Linux: 'linux', + OpenBSD: 'openbsd', + SnOS: 'sunos', + Windows: 'win32' +}; + +// +const isWindows = process.platform === OS.Windows; +//#endregion + +// +//#region Actions ... +// +//#region Pure shell commands ... +/** + * execute a command using NodeJS on shell ... + * + * @param {string} cmd command to execute ... + * @param {string} cwd working directory ... + * + * @returns Promise instance ... + */ +function execute(cmd, cwd) { + return new Promise((resolve, reject) => { + // + if (!cmd || cmd.toString().length === 0 || (cwd && !XFileTools.isDirectoryExists(cwd))) { + reject('invalid args ...'); + return; + } + + // + exec(cmd, { cwd }, (err, result, stdError) => { + // + if (err) { + reject(err); + return; + } + + // + if (stdError) { + // + // reject(stdError); + // return; + } + + // + resolve(result); + }); + }); +}; + +/** + * determines a command exists on host or not ... + * + * @param {string} name specific command name ... + * + * @returns boolean Promise ... + */ +function checkCommandExists(name) { + return new Promise(resolve => { + // + if (!name) { + resolve(false); + return; + } + + // + const cmd = isWindows ? `${name} >nul 2>&1` : `type ${name} >/dev/null 2>&1`; + execute(cmd).then(result => { + resolve(true); + }) + .catch(err => { + resolve(false); + }); + }); +} +//#endregion + +// +//#region required commands state ... +/** + * check al required commands exists or not ... + * + * @returns + */ +async function isRequiredCommandsExists() { + // + let result = false; + + // + // const isTarExists = await isTarCommandExists(); + // const isCatExists = await isCatCommandExists(); + // const isGrepExists = await isGrepCommandExists(); + // const isSedExists = await isSedCommandExists(); + const isNpmExists = await isNpmCommandExists(); + const isNgExists = await isNgCommandExists(); + const isIonicExists = await isIonicCommandExists(); + const isCordovaExists = await isCordovaCommandExists(); + + // + result = isNpmExists + && isNgExists + && isIonicExists + && isCordovaExists + ; + + // + return result; +} + +/** + * retrieve required commands state object ... + * + * @returns + */ +async function getRequiredCommandsStates() { + // + const result = {}; + + // + // const isTarExists = await isTarCommandExists(); + // const isCatExists = await isCatCommandExists(); + // const isGrepExists = await isGrepCommandExists(); + // const isSedExists = await isSedCommandExists(); + const isNpmExists = await isNpmCommandExists(); + const isNgExists = await isNgCommandExists(); + const isIonicExists = await isIonicCommandExists(); + const isCordovaExists = await isCordovaCommandExists(); + + // + result['npm'] = isNpmExists; + result['ng'] = isNgExists; + result['ionic'] = isIonicExists; + result['cordova'] = isCordovaExists; + + // + return result; +} +//#endregion + +// +//#region Commonly used Command Checkers ... +/** + * determines npm command exists or not ... + * + * @returns + */ +function isNpmCommandExists() { + return checkCommandExists('npm'); +} + +/** + * determines ng command exists or not ... + * + * @returns + */ +function isNgCommandExists() { + return checkCommandExists('ng'); +} + +/** + * determines ionic command exists or not ... + * + * @returns + */ +function isIonicCommandExists() { + return checkCommandExists('ionic'); +} + +/** + * determines cordova command exists or not ... + * + * @returns + */ +function isCordovaCommandExists() { + return checkCommandExists('cordova'); +} +//#endregion +//#endregion + +// +//#region Module Exports ... +module.exports = { + // + execute, + checkCommandExists, + isRequiredCommandsExists, + getRequiredCommandsStates, + + // + isNgCommandExists, + isIonicCommandExists, + isCordovaCommandExists, +} +//#endregion \ No newline at end of file diff --git a/MQLTestWorkspace/X121/14030217/Documents/JsModules/x-type-detector.tools.js b/MQLTestWorkspace/X121/14030217/Documents/JsModules/x-type-detector.tools.js new file mode 100644 index 0000000..86ed3d8 --- /dev/null +++ b/MQLTestWorkspace/X121/14030217/Documents/JsModules/x-type-detector.tools.js @@ -0,0 +1,268 @@ +/** + * DataType Tools Module ... + * a module for manipulate and detect supported data types in node js ... + * + * Maintainer + * + * Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) + */ + +// +//#region Constants ... +/** + * all supported data types ... + */ +const DataTypes = { + Null: 'null', + Date: 'date', + Array: 'array', + Object: 'object', + String: 'string', + Number: 'number', + Unknown: 'unknown', + Boolean: 'boolean', + Function: 'function', + Undefined: 'undefined', +}; +//#endregion + +// +//#region Actions ... +/** + * detect type of a content ... + * + * @param {any} value the content which going to check ... + * @returns + */ +function getType(value) { + // + const type = typeof value; + + // + let result = DataTypes.Unknown; + let dateIdentifier = '[object Date]'; + let constructor = value && value.constructor ? + value.constructor.toString() : + ''; + + // + switch (type) { + // + case 'undefined': + result = DataTypes.Undefined; + break; + + // + case 'boolean': + result = DataTypes.Boolean; + break; + + // + case 'string': + result = DataTypes.String; + break; + + // + case 'number': + result = DataTypes.Number; + break; + + // + case 'function': + result = DataTypes.Function; + break; + + // + case 'object': + // + // Null ... + if (value === null) { + result = DataTypes.Null; + } else + // + // Array ... + if (Array.isArray(value)) { + result = DataTypes.Array; + } else + // + // Data ... + if ( + value instanceof Date || + isFunction(value.getMonth) || + constructor.includes(dateIdentifier) || + Object.prototype.toString.call(value) === dateIdentifier + ) { + result = DataTypes.Date; + } else + // + // Object ... + { + result = DataTypes.Object; + } + break; + + // + default: + result = DataTypes.Unknown; + break; + } + + // + return result; +} + +/** + * retrieve an object constructor ... + * + * @param {any} value the content which going to check ... + * @returns + */ +function getConstructor(value) { + // + const result = value && value.constructor ? + value.constructor.toString() : + ''; + + // + return result; +} + +/** + * retrieve an object prototype ... + * + * @param {any} value the content which going to check ... + * @returns + */ +function getPrototype(value) { + // + const result = value ? + Object.prototype.toString.call(value) : + ''; + + // + return result; +} + +/** + * check an object is null or not ... + * + * @param {any} value the content which going to check ... + * @returns + */ +function isNull(value) { + return getType(value) === DataTypes.Null; +} + +/** + * check an object is undefined or not ... + * + * @param {any} value the content which going to check ... + * @returns + */ +function isUndefined(value) { + return getType(value) === DataTypes.Undefined; +} + +/** + * check an object is null or undefined or not ... + * + * @param {any} value the content which going to check ... + * @returns + */ +function isNullOrUndefined(value) { + return isNull(value) || isUndefined(value); +} + +/** + * check an object is a date or not ... + * + * @param {any} value the content which going to check ... + * @returns + */ +function isDate(value) { + return getType(value) === DataTypes.Date; +} + +/** + * check an object is number or not ... + * + * @param {any} value the content which going to check ... + * @returns + */ +function isNumber(value) { + return getType(value) === DataTypes.Number; +} + +/** + * check an object is string or not ... + * + * @param {any} value the content which going to check ... + * @returns + */ +function isString(value) { + return getType(value) === DataTypes.String; +} + +/** + * check an object is boolean or not ... + * + * @param {any} value the content which going to check ... + * @returns + */ +function isBoolean(value) { + return getType(value) === DataTypes.Boolean; +} + +/** + * check an object is an Array or not ... + * + * @param {any} value the content which going to check ... + * @returns + */ +function isArray(value) { + return getType(value) === DataTypes.Array; +} + +/** + * check an object is and Object or not ... + * + * @param {any} value the content which going to check ... + * @returns + */ +function isObject(value) { + return getType(value) === DataTypes.Object; +} + +/** + * check an object is a Function or not ... + * + * @param {any} value the content which going to check ... + * @returns + */ +function isFunction(value) { + return getType(value) === DataTypes.Function; +} +//#endregion + +// +//#region Module Exports ... +module.exports = { + // + DataTypes, + + // + getType, + getConstructor, + getPrototype, + isNull, + isUndefined, + isNullOrUndefined, + isDate, + isNumber, + isString, + isBoolean, + isArray, + isObject, + isFunction, +} +//#endregion \ No newline at end of file diff --git a/MQLTestWorkspace/X121/14030217/Documents/JsModules/x-value.tools.js b/MQLTestWorkspace/X121/14030217/Documents/JsModules/x-value.tools.js new file mode 100644 index 0000000..81cfcc4 --- /dev/null +++ b/MQLTestWorkspace/X121/14030217/Documents/JsModules/x-value.tools.js @@ -0,0 +1,1528 @@ +/** + * Value Tools Module ... + * a module for Validate args and values ... + * + * Maintainer + * + * Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) + */ + +// +//#region Imports ... +const XTypeTools = require('./x-type-detector.tools'); +//#endregion + +// +//#region Actions ... +/** +* validate a value as an argument ... +* +* @param {string} value the value which going to validate ... +* @returns +*/ +function isValidArg(value) { + // + let result = false; + + // + result = value && + value.length > 0; + + // + return result; +} + +/** + * validate a collection of valuea as an arguments ... + * + * @param {string|string[]} values the value collection which going to checked ... + * @returns + */ +function isValidArgs(values) { + // + // Normalize Values ... + const normalValues = toNormalArray(values); + if (!hasChildArray(normalValues)) { + return false; + } + + // + let result = normalValues.every(nv => isValidArg(nv)); + return result; +} + +/** + * converts content to an array object ... + * + * @param {string|string[]} content the content which required to normalized ... + * @returns {string[]} array object ... + */ +function toNormalArray(content = '') { + // + // Validate Args ... + if (!isValidArg(content)) { + return []; + } + + // + const result = Array.isArray(content) ? + [...content] : + content.includes(',') && + content !== ',' ? + [...content.split(',')] : + [content]; + + // + return result; +} + +/** + * determines value is array and has atleast one child ... + * + * @param {any} value the value which going to checked ... + * @returns {boolean} result of checking ... + */ +function hasChildArray(value) { + // + let result = false; + result = value && + Array.isArray(value) && + value.length > 0; + + // + return result; +} + +/** + * check an string is ends with specified symbol ... + * + * @param {string} symbol specified search symbol ... + * @param {string} value specified search content ... + * @param {boolean} ignoreCase specified search case sensitive or not ... + * @returns + */ +function endsWidth( + symbol = '', + value = '', + ignoreCase = true +) { + // + if (!isValidArg(value)) { + return false; + } + + // + if (!isValidArg(symbol)) { + return true; + } + + // + // TODO: uncomment it if necessary ... + // symbol = symbol.trim(); + + // + let result = false; + const subtractedContent = value.substring(value.length - symbol.length); + result = !!ignoreCase ? + subtractedContent + .toLowerCase() === symbol + .toLowerCase() : + subtractedContent === symbol; + + // + return result; +} + +/** + * surround specified content by provided symbol ... + * + * @param {string} symbol surround string ... + * @param {string} content used content to surrounded by symbol ... + * @returns surrounded content ... + */ +function surroundBy( + symbol = '', + content = '' +) { + // + // Validate Args ... + if (!isValidArg(content)) { + content = ''; + } + + // + if (!isValidArg(symbol)) { + symbol = ''; + } + + // + if (isSurrounded(symbol, content)) { + return content; + } + + // + const result = `${symbol}${content}${symbol}`; + return result; +} + +/** + * convert a parsed sign to clear string ... + * + * @param {string} value a parsed content ... + * @returns clear parsed signs ... + */ +function toStringExpression(value) { + // + let result = ''; + result = value; + + // + if ( + !value || + !isValidArg(value) || + !isSurroundedString(value) + ) { + return result; + } + + // + const startSymbol = value.charAt(0); + const endSymbol = value.charAt(value.length - 1); + + // + if (startSymbol !== endSymbol) { + return result; + } + + // + if ( + startSymbol === "\"" || + startSymbol === "\'" + ) { + result = clearSurround(startSymbol, value); + } + + // + return result; +} + + + +/** + * find and cleare proposed candidates from specified content ... + * + * @param {string|string[]} candidates the proposed string(s) whic going to cleared from content ... + * @param {string} content the destination content which used to find and replace candidates on it ... + * @returns cleared content ... + */ +function clearContent( + candidates, + content +) { + // + // Validate Args ... + if ( + !candidates || + !isValidArg(content) + ) { + return ''; + } + + // + // Normalize candidates ... + const normalCandidates = toNormalArray(candidates) + .filter(c => isValidArg(c)); + if (!hasChildArray(normalCandidates)) { + return content; + } + + // + // define regexp for content ... + const regExpExpression = normalCandidates.join('|'); + const regExp = new RegExp( + regExpExpression, + 'gi' + ); + + // + let result = ''; + result = content.replace(regExp, ''); + + // + return result; +} + +/** + * clear surrounded symbol from content ... + * + * @param {string} symbol specified search symbol ... + * @param {string} content specified content to clear ... + * @returns + */ +function clearSurround( + symbol = '', + content = '' +) { + // + // Validate Args ... + if ( + !isValidArg(content) || + (isValidArg(symbol) && + symbol.length >= content.length - 1) + ) { + return ''; + } + + // + // Validate Surround ... + if (!isSurrounded(symbol, content)) { + return content; + } + + // + if (!isValidArg(symbol)) { + return content; + } + + // + let result = content.substring(symbol.length, content.length - symbol.length); + return result; +} + +/** + * clear object sign ... + * + * @param {string} content + * @returns cleared content ... + */ +function clearObjectSurround(content = '') { + // + // Validate Args ... + if ( + !isValidArg(content) || + !isSurroundedObject(content) + ) { + return content; + } + + // + const endIndex = content.length - ( + endsWidth('}', content) ? + 1 : + endsWidth('},', content) || + endsWidth('};', content) || + endsWidth('}\n', content) ? + 2 : + 0 + ); + + // + const result = content.substring(1, endIndex); + return result; +} + +/** + * clear array sign ... + * + * @param {string} content + * @returns cleared content ... + */ +function clearArraySurround(content = '') { + // + // Validate Args ... + if ( + !isValidArg(content) || + !isSurroundedArray(content) + ) { + return content; + } + + // + const endIndex = content.length - ( + endsWidth(']', content) ? + 1 : + endsWidth('],', content) || + endsWidth('];', content) || + endsWidth(']\n', content) ? + 2 : + 0 + ); + + // + const result = content.substring(1, endIndex); + return result; +} + +/** + * slice a content to individual parts ... + * + * @param {number|number[]} indexes which indexes used to slice ... + * @param {strng} content the content which going to sliced ... + * @returns sliced parts of content ... + */ +function sliceContent(indexes, content) { + // + // Validate Args ... + if ( + !isValidArg(indexes) || + !isValidArg(content) + ) { + return []; + } + + // + // Normalize indexes ... + const normalIndexes = toNormalArray(indexes) + .filter(index => index > -1 && index < content.length); + if (!hasChildArray(normalIndexes)) { + return []; + } + + // + let result = ['']; + result.pop(); + + // + let lastIndex = 0; + for (const index of normalIndexes) { + // + const part = content.substring(lastIndex, index); + if (isValidArg(part)) { + result.push(part.trim()); + } + + // + lastIndex = index + 1; + } + + // + // check remained parts ... + if (lastIndex < content.length) { + // + const part = content.substring(lastIndex); + if (isValidArg(part)) { + result.push(part.trim()); + } + } + + // + return result; +} + + + +/** + * check an string is starts and ends with specified symbol ... + * + * @param {string} symbol specified search symbol ... + * @param {string} content specified search content ... + * @param {boolean} ignoreCase specified search case sensitive or not ... + * @returns + */ +function isSurrounded( + symbol = '', + content = '', + ignoreCase = true +) { + // + // Validate Args ... + if (!isValidArg(content)) { + return false; + } + + // + if (!isValidArg(symbol)) { + return true; + } + + // + symbol = symbol.trim(); + + // + let result = false; + result = (!!ignoreCase ? + content + .toLowerCase() + .startsWith(symbol.toLowerCase()) : + content.startsWith(symbol) + ) && + endsWidth(symbol, content, ignoreCase); + + // + return result; +} + +/** + * determines a content is an string surrounded value or not ... + * + * @param {string} content a content which going to check ... + * @returns + */ +function isSurroundedString(content = '') { + // + // Validate Args ... + if (!isValidArg(content)) { + return false; + } + + // + let result = false; + result = ( + content.startsWith('\'') && + ( + endsWidth('\'', content) || + endsWidth('\',', content) || + endsWidth('\';', content) || + endsWidth('\'\n', content) + ) || + content.startsWith('\"') && + ( + endsWidth('\"', content) || + endsWidth('\",', content) || + endsWidth('\";', content) || + endsWidth('\"\n', content) + ) || + content.startsWith('`') && + ( + endsWidth('\`', content) || + endsWidth('\`,', content) || + endsWidth('\`;', content) || + endsWidth('\`\n', content) + ) + ); + return result; +} + +/** + * check a content is an array content or not ... + * + * @param {string} content + * @returns + */ +function isSurroundedArray(content = '') { + // + // Validate Args ... + if (!isValidArg(content)) { + return false; + } + + // + let result = false; + result = content.startsWith('[') && + ( + endsWidth(']', content) || + endsWidth('],', content) || + endsWidth('];', content) || + endsWidth(']\n', content) + ); + return result; +} + +/** + * check a content is an object content or not ... + * + * @param {string} content + * @returns + */ +function isSurroundedObject(content = '') { + // + // Validate Args ... + if (!isValidArg(content)) { + return false; + } + + // + let result = false; + result = content.startsWith('{') && + ( + endsWidth('}', content) || + endsWidth('},', content) || + endsWidth('};', content) || + endsWidth('}\n', content) + ); + return result; +} + +/** + * check an index model is contains inside anothers or not ... + * + * @param {{ start: number, end: number}} source the source index model to check ... + * @param {...{ start: number, end: number}} dest the collection of index models which going to check ... + * @returns + */ +function isIndexInside(source, ...dest) { + // + let result = false; + + // + // Validate Args ... + if (!source || !dest) { + return result; + } + + // + // Check idx is standard ... + if ( + !source || + !source.end || + !source.start || + source.start > source.end + ) { + return false; + } + + // + // Check types of destinations ... + for (let index of dest) { + // + // Check idx is standard ... + if ( + !index || + !index.end || + !index.start || + index.start > index.end + ) { + return false; + } + } + + // + if (dest.includes(source)) { + dest = dest.filter(d => d !== source); + } + + // + const insideContentIndex = dest.find(dIndex => { + // + const result = source.start >= dIndex.start && + source.start <= dIndex.end && + source.end >= dIndex.start && + source.end <= dIndex.end; + return result; + }); + + // + result = insideContentIndex; + return result; +} + +/** + * check a number exists in + * @param {number} idx the number which going to check ... + * @param {{ start: number, end: number}} index the index model + * @returns + */ +function isInsideIndex(idx = -1, index) { + // + let result = false; + + // + // Validate Args ... + if ( + !index || + !index.hasOwnProperty('end') || + !index.hasOwnProperty('start') + ) { + return result; + } + + // + result = idx > index.start && idx < index.end; + return result; +} + +/** + * determines an object is key/value and type ... + * + * @param {any} content the object which we are going to check ... + * @returns + */ +function isKeyValueType(content) { + // + const result = content && + content.hasOwnProperty('key') && + content.hasOwnProperty('type') && + content.hasOwnProperty('value'); + + // + return result; +} + + + +/** + * find all indexes of token(s) in content ... + * + * @param {string|string[]} tokens the tokens which require to search ... + * @param {string} content the content which using to search ... + * @returns {number[]} all occured indexes ... + */ +function findAllIndexes( + tokens, + content +) { + // + // Validate Args ... + if ( + !isValidArg(tokens) || + !isValidArg(content) + ) { + return []; + } + + // + // normalize tokens ... + const normalTokens = toNormalArray(tokens); + if (!hasChildArray(normalTokens)) { + return []; + } + + // + // Parse contents ... + let match; + const result = []; + const regExp = new RegExp( + normalTokens.join('|'), + 'g' + ); + while ((match = regExp.exec(content)) !== null) { + result.push(match.index); + } + if (!hasChildArray(result)) { + return []; + } + + // + return result; +} + +/** + * find nearest symbol in a content from specified index ... + * + * @param {string|string[]} candidates specifies which symbols to find ... + * @param {string} content te content for seasrch ... + * @param {number} startFromIndex the index of start position ... + * @returns + */ +function findNearest( + candidates, + content = '', + startFromIndex = 0 +) { + // + // Validate Args ... + if ( + !isValidArg(content) || + !isValidArg(candidates) || + !isValidArg(content.trim()) + ) { + return ''; + } + + // + // Normalize Content ... + content = content.trim(); + + // + // Normalize Starts From ... + startFromIndex = startFromIndex < 0 || startFromIndex > content.length - 1 ? 0 : startFromIndex; + + // + // Normalize Symbols ... + const normalCandidates = toNormalArray(candidates); + if (!hasChildArray(normalCandidates)) { + return ''; + } + + // + let nearestIndex = findNearestIndex( + normalCandidates, + content, + startFromIndex + ); + if (nearestIndex < 0) { + return ''; + } + + // + let result = content.substring( + nearestIndex, + nearestIndex + Math.max(...normalCandidates.map(nc => nc.length)) + ).trim(); + return result; +} + +/** + * search candidates in content and find nearest one and return it ... + * + * @param {string|string[]} candidates which candidates required to check ... + * @param {string} content the content which required to search candidates ... + * @param {number} startFromIndex the proposed index to start searching content from on ... + * @returns + */ +function findNearestIndex( + candidates = [''], + content = '', + startFromIndex = 0, + ignoreClosedItems = false +) { + // + // Validate Args ... + if ( + !isValidArg(content) || + !isValidArg(candidates) + ) { + return -1; + } + + // + // Mormalize startFromIndex value ... + startFromIndex = startFromIndex < 0 ? + 0 : + startFromIndex > content.length - 1 ? + content.length - 1 : + startFromIndex; + + // + // Normalize candidates ... + let normalCandidates = toNormalArray(candidates); + + // + if (!!ignoreClosedItems) { + normalCandidates = normalCandidates + .map(c => content.indexOf( + c, + startFromIndex + ) + ).map(c => +c) + .filter(c => +c > -1); + } else { + normalCandidates = findAllIndexesOutOfCloseds(normalCandidates, content) + .filter(c => c >= startFromIndex); + } + if (!hasChildArray(normalCandidates)) { + return -1; + } + + // + let result = -1; + result = Math.min(...normalCandidates); + + // + return result; +} + +/** + * find close index of specific sign in destination content ... + * + * @param {string} openSymbol open of area sign ... + * @param {string} closeSymbol close of area sign ... + * @param {string} content the destination content for parsing ... + * @param {number} startsFrom an start index of content for start parsing ... + * @returns + */ +function findCloseIndex( + openSymbol = '', + closeSymbol = '', + content = '', + startsFrom = -1 +) { + // + // Validate Args ... + if ( + startsFrom < 0 || + !isValidArg(content) || + !isValidArg(openSymbol) || + !isValidArg(closeSymbol) || + openSymbol === closeSymbol || + !content.includes(openSymbol) || + !content.includes(closeSymbol) || + startsFrom > content.length - 1 + ) { + return -1; + } + + // + let result = -1; + + // + let index = startsFrom; + const openSignStack = []; + while (index < content.length) { + // + const openCandidate = content.substring(index, index + openSymbol.length); + const closeCandidate = content.substring(index, index + closeSymbol.length); + + // + if (openCandidate === openSymbol) { + openSignStack.push(index); + } else if (closeCandidate === closeSymbol) { + // + if (openSignStack.length > 0) { + openSignStack.pop(); + } + + // + if (openSignStack.length === 0) { + result = index; + break; + } + } + + // + index++; + } + + // + return result; +} + +/** + * find closed contents of specific sign in destination content ... + * + * @param {string} openSymbol open of area sign ... + * @param {string} closeSymbol close of area sign ... + * @param {string} content the destination content for parsing ... + * @param {number} startsFrom an start index of content for start parsing ... + * @returns + */ +function findClosedContent( + openSymbol = '', + closeSymbol = '', + content = '', + startsFrom = 0, +) { + // + let result = [{ + start: -1, + end: -1, + content: '' + }]; + result.pop(); + + // + // Validate Args ... + if ( + !isValidArg(content) || + !isValidArg(openSymbol) || + !isValidArg(closeSymbol) || + !content.includes(openSymbol) || + !content.includes(closeSymbol) || + openSymbol.length >= content.length || + closeSymbol.length >= content.length + ) { + return result; + } + + // + // Normalize Start From ... + startsFrom = startsFrom < 0 || startsFrom >= content.length ? 0 : startsFrom; + + // + let canContinue = true; + while (!!canContinue) { + // + let openSymbolIndex = content.indexOf(openSymbol, startsFrom); + if (openSymbolIndex < 0) { + // + canContinue = false; + continue; + } + + // + let closeSymbolIndex = findCloseIndex( + openSymbol, + closeSymbol, + content, + openSymbolIndex + ); + if (closeSymbolIndex < 0) { + // + canContinue = false; + continue; + } + if (content.charAt(closeSymbolIndex) !== closeSymbol) { + closeSymbolIndex++; + } + + // + // Prevent ${} string interpolations ... + if ( + openSymbol === '{' && + openSymbolIndex - 1 >= 0 + ) { + // + const prevChar = content.charAt(openSymbolIndex - 1); + if (prevChar === '$') { + continue; + } + } + + // + const item = content + .substring(openSymbolIndex, closeSymbolIndex + 1) + .trim(); + startsFrom = closeSymbolIndex + 1; + result.push({ + start: openSymbolIndex, + end: closeSymbolIndex, + content: item + }); + } + + // + if (!hasChildArray(result)) { + return result; + } + + // + return result; +} + +/** + * extract a collection of closed contents exists in a content ... + * + * @param symbols a collection of open and close contents ... + * @param {string} content a content for searching inside it ... + * @returns a collection of closed content ... + */ +function findClosedContents( + symbols = [ + { + openSymbol: '', + closeSymbol: '' + } + ], + content = '' +) { + // + let result = [{ + start: -1, + end: -1, + content: '' + }]; + result.pop(); + + // + if ( + !isValidArg(content) || + !hasChildArray(symbols) + ) { + return []; + } + + // + symbols.forEach(symbol => { + // + const closedContent = findClosedContent( + symbol.openSymbol, + symbol.closeSymbol, + content + ); + + // + if (hasChildArray(closedContent)) { + result.push( + ...closedContent + ); + } + }); + + // + return result; +} + +/** + * find all string content closed items ... + * + * @param {string} content a content which going to search ... + * @returns a collection of index descriptors ... + */ +function findClosedStrings(content = '') { + // + // Validate Args ... + if (!isValidArg(content)) { + return []; + } + + // + // there are 3 types of strings ... + // ' " and ` + + // + const token1 = '\''; + const token1Stack = [0]; + token1Stack.pop(); + + // + const token2 = '"'; + const token2Stack = [0]; + token2Stack.pop(); + + // + const token3 = '`'; + const token3Stack = [0]; + token3Stack.pop(); + + // + const result = [ + { + start: -1, + end: -1, + content: '' + } + ]; + result.pop(); + + // + for (let i = 0; i < content.length; i++) { + // + const currentChart = content.charAt(i); + + // + //#region Token 1 ... + if (currentChart === token1) { + // + if (!hasChildArray(token1Stack)) { + token1Stack.push(i); + } else { + // + const start = token1Stack.pop(); + const end = i + 1; + const pContent = content.substring(start, end); + result.push({ + start, + end, + content: pContent + }); + } + } + //#endregion + + // + //#region Token 2 ... + if (currentChart === token2) { + // + if (!hasChildArray(token2Stack)) { + token2Stack.push(i); + } else { + // + const start = token2Stack.pop(); + const end = i + 1; + const pContent = content.substring(start, end); + result.push({ + start, + end, + content: pContent + }); + } + } + //#endregion + + // + //#region Token 3 ... + if (currentChart === token3) { + // + if (!hasChildArray(token3Stack)) { + token3Stack.push(i); + } else { + // + const start = token3Stack.pop(); + const end = i + 1; + const pContent = content.substring(start, end); + result.push({ + start, + end, + content: pContent + }); + } + } + //#endregion + } + + // + return result; +} + +/** + * find container indexes from within indexes ... + * + * @param {...{start: number, end: number}} index the collection of indexes to find beiggers inside ... + * @returns + */ +function findContainerIndexes(...index) { + // + let result = [ + { + start: -1, + end: -1, + content: '' + } + ]; + result.pop(); + + // + let concatedIndexes = []; + for (let idx of index) { + // + // Index Childs ... + for (let iix of idx) { + // + // Check idx is standard ... + if ( + !iix || + !iix.end || + !iix.start || + iix.start > iix.end + ) { + continue; + } + + // + // Check index inside another index ... + concatedIndexes.push(iix); + } + } + + // + if (!hasChildArray(concatedIndexes)) { + return result; + } + + // + for (let ccIdx of concatedIndexes) { + // + const isInside = isIndexInside(ccIdx, ...concatedIndexes); + if (isInside) { + continue; + } + + // + if (hasChildArray(result)) { + // + const isInsideResult = isIndexInside(ccIdx, ...result); + if (isInsideResult) { + continue; + } + } + + // + result.push(ccIdx); + } + + // + return result; +} + +/** + * find all tokens indexes inside a content which they are not inside closed items ... + * + * @param {string|string[]} tokens the tokens which require to search ... + * @param {string} content the content which using to search ... + * @returns + */ +function findAllIndexesOutOfCloseds1( + tokens, + content, +) { + // + // Validate Args ... + if (!isValidArg(content)) { + return []; + } + + // + // Extract token Indexes ... + const tokensIndexes = findAllIndexes(tokens, content); + if (!hasChildArray(tokensIndexes)) { + return []; + } + + // + // Extract Closed Objects Indexes ... + const closedArrays = findClosedContent('[', ']', content); + const closedObjects = findClosedContent('{', '}', content); + const closedStrings = findClosedStrings(content); + if ( + !hasChildArray(closedObjects) && + !hasChildArray(closedArrays) && + !hasChildArray(closedStrings) + ) { + return tokensIndexes; + } + + // + // find bigger sloded ... + let containerClosedItems = findContainerIndexes( + closedArrays, + closedObjects, + closedStrings + ).filter(i => !isSurroundedString(i.content)); + + // + let result = [-1]; + result.pop(); + + // + for (let tIdx of tokensIndexes) { + // + let canAdd = true; + for (let ccIndex of containerClosedItems) { + // + canAdd = isInsideIndex(tIdx, ccIndex); + if (canAdd) { + break; + } + } + + // + if (!canAdd) { + result.push(tIdx); + } + } + + // + return result; +} + +/** + * find all tokens indexes inside a content which they are not inside closed items ... + * + * @param {string|string[]} tokens the tokens which require to search ... + * @param {string} content the content which using to search ... + * @returns + */ +function findAllIndexesOutOfCloseds( + tokens, + content, +) { + // + // Define Result ... + let result = [-1]; + result.pop(); + + // + // Validate Args ... + if (!isValidArg(content)) { + return []; + } + + // + // Normalize Tokens ... + const normalizeTokens = toNormalArray(tokens); + if (!hasChildArray(normalizeTokens)) { + return result; + } + + // + // Extract Closed Objects Indexes ... + let openSymbols = [ + '{', + '[', + '\'', + '"', + '`' + ]; + let closeSymbols = [ + '}', + ']', + '\'', + '"', + '`' + ]; + let openStack = []; + let lastOpenSymbol = ''; + let lastClosedIndex = -1; + for (let i = 0; i < content.length; i++) { + // + const prevChar = content.charAt(i - 1) || ''; + const char = content.charAt(i); + const nextChar = content.charAt(i + 1) || ''; + + // + const isToken = normalizeTokens.includes(char); + const isOpenSymbol = openSymbols.includes(char); + const isCloseSymbol = closeSymbols.includes(char); + + // + if (isOpenSymbol && lastOpenSymbol !== char) { + openStack.push(i); + lastOpenSymbol = char === '\'' || char === '"' || char === '`' ? char : lastOpenSymbol; + } else if (isCloseSymbol) { + // + lastOpenSymbol = char === '\'' || char === '"' || char === '`' ? '' : lastOpenSymbol; + let lastPop = openStack.pop(); + if (openStack.length === 0) { + lastClosedIndex = lastPop; + } + } else if (isToken) { + if ( + i > lastClosedIndex && + openStack.length === 0 + ) { + result.push(i); + } + } + } + + // + return result; +} +//#endregion + +// +//#region Validator Actions ... +/** + * check specified value is Valid URL Address or not ... + * + * @param {string} value specified string which required to check + * @returns {boolean} + */ +function isValidURL(value = "") { + // + if (!isValidArg(value)) { + return false; + } + + const pattern = new RegExp( + '^([a-zA-Z]+:\\/\\/)?' + // protocol + '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // domain name + '((\\d{1,3}\\.){3}\\d{1,3}))' + // OR IP (v4) address + '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // port and path + '(\\?[;&a-z\\d%_.~+=-]*)?' + // query string + '(\\#[-a-z\\d_]*)?$', // fragment locator + 'i' + ); + + // + const result = pattern.test(value); + return result; +} + +/** + * check specified value is Valid URL Address or not ... + * + * @param {string} value specified string which required to check + */ +function isValidEmail(value = "") { + // + if (!isValidArg(value)) { + return false; + } + + // + const pattern = /[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}/gim; + + // + const result = pattern.test(value); + return result; +} +//#endregion + +// +//#region Normallizers ... +/** + * normallize an string ... + * + * @param {string} value specified value ... + * @returns {string} + */ +function toNormalString(value = "") { + // + if (!XTypeTools.isString(value)) { + value = ""; + } + + // + const result = value + .trim() + .toLowerCase(); + + // + return result; +} +//#endregion + +// +//#region Beautifiers ... +/** + * converts an object to string based on json and beautify result ... + * + * @param {any} object + * @returns {string} + */ +function beautifyJSON(object = undefined) { + // + // TODO: Complete this ... + let result = ""; + + // + // validate object ... + if (object === undefined) { + return result; + } + + // + // Convert result ... + result = JSON.stringify( + object, + null, + 4 + ); + + // + return result; +} +//#endregion + +// +//#region Module Exports ... +module.exports = { + // + endsWidth, + surroundBy, + isValidArg, + isValidArgs, + toNormalArray, + hasChildArray, + toStringExpression, + + // + sliceContent, + clearContent, + clearSurround, + clearArraySurround, + clearObjectSurround, + + // + isSurrounded, + isIndexInside, + isInsideIndex, + isKeyValueType, + isSurroundedArray, + isSurroundedString, + isSurroundedObject, + + // + findNearest, + findAllIndexes, + findCloseIndex, + findNearestIndex, + findClosedContent, + findClosedStrings, + findClosedContents, + findAllIndexesOutOfCloseds, + + // + // Validator Actions ... + isValidURL, + isValidEmail, + + // + // Normallizers ... + toNormalString, + + // + beautifyJSON, +} +//#endregion \ No newline at end of file diff --git a/MQLTestWorkspace/X121/14030217/Documents/Temp/multi.asset.configs.yml b/MQLTestWorkspace/X121/14030217/Documents/Temp/multi.asset.configs.yml new file mode 100644 index 0000000..79e0ba7 --- /dev/null +++ b/MQLTestWorkspace/X121/14030217/Documents/Temp/multi.asset.configs.yml @@ -0,0 +1 @@ +EURUSDb,GBPUSDb,USDJPYb,USDCHFb,XAUUSDb|M5,M15|0.01|X786|true \ No newline at end of file diff --git a/MQLTestWorkspace/X121/14030217/Experts/x-saherelm.xea.ex5 b/MQLTestWorkspace/X121/14030217/Experts/x-saherelm.xea.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..522991e8616a97db3baf354e508fa54a72449a00 GIT binary patch literal 545088 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

C`ODGNva+Jh2V0Tf11~PfW z%Ruytfi-Fj2-kZVJX%5E!JdHUVD)AxjP017VO!dqQXYD#DXKrs#>>`XG>rTp3)Eo% zvfS#_ ze7XREw+QMkIiatC4i(8#hWdV?k@LYffOlGh{f40(A%!?SXJ4U0pa~Wq`B&8n{=xhj zubhjB|GZ=L#q+4-qiY7|D;mK#dvS>Y%Q;o#ocEUA*YHk-J@|Q!Ua{+l$t!0g=A2tpg+Ay%qcTOD_T1zfOoKuXZKSR+1e%*u zX|Jhb$7Ii~-7b=)mWwfi7y`2(p?@9cqr}8rHW{I_V=}{km-uk<_M)#~iZ;(5k#zR2 zyVT0cIzl_>n3J$5N})?i!@RfZ+3Y`XV2k27W8MGkrczYg#laYqT;;AY6FHEP*&h85 zHy{0Nd(s9Uz8+{H`*H5e*&`q$X@Q0Y9tc-A2~S3VEY775Q{|1mf+TeZD5+l7s%>jC ze6G86=OO{)ABeuZny951_U$hW34c~q^#8h#o=e2mmqsb-)JuffF=WqYZHST{6cBVe@{#-MH5>rk(gXaSTdB62#k zuKhHK`2JjBJ0!It?+ZVxVtEMcHR`Otcl|o;Q6$(I3QV~U0di|Xa&pnxW6tURIr^_| zPqg91$w^nX=UCIjq$aeEBC|wNN1~X~yqO;Bs%f7lW>t6p=uc9q+Y!CfxeI+o%-?Qs zy!~K!_;3LdSqKZFjE{J0Pw5#Q$52MR{#~UB8=t zZHd>VV1d0tCb1JsuM-A~wqwT4zeegZ^G4%howNE>jwzzwKz*B(UqAEy`1XjNhYUkJ z&!wo#;_QO`C64Ir<~^J$zBVRY(E|4yIrWiZs4|6lodi0NJA4&;#|Y^N1xN|o%?Er; zzh((PuZ-#bVUvJ_m#=qq;9!zaw#N`2GVFj8FD}4&Yn5TFmI>w%twHZW*y)g=fkb9E zJwg?hLj?1?`GA-=yQiH}8m$*@LE#lBeIXjU7DQ`mF>+%BV$NqtrG11j3+0Q?A(E@} zFgx#2Lc1?|w%XZ{{iH3{si4Uov>G$F5D?C$8W5$xn@I&8O8ah;iPWLpXDaUEG?#%H zf&Ir6fMMZg@Ul5Jt7bg4i9YGLZbJhN0KmTk@E10)h|9tYc#=H|@rU&q_j5^(z_we#5E-j7(WR%{ZCmIQ=K?Hz6jjwybKC5?&B1BNiv7bXN!5%Ls=-T zV^UbuE1fWMv9TZr%6y7U6uClH(+h|zz{`@z52x6_EG<4$6Lze;RU|@-*R6T}P_A%> zf+`u);#IH<9MpfNf3#JD8qt}s0tTH(ioL6@6I%DR{V-9hj?sF9I9k047-O0|$Gv`o zMoKdl|MlW0CA#LC$Hf&b%O*e{dD_gC?PbrN^AB8sTJWZX)zoF88(PAGvrtQV^Pq~Q zI&mLp?$ml7qQ_V7d62}MN85QSZC)x-SOd=1`1-8jUtITDM~0x9XOarJOyyrM?k0aB z>A0K6Q6*vrFh7Bw9vhQCtix{t?@vvFHbcG(T8ffl&uwF1Ah?pzUvKz=2ok&DbSN~= z)(gSY3+Vh`4K(ABN5-5Rk0<7g;1Jh`zI6SF7$<*2F{4TpwP|&%Ez`{mLm^UV)M@57 zH|dkM4P`8ZBsKiuN5%c7-B*46Oqth~UT?4nUG;?ew`Vo0E-n@RSeU{?_W(j9k+f-9 z78_v16v5Wc-@Oe1lUTFnr)U$XjtqXwk{_ZUu#=}uY3zsJjW&!*1q8XVf+}_I7t-XT z)fA|o{{qbp&(IbdAg?n{GH`e{9HJ4HB0};~8S!1~gL%f-!EBZcbDk8K=a3j$ zX66`Y^`!eC?rkSD5q0S3T@_5Y&UV*bBAk*w7ZrJhR(Rs1RezkCR<+E!QAuC^e94J5 z`yXTYM>xKxr}Vr{vWUQsE8GZ&IU0~prMQ0e^ZjT1teM2fDn1(R4;62Bd3C&y0Akue zpXiJknnrWm7zN*{4?!O1bo7D!M$8!tf4j6N{<4z*8|jh#Y5RsXPXeRQeBKB7S{c0C zq7lqzalFszV!f>m#uEz=PDUM*#EB{H`tK5*-826I%Sbe#607{uzQl{=Wj*>R3))Op zzx@$`^o3L7*#UhU`v6Q%s@PxjW`jy8EZ&!{d<8S&V~T>l@vj4?AfItHKf9q7`&sK0 z4whN#ZR1f5&P#`CF7{^qlmV0^kW;?Q&B%QTDOSEEBTAR{(X=2z=`uSWd<56^B8tHO z-GdC@O$1sT!d$cb78&YK3BsAr*n~!pM_TW@55H97{Z`fbw#NcA7IRAKm{sUXQsTvi2L-YSRfzc|sctFRYR@k3&1A0`i zI*ei&%+nzQ7H}~Lb}OR6lZU$U!qkaNS~AStdZH~3eoyNV;d_vn)-G~+(pU3-f;v^G zh=)lI!XX>yI?>oy!;2#X4+wr4v}t0?AkvD{HHf8M_l+RQ{zJ^~iE*a-mgz3p)j-eN&h>joue80HSAIUz;vYlFMkCs_AcG)+?To9x;T=H$@0V8P`U1r zE{Bctnrs(V6;o6In#Fi|@W)gntT0fyjSV2mL^H?L6Xl&s4w0Q^b(i3($zhEPOhWkx0HSUGq^lkAi<-ASaKU<67*c_&}6Fu1-_BsCNkb3~N zTGT9V)ewEvc)duH362U5EHAD?d0fiaS|xPt9-CKakieao(wo8%p*fwz+c-dOwkD>u z#vg!Gyta*NTscByDF9jM_y9BAX2-#YWVXf6=Fsd`al?jeqF!-vG#MZhy(|7(2E6s@hz7TIr%GbTXFpHR7-0SG-bG zihlhff?GjOEwjEoS82BS4e($KfJH<7C$(0TqqFaYuBh+_l{qlKLr*^4n{-US>Ws$b z8U5t>8aJaj0}*b^sRr9&ck)+s_RC{x@pj62Pzkb^-dw;+KQ)#4NiE)MtFS(^-V~tF zS)Bwxz780L1&pZd84-4T4}6HCnIR*mODv-B|LX$$jnP3H#gZ`pb>37!<0Y2YqpI`% zfk%U`3)6KlY!(VI4USr(d|1%WMUA3OeWuP0PBV&3>sAM+ZQwSg=4G}^oTy=QbkNYm ziC0!(Oc0@}kH@n2gi5 z9X;gj<6b4J0~~X%dpJ~xdbl^cn~=b1z0?w=gZE~&I#-+4n)oztcfnOb;|f`y$7x|h z%~}m36H#C48o4n1G)3BB*(jcsAsp~)+|?NEu+aPWG2dRQcb@CsjmDNnGgSpH1oR`m zmoY9F1OdrWiMVq}U#F5WGfUO$0ks2Z9F~Xr+|q5oGRUqiB2;fj9i@rC_(Syncp&m` zTtQ&~xDqrPy>80C;P0I`4$SUTL^btwd4kQbR5Jq&?Kq5$YlTi3H&{OUL4}HtCTQ#nPyW$@^?EJ4OY4s%i#;R7CPlb(uZw)TUYLyRt6T-2{r)qz zq5S%Tm|~wXUYHZx&$_9G%|I7F>=h>-PU8&Kou=b70v-{!v}Mg}t>#J(ChlajUG%{G z%ZcTnQ)eSU7##~R9I4<)Y~3$$mRXndXHJ6QAm8W1w95t1!@zqY;B<#25U0&uar}^R z%9gRwX%sc&I|XARs&b0o*}3_k2vD#}SKtLJ2Yg0=X(YW+&>X9Y1T6rDaTvI{lJO(R zi}S}04os)Q{6u#*Vu@YK(e~u0(w%6J>pSmwcyWtTrm(jhHOZ?ddZZa{{_}u>eU8TC zj8qZj@WI9^g0TQx#^)&~J@#cw@}Z0s-sn7@FDo|wY`&OP6&HbvK*J81 zA=LRn7g+jB@3q3b<$i{_Q_D=CTzj3b(xIlhy`ja5h`RxN-{-T;|6tm7nqym3jc2s{ zLQ#$r`0%l%AVE{HewLi25S(>PP!I|#$7CgNyoP;*r#pg>VBD?c4ZCxwwkjv0_kM{+ zRDb?>h(y^5Dj%Q;{onHRwdH&+h{L4q{7oSzW8#{KT1Bmoy|1gLWh!t0E2h8K#dQE;bF zdsRuZk$7RPG6FO|JU+(m(pNx3T2pxxgqnD$T)}e6JXdPMuak0YS*Z%ylUV*P-wH)5 zvk@kifDaB~tr8>^F(FAYePGZfP%C6CE`&Pu7FEg|BIWZBHtvzI;Ee-63^XTDPTRGN zkSm{^mXO9ZVq>{j20N=3V<0pu{bcJ)U@gnx(*6?WNCtdzn>I7)z55&J5(So!#7L;% z2xZ=Zo;a=LUT~_oJCJH6CE#O+HQEKub+neC zou1QQ^`Y32^}2+BJ~vXE-0-2gKbkdvZ@Gj*hPngg5Ke#wR2P?z_Zh?0))dvHOv1)= zG@S4|e$8gO@f*-pgy9!Opp;QSm*)>*z5Lz&=-ij0Jj3` zyyoXTHz(Nt19^|{vpU z!S=5!2NhD4q9$Ujah5Zi^UGwiwd1QryAm9~_*uEKBjCL^xukDz{J3L@*!>!Px=E(( zLWJw_j#^T%9Vie4G074ER>6f5zaaSyTo9@i;_9w5cMy|2U2riM^pKu@eXZi& zB{S8!6igJPSg0P$x@PF%7>}5Wnv+E{(q^{N;wa`x+N*TB1L9Tq!@%QT0^ou8w*G6Z zJr1d@d|6WW2~-7&9Crc;3n?dHU%Ay1)GvFaV+lFqn4P9iB2yY7AyNA92@UbyTBLiU zMPjs#J7ok`C|SjE+(3ED%P+3u#Rj@m?CuJsiQO&>#5oQ>-IOZ+vH_Cj8f?`lC2-*n zj%MOXfHbvHtHgM-(>f8|qhF&xtVvSocQO0U7owf?$5Hk?s+=y&XOJY%5ZOrMzey0 zIebaTiLJFam01Qm>$;YW(ndJCxLL_qEE}BBv=qo^`0NS%v7M3kSM0=5u*C~Dgf>Lx zGuwP!-;Q^YXxXQKtm)Y%&)&2~S=PJB7qjk8s0Nf>k`F+bgj+yF8nOEcR>9Xt)~MEPDgVj`@r=4YaiVo9vmRkQ56_ zpLh9ghCOA&3Q5o{n`EP4H1loA>F$+zxuLHd716o(^kF}LMyl52!D;$9>`yh{DRsw+ zu=5nWFh5TZrbN69j$oJDyUb#JDF=Y(_|84fqzsS^bn|(xpT!-V@9cfwW6K0I=O-A) zZKFAWj@9expVQs~gSCjp)%3q7n)gL=ubL7P)QL~TrE_eWM<9V>^lTVZmOtE??P#xA zA#qvobWNVMg5>z#KiY{v&*v6}7}kt5>KT;yVK07Ep2B!l*lIj+>rOfj=vr9lA#!z#6h7H7zeHE9c7DDP@M(ZMmXPg3* zdYfsot_4*OiV0KuTpu6CIsgW@RfBcM#jO#DA@U|c^xA4xU*_A{89E_9Vx?z_hw7A` zxdj){zhms02Zzyq2gRSB%S#ZoD;Zrk0RU6$0F_ezui%kXP{(-2g*9xB4$@)C!G=h} zr6I#gSQCUsd0Sm)uB#vGGU?ZwgGAEgk+Pm{B?pdH{IJlKPTYhJe!kmOZ(q^j?|P_4 zY52^ATcU;vVL%-IFre9;6;qi67SEBFQe^TieB8RnLCt#C4^b(}j_@n+vAUfY_TyYy zxk<);U==mE*jybZ+sR=E4OK|D-L~=A7%5&#}HKT zpIqGOhf9Y#9A_-|SP|dO89O`G?gl4_2?F!RotCx|74I{$@-FvtGBJV)nz$IJ7dZ26 zvw}4Cjy`r#&1p}d3*)$xLs%!*_-#2kkb^Bb2xzVDO-9fmTvY321Ctt@i@{Q=rY;1w z%gd&_h+FuTx&j2&?#63BIbrlzV`#(>bw(^+TowHaQU~XJB3R_u1$cv`BlkG7GWfw@ zD)cxP=tta*{_@vN<|XKJL%2WeIlKS_h<2+H!*~)`^YxyHHc8M7WYipXn~N{NmnZMb z{Gw+X$?i6m*`k8 zyPk1$KQu^MkKZKPCl8psY(UPy7AbE{Wbo(ispU19)5>x5lNkFdzaLtT3Pby?Wo5?a>xyGL< zdy7d&ZVMHtbHXN?PSqa*Xnt0>^bn)tX#~TOYQrFn7_=YN{`QeQ(P!td{o0^>Y;rX; zsa}+{NPgfmH^pAssZrAaqlcUyMF@_V`W+Ao^6vRQ8C(WfO`-kr*zRkXg*vv%LATC z{_vGKR?E|wtOTFBrZNeMHNR8)b3`!%J1@X%QxLk?c6fPVUlxqWIv8QDbn+ac%O6Hq+tQbGc_rYoO#aT#^~G70{%p?Jz8z|8EIDvbmdFlP^298`!JSMDZUy_ zEm=u!szp-dOkfI8to}7nZ-GZw@&}5g1ijnaaorlz6bN%)NI;;0^k^0 z*@~qfPh^1oElo3t<`} z{3TEC4<%C?qswYO?om!qwEQ(I3o1PTPDKZp(finskZmc5+Syw3&Jf78>xiUK&_DaJ z>zU)IxYffy7LZK0Yi|c#o$)r}Pwa#Ncl~e|_&Imzc{*LdE+J(^fGf?ik*9QFi_uM1 z48@Ag1SjPJ<^*3n6OidQ<@wNR+e$Ra?cn3kK!M`M4^+E^>*6Hl zguA<@f#wuG1@=k$od-fe zEsK*~s4WSDji{6=M!;^XE$AB#3z#_}$*B8x_1vdiIbm+(2XOvq^XVcb@|V{k>ZaU0 zfolK|Z^$eE>-cG#ATZXg>_u13^8P9u>OxvXdRn#MXd^5OPv5($QEf>frcidcy$C>^ za_wi9Zpx=}LMCr>qX&0pzpu?CR_&ZY4LW@jaS1$)PrPYO{A{^iQFUFQW9DY2uZ_*G zo@x~pDamj`UKLvcg92+F^<$0$a&-sE*7^mciCaq_4h=aDllh_G9aJxr0R)JxM7Dr1 z-lt&#%2RCsvW>KEp*@VCozx$wmG7!{#Pd6?CVjwh(n)^SbJx}KHBT84!z$&*I1t|+ ze+&x%5PD_Ij#DNSl?E<{8!zBHTGR>MF50q31t56!uBrZC1+lu;c$frDYg%olX;KCT z=r?ON@&MY>al;Klk988UfQXZ1cML=I-)n&jVo9r2Byth<==|<@d4ZrOX2|}*jUni! z_V$S3W`=W*2N|61KRKA$>c-SBsYk80|IMF%Z8FScl2gzWCo?L~IqbK3{@JRtt!&Q13mm3i$M(k}A1Cj5^DZ zw>ww`g4dTZyDbcLmE4G759k37$(7TAkuRZHNIQzs99;QS@0IsbTtmA}r3|x{BXe?0(W!-bLw-fQE-1oodv_}l= z>o-u#VXdGl{Z&EY44kC$P1a^mTO^|@ehxn^slRAHi-{3ElX;)L7vfhi4$ZpHO{yex7f{`Z!A_~16$JHWbv2XUyzBP|eb=1lkDx8Vc zV8gJ&cyBl0qE(ABM+m73mDjty3?}wtsq1m$GHVy=k3Xsc8nV23e_(!Og9q?d*XlLR z*de`<8%Q};z>Zr0h#ATO4{JtfeW!+(GQk`&1O%F`M5uSOTHqMEka?m^#&8hMrZ8yH zF)u%;k3DGlbSBH}NoThCgGY)oY`mis{$%AdWTm`@Cw(5}dHPQJF>y+kT7ANU@# z_7^wYq&S$ls|>(VfLbj67)eW{yGrHmHYZg4EAg@|V^&k3;us{k5I@1*+dXEwkq}O4F;}dmpb{WUFx9zRE9RW=h*eE~SCPBb%@Q^)8@89_`ziMcRcq&=@}(u0b!6@C_iM+k8po$Z+ob1x#FHA(MHsitA=t{Y zMeDB1x7BTfPpr#%2<Q0ffE8$1POADM4M(Am`i&)u?~k)<_d>ZKfVwo z(EGD2Y(PU3X)wHNGUTxZjQn%LCMXBvZYkJX-lL#?1~hxvR_^?+&YT{}S&ZMgGm{d} zjK4WVjzM%qmE7dnjI&S4Rs33jhMWu*Mo*M6+;uGf7VrB6k(l)K^A3%+Nl9y^+AXY$ zP!UNzUUBeQ0?c&K%&F=-j)L4ZYBE(9H8>6`0I+N%$(KWroBH+w7p7@@RF_5X@`=2l zAX9hcuEY|?0ClS-gK`2FC5dMc$cv=`ZpK|IG$YcmrBNbftM3>>9rf`zwIdk0ARzwr zV7XWwBzG?R{P_E=x7S?B#0zQF_<n49L30xMkp^WOe9RRpLTN$n3l^E&vya&glwAbyQv z+l!folG?B(0PCC-uR1j+BL-DP5Zv6Mc_2dZL&5F*>J!PV8-=&qur=hCv5?{QIg;SS z;G1_V_16*Kx8EM^wJZCE$hgzKV-Q5TMu2B!7MA0Jnu&I75#=4@Z|pQ|y_(iYvEF)c zU8?pR#O};rTIm~{qK^$VA$a-#7s=lqIe-Ql(~a;$<7dXxp=pFhZ-q-7)%e-lbeLcc zS}23r12|N6R3A?2bh~R)Sn0xS^4R*K%IIsz=ArOlu6PJ?)02eEWU7a53-bOThOL>> zuS*h@n`s$^_C3U)0F{j7Kf>Vb96k(FszSfd)6tzUHN}T(U3TUUfxpG(m@hl>&2kaG zKZi3vE+! zQ=#I;b*i3dbhSfSuQ4#Ct&Wype@OX;5sEBrEjrs_>c;v#vwH=|#eghsD>MLtdj&jL zfurh^o=O~g(>2mO(7Vo?@mpV&TVQquC0l5)2JvJ9X{Nr1L#muZQQxzH z(y{Xejv*y@+uW}Xl^%UHCBo?>Is{ z3f-JIum0}U2m*xT8A74v{)*D(B-f=evG!Fji+^?~`SHFy(N5et4n{@5Wk{8gZj4f8HlJ)sQ1Q5GV z-wH|PFF1DQ8O`~vPN^f$6HR9nHM##y|MkE(P0J0?ZI4JRTQ^8YUUgcc(Fd8f7>0Jdp&QN z51=?&DKJ}?h}uYLOa&8S?lbij-y#HCy1qi>COXc?%$3LZ}n(pM>2GHkb8Vn@4T&7Z?Ax>Ye?`n$->#6wmN z+09HB*&7d1SGzvRFWo?Z-@`&hpB(RG^z&Z20})9E#>XM-E_31mTyDZUjqXZ99j>1= z;q@Cx%rJA@{b9+)SjEy@t}X|ii5}(X9BfB2AhY5SInIX~taaC`&pEv&hnu1aoPu}e zBGekSx`~0Lty`DN23teTlpROx{YFxFdV&Bxi-Ju^BsQ6l`A;*vXYzpkpe^RK^~oPC zZ>%Gd`gHb67GXitY$O(ZWfv!0FNa4AJOn>;i`dYOs$=KEoGTjPbTFmtNpw~#4B_Y5 zb7rN1v=H+usN8cnUtN`0(Ln|L;ViQFk*ZO8cM+@Fy+H(Z92COqXb+A2-6^YFPw5~* zjrED<& zdb-h;w_gG)?YI`VL%GSqvbDb;&Kcfl*PlMWk5P&~SNi;UQ4)B?PV!nb`B5+Y2s9<@ zn;n*c6QUR}#0fBY1|sf;Tv{o?W|V1vScRv2TbhXCysVp9x6kCu6Ng~R4|0>~x$rNR z^}ocDt#8crBgs+8C{5cbKM1?5ynZPS-;+<2b8h9m#!Po;UEI|mgvz9sY-Ai0DXY-> ztnyTCul8gHk2ER6ykOtX3d=9wH!M&28^t0!5-ofS4fNTPi}ibGbxl^E8e8$mcyvxE z;r;zC;jsFUyehpHuJsfE5p)hRu3_RSg$A+xl&vXN4ARE-u1^qhBKD}n{nd~Jl3dEH zneid1+3T`2%Zy2Dr}F{Fx>xPaplYjO?0(-mtd$|AU@kg{uZQ#k6)8UPKr1}Fo6B7o@}t#dss%|Ii|7cgykCuO3$RDM!wffcGPg;b}lmC zMcfTM1Pb}UD_xu2b{uWuZ%MpMK|4B!$S}-f8bupY3ok}mwmtjfOO)1Moh?!)+}O=6 zCV5bX3gzK&X%kDh4u5}3|EjnChHMQ+lmQM`K}N$ez0U&Il=gwUA$uC$Q&derST;Yx z6e3tSm&aTznmG)^JU|;{%nd|bLudgF7vru=;p=CR&mhwOb93KOAn^I*#UR!)qB2AZ%bDp*Byy?$QJfV%*p42On|&VJ=TnWI<*6BHhS zHpGzGBk#NjriacpjlAd^OAOSwXr9f1rPds9wGNk#ouNn`ZUTNlVVmAy%XiYnH=ykQv4?M+Vn+6^%sEstcwf}=9rGqUrr8gks zm&$PyqR!{75XFI!*!&?JJ~+sGQ1~}xAMqXg4WzXtDU}1o3@XcHE$;9zoXiME%&7?f zFgxcKYnF63n;*SgXhtZ=G~W?5bz@^)I2~C~yfFwJ+ZeMl-8!ZHsWryEX@T*4RXthv z>I^;dW+^ci4tPb8>V>20e$FFztJ4N-t)S;f!RDvC-F~?;5(w4`-S=QH-{e79)|={m zQECYHJlyi!>zsY|Fo%$}1vmq7a5gnT?PJ34ZQpJ-uD$Dg+gqjdQ0gTVI2}L?U>Q6p znxRCM^+Mw2w%PH~9R8=w$H~wlhzp3tF}LXhT*Ix9+&(30K<2k{hofJFqD|Z#bvYFLT#DmXK%R{*ebX==cVRGHYGy5d}}uJBAop0D-O%&B+)P;{a$n#w@!;Lb)VuQ`&TGlb9Ns5@Zs zXgB5Vt!?KE$pRcYyk9=wkeE3r8^~sBmRlVeGNFuAAX46N$6vSr$jO*^^0&t5uG>`e z?VYrQFktw62-xS9Nrp9s(6ztL=r{x%6;e7 zAY*tE;7sAU0AhfT#v+84N@_7ebW7IELyfB1C+UMrczD1s265ARLJKc_!L4 z)u;L}hWuP0`#8~Lz(5blxp|V@@cz)7>_CcwgI$a`b~2oZcqNs6NDR(ySmj^#WhlII zC!v|{23JQfbdc9m!mnaGlng#`5Vx;aq7vNoGY;S*%D+{NNi%v}Oe+etkefPdHu=@> zftV~Gpg%Kq#9GFVK9srd?8jnAOBBQUoH^LFw5Q)PJw-Scm#&^petVF}aJ1^ow5^w~ zz!84vL32>k4avOwOX|ui9)Kf|v*Mp03FQ0Wwrpp6yl{@vIG*jG@Hh4{0B-> z5fU2V*%?~`P)5rh%~t6|9w5Aw$fs>< zjtWm~r950?sb1CfcAN%Ue~sFkU4q$bQh7ABNgA+np*zP?r^dY9{Yuqd_N zIB$#=*x|GHeA7Fx*tZY}RwM0pUA?#c#mec)gdh5?4H^*VsWm8ut2#NeYnpmP{eWG9 z?$_g#*+_=jK~b?%P_-Ar&>BNrLvht(r2t>gW)X?tK$8Fl04#(_9j5;;aT~xeIFWKZ z)ld?R3=E>fYO>ElQ@jz*H0t6KlI1jdQIC`&kg= z7lJV7%U@tamY1l9C{}r6u{*5cGUqwH2%XofCO;O#6;*Zes90?Q(Tg3RlfEF?fOi_; zZmtm!pC#ax)T``Vh&!{ge0gu6CAI>XsItZ19oE~<3?5v({%^##cb5!E#vH9Am|6equ=6EstE#m)+ zaLlZu=~?^)VcxIcI6n>D-0OcTr?FEbSOIxs{A)MxBF5vO5@K0lr-31nrG=@gk+_6n zJdKk0iz(dONmAxyx#I?%9KkuDuV>DFk5+dbD^HVr?Bmle3@mOsM z-J@w?@(o>CKW*i#fZkl9zPw5SA2|L`@qO@U#^J%`Q~*IhzQ0fN6WWLwtrqiuwr>>x z2s8Ro758uLndG9Vmop3dBW}ahe?I!#vYEVd-c9{DZ*JuTGFX9zIX5ODX0Bj!@s6KozIiEL8YRB&Ps+3VopQI3Uu- zoHft-eiMm%_lXm&=S-{`$2V8(`kqp>$v$gBpb@Es^h1&O7RRNwDN10!DmK5x2u7IEp^f#ZV+NP%)Oxybuw7KIdphsb| zIT`7paLnkBC+DPY|6I{Q8Galr>jlUw%SDrx)k@g+{8bV%uS+F`RbqP(w%BbZa-#+_ zu_aItLPE?xZc@S_Asu*SM{XQg#?ve}r?be&FSaZ{!A*Hcs{7rI4cvou@!o62PsS^} z^>dNclZj)5>;mhwKlW}pA~APT66@yl38gjLcDs}|wV=Z2E_~nDq1t)Bc7{e2%yqfJ z+!g{=9D8!l^XD#!(~iv0w^y%vpvonj69Fk>|szmCvz zAqeA8r^IA9j4TZQ5RsjdSq;RxHvC^TMsoe#F522wFl>eBPBCXWqq1M%>cUU@enRx7 zIep1O)q{ae=v*ZtQxBVXUz!#W3;-UOg$3t^5f|Zk*>pxPXHPGR!LtVnllVc80NBlM zIzkFP8e0&;q1H#9q?BgIRL7_lc(&m~eQSeR(b(tIPqXuWc8?kIfvz3^e&vG{6ZvpI zB15tAWv$4#EuD@$;ur{EEs~}c=t8}mOt3$cMjW{P~dUbp?SS;QUyyXZKL+amky=i_U<`iV#&hSbS zNA=MC`+B@h#%Yffx#frj6!WjJ1&pB@i6wDCUH3koc#;GOK|{dN?F}Rixz>?)GW+#i zo9jMD^_Y|W1U7z!ha%;NXV4~{mH~mh2Ie?3q*@&DwOBW|TY;Ui#-v&u^DmlohB!AS z6yz@AoGNL~2Gvfvt}a};p{qw*m|_dMu=F`~I))F)gUZC7AWX}ZmCYV|kXritACX+> zG=;e~z4hb+A6*?w3AUR8LL1v_8VLO%JS*4)1q8+2+T~T40FWjN8hog2VTtBP3O!5h zOoPG}yScM}6a37ZZsE?rM6v+>iDL>3J+2!B0CXlIT%lCWh6n_N zhN53&?xiAWFHkYT7pkhQ5OwHwh#kZ@xMQqFZjXBVwDW_tS~aW<(ASZ?SWUa$Mwb9j z(-|uc_a6g;U(a~%FlJrQRo$`TTXe7V@%bJ2=g;dr=CjO2?|eGGv<;i0Pd_0wNKh6q z7M=b-RHv%~)rOC5x;A*5wG=-t|Hcz;!ctjM>V^~|h0b;9Mj1d-Ch}kgc1w_HZis1Y zUYhHqVHOwH9h$U=I`RtaSU4UF7*#8L#ww}dn~NPPRgo0QF( zA`D8#Kc#(Go_)I=+%@j#q}BeP?E<M?LVP+wHWQnVfY$$$gGfDi!d@9v{yPD zBsZ*oF>cjQGaq)XLM6U@^)sI2x;^w|>ENZFow>%#DTt`bJ!G|>p%n-6Sw=b6 z&J(&NE578aL;3enIkr&4?E^8lvx`a)qX%k-JrcOTn#aNfPsD(zN!#=()>siOMHcpa z3(l}bAVQ*o3iTjI1qjN`qKV?|dWGX4Yl6*D@1Z}8_rU4v$LlM<>rPAJD-wm`xz0|l zoP;RJPAQi`ALh?=Q>YC+Tr$pf3CBJM!js(YC`B3=Dg!o60d^Q;qAN`JC^v;h4gE91 zpYIYO;|>mOPq2C!pzIw^^Tshdd)E0`_YX(PnIN);?+m3^#|#D_oX z|M;;N(FPORV$}jspT_$6mk5DlVAk^o1->C4hvBJmD?VQV;}vffprCUCW#;jE3IeVR z2UT!&f?X{YGH=w3Z5Dtx=Qze2ev9xdgxta4Rf@#iWETZLr?AZ~*$h=2=G8%C&WKZk zg;WQElc#J@qJhk>Q?GfGF*RKFIDn zQ5HXe-s$-UCVsJhGIkaqke9}auGA#+`&{~DNt^-txR^D&yJJRy)^~V8h6&5)mRQ`U z#4QoE-N0ux0X_Rm_TM>C@HxIzo^Aa#U-g38UIViKj67|q1`2w{{K@X0NcyIfIzhA* zMn-f`SS6GiN->wwXX62(a$;xH2G5ETSD0%ud3bW(0#rqdrZTISgNopG^LF=|Vjl7B zcIF;(GAR(Jyn9kf9}4U+sm%nXFJ+7r&xQC+uiughsTEKVz&2}gamG9Z3X=qcH^r!e z?8PZY_v5bz?fRKW66X@jmI}cyXu8qY9PyBkXG(xJ95TK{(Ij=)1b6B1HLo^L3i1L z?`P88Mq!&G-nEApywxW5(Z`c8Iq*#=mOs?5SVSoEp@(D+Zj*XHP&_I5_&^P$+%pu> zhhEdDggQoj;mBI{l*FZnT8q%4#BsL}`Ut%tbY=_RzTx-ZaKL(lw=0#6@JkrA7>7P-@6-(9DPg4%mcoOd}mdtZ``bF zJ*Sbx1_rcIC+s2!=$)IOK3#885@qH~RC0yPQm|JBAi0&}4n+C0I*!aKjcGyke%x62 zS{+{`T`PeA8NdyU2!v zH*38T-c*yTzEOEK+xQ8UAAs9E>Ro6Qlla@vLa5+*MwWifl}Bt6QHRWVR)MQPvX9nb zI&S8c-`qn)AeZ+i?Hi+K&xsC)F)MoyF^Lx6yy8fZWxl@I>qoJsW=g4^1K7tVY!o&J zP;DYwr1|Ruy0iHFb=QY)`_@iXq#S!6GNf9+s+xPZ%iapNgKQHh>qJF1RB4qI0GIMT zXhcg&C5DIYWQqu$IZr|*F3en)?X)E+Oj%udCKy^@ccG3tP(SEMfg(odEiN~`eGqA> zgORiweYFTX1s_cGJ@Ci~HoTgt#v1YdKX}1;dc+a%;B|%;TTKh+Z{J2{Lktcf&K;O9 z2;~5ecA10sXuPY2u*yNyzRWOMjDqzwc2T#O;V_!x-=eN0vMR^Fi?vvaN&)KD-cdpe zMA}Z8U)C>(O@;Qz3`Y573tZgh|CN`@R{Z<%hv=d{ZWJArwb4fuY^iz3-MfFZNRk-6 z+usg>SydpOo0G1fL6{XaT_{CmxrOaRK>|XhSy_*$-&F7u6iUkIXJeT_8)t?nZLSp{ z%Va)vfDpb+UwZ>Y-3m^v2lyICgc>1Qrv@t;RKBqZ!6 z8(&09v3-1+e7lt1rkS*14vLa%V0p%ovR-E!TsZR}A{E_fs93;$-ixJCn_s71@`>gZ zV>Gr_=|te4|FfYQ%cK}NsKVC`?6L|R_m4h9NPv2T!RB^cH}pJ^plA>I5pFfaop7_o z!KBD~Yzj@bvCUd*g8iwq>zwhI@In{7axH2w6bFY}5gDi@}ypxy<1}{z6Jz;fD zWm~49$#R(Ahv`Ldrf`lCxR9KHIY#>Jx%ruq*n)H~;^ z3;6E$G#>tnt*57JOVUf##d;L1DnhSTQIorD6%>RP7;P%el`jst7ON`-%L|C9R7yQ5 zgePAuV}?{oH4u)KA}cBWV)2acwRJ8zE7=N>mYV%(5QJB;hg1k+cjAj*kpaqnWatJ1 zLXK%>H#Bu`#V@ORV1v@u74rfK(Gu=ts~U9O?TGE4!eY4CV?*tt#-R9Lz4@~eliyC+ z)RuL7w?pp)#r*ivwPv~re2JUlmc)+BHtE;11zEi)u>FgEJ# zO;tJ^aGo|n&XGxij-wqznO-otY~5$Sx&2?kDoptmnox-lUgX-+6tI-29mqjXe##cP zYyS@3J_&gslLWzJso+))@uM#k|A9+KhlaXjKlQ7-VrNu zOTY)R&}x4Hpc8-XAQOa>3`CH`UaJl$Uf7@jqS+drK8Z9CFUaap{!clMiuLsY#Ji~u zJ=XNSmUwTg)?F)Qk+ypG;b>HTUST85i9bp<45^1uh&-{)`+9*d`4Tg$S$83$Fn3QP z@iYYwmw2r^UtN9a}EdX{#e|XuD*7?dj+*tZ;!MlX`?0w`h zy4cy3-=8);ZCtCn;+U4JmP?VW#hUifzjkB%X(pbq30ziOEkmY@6W8x_U$jOi4^HR< z8yZSX`ejYIqtsR?WziP1wz+lYFZQYY3ZL~@?6Y!GgKLjwBP?X-2hHW*2gfFm*wEI4 zua&ZyK|2V*X2s{EJ38teeM7SOR1I?jn5LHkZ)fr0Yn`A3n7)W&0ekF)oXO(z&mhZS z5y%5&W|oR_hOQ)urv?G z+Puf|mNgC8Q3#959?^tfpe90QTrFH5FxKSDp3ut(4eekKNe2Zu3QcG5&JhphU zWx-_o_51%N>;xT(bD~`Emv`ph2{%3u$*855o&!9!BZPLEqecV^pOc)rqhpR>W^kSq z1Z88T_5dVd0-ZL_ubTp0G#%b=ixV1C{C$~X$Ig*uSQ{3A@5#s3(im4^2tCDP7fy0XB?<}KowWyu z#l(3K<`c(jh+5IPjf-i|IA4P|#i`s=vG>++Zv#iAoaje6EfLn$LYDu6zchJ|w>NKp zWKq>wmgjhE!RMg#0bw}*EYnWVlZL5Y_zqx+ycXZffgrp^!P2ZuNMmnj}EW3NS= zf?5=$@FIdx6uFkY@9DCG2J{CD{*p6?ZeQyGP$3IU@);B$9RF$?gJ0i+{u$Z8r_O^r zIlh=^(1dZXr7JPI0GP82T=IFLf!!5AW%Sb6`{*|td3G}hk&ob9 z^&S0sDxO-)r5Lwc<$AJ_Kf*fdIzkI~y&M4GR(8c8HCgvm4H${ikpvY2CErO0)#|Gw zPhGX>Xcc**6OGaL)J?lzY5tD`OHT&jC7)tgLofG~UB3mOLHR;VGc{N0?Z_YuhgJk- zCV6nP;(ivPY4gSu5?4>S-*mj9?36p^AQH?Ih2n09Xjm25P23qqtfyb`qB*GQLq2U0 zasOc&A@wg(-CxYvcauCeCx$6>mQ+{?I!FS4gbj!nW*m_`TKt>B62^(0KvD8ZxrQc+ z3p_X%eb4wEF^{3ZNEL~~?wV_-6gg9X>0k;M(ouwz6#)#&6Y*1nM>cI>}$;y z^;tryPjPHvA^^eI8;F@F$Yp20RovYcc~)_gk&?{DL`eNNY{lO9{bOuQzwU*MzptiDhYm5jv_ZG3r|!%>rzh zR(g?Q-8o0M#+k8jMAl~Dr4N1V!di%wx-2aC-R!md;wHa?=hT{}C_1iTk$&PQ5b%*! z)nQt>&8~2|;*e1b$k7bybD5r5yvc1Wh0FGDV%-%wnV0ka$RY@JH3fuNXyH@AH1kbE zz9@y=RXZ$im^2gvro&(5%elfaZ}LZvOn@Q_HX=6wu^}Cg_NWm{6yC>)i`LbQ;k=gm zW309Q;NOmP?;Z&pPZa!xBKu&i4o8d4T%gA)lMzec?I^q|`CBaBL^x|gNC7yA;5G~& zp2R6o!%c?udr1uxGyWBPRh;3zSg4}~wewpq>2n@+y&P_VXO4aNCPpl@HKqsDRF!y4 z9N~#uih`<*Q1-79+luOvO_Nxhmf*XN@kJX7mPyn-la#J@{-Bo&g_kHGgrerKK}uk= zJ#i1+zDdJ;-Z_d(APu1h3@Y-$kv2-e&JO8jpo|1e;{D0sk2E$t8>J$sHfe5RprB*Y-9{SD+t#Cu2w#tj=*hVk9JF zA;To=1~#zKJ?U03j-bEjTmw65gO*={Lr_AWkyjaMG7Y<77d^?e!x@d_bHhtz5^-hR zzgmr4z}ti0sTCA2_eIf+aNU8Oc}*-WM|LEi_4ygsIQK+s;H&$CuYw78UTm|o1e#k6 z-Vu8YQy+rA1ivkUkbsKjT*|zXs30H~!RHXvzz@|^W~}>HwN*HQji76HG`R`0$?VR6 zmmxh3>7o?me_=;RCVUy<#A@?<((3@1@`6c>?oYCINUnxbSI&N~Gf zyB~6NSiI^kK~^5 zeX_xzHKhpQRsg?_ML|BRt9F#QFp*9Gof^<`S`jS4g@^6*{`U1b*n9aD=yjd(X#gRE zilGbXE0BLuhu6@542y7m`U}!S3z?3$itEYfgS&e?VBd-{@6D)c#jFaB?yxfy;KvpD zv+@DIEsMg`$_8hwG`kP1z^_7122{KI*4N2iY+{iNbM+H>1|e zf1u*|0Z200+G&jNyeV<6>xBe{#YHAxWn@KNHNPTjc2Bw@`aXJW7)>pE4G_NQr&;d1 zqROvpBUR}^>Zz@?0cuTo2~t1j!Q2%V1qhRB#0gKIxJ%=v|L=<%2Hjn z(6fwI~-15PhM%_N9#m{Jdyy!2A- ziKDxjf@kNSYXltRR5dgRc|1{RZH5S{eHXg*k58cFc2y(VON(L{ueFs+7VL}c(nHZ7 z|E<}=iYrDJN9^Asb}U=aD|8D9@wPaq<*w)6&~EIFD@ z(oP-Oj35(_9j{ID8Y_gM$~R!0x#m(s#OTHYe=)aHmZJ z0bonrWoi$l8@br5i{2s4&P5g0j8cSWuF)0BnbR3t71b}jP*U-hc09g~m|i>r?^P1y zVe5Ri6&~A98{b%9xjoPx7|qv+P6skRgP_#YG?oSUO{Tw`C8?J=@x420QxB0WCTs{= zAdDHm&M0uhON@FFh_z`2cdYab@rLox3|47ctdb?*IiwfE-(kmVXBw&y#4Ku} z9$_U80&k30m3mnU#9Kh*Ce0Z!ympwI@wO1($$mb20yyg-H}!M3lAEvbLBn_U;~Q!} zO`Vn!WKNkFT)Xl+#P>7L5qF4L2>}vy9(91GtZ@tD<+RXgppJu}8uHazwt>$a2gb6G z??0&QNg#9BP(I_6xbvA3Bc}w{Uo9jV$Oo%8{bOgsTm1Y6_k2@P1Nwppez53}n%6dKyKhG=1GMpvW60?#tt_>IE)k>`~e+2lpIC z-|(|3gx4Din#U1@{>b?lL>HaJ7e#HNGY9V<9>9`4!luMdE5{=v3^TI=2@mdJ%+i>M*gP0vww`|E$J zKUdHBuZWAUJUei87kq+qxR*#1ajw1IV2p%o)&uu)oDWD++ocHDsg9SdV9T?8$Tj z546-LP5cBiDFp+D_{`vgEMi;~_P#MhwM-XsJI+y-lq}p;634Wg(8@UzOZKru$98BCMBSEd(lo*n>jf4ZcrVQ6Rfb~9E z(Jkh}^rVT|n@|g^-86)gmKng7`rNB&5Ak-%E3wJ!ANxh9w*(%q0)iHg$SF3~HD~c2 zBK=8$aiC7hfQI0o{U4a1*xOE!Hj2j(Dn!xnW-?HJ(6`P7JPf9AJ8G9 zM1YXPQBM-PdcnI80q>S3qCq?t3}e7BgIpf+?I0We(o#w##dluOg40mV_@_e=>}WFO!rImfrf_)kN~cudd2lt#A5|oop7fg+FAQ-)3*vn=AXKA?o6LHNwP?Y7 zKzC{8wcR-WXwPz%>nyo$rU{sHlS4M}3buWXw1Z@g-&ig9+gx#@^@fz_Hc5%u8ww~a zZ<&6`V0n=BhO79pcFZ0Gu{Rhd4mrfHvyNGj=s~;ZEET7w=7jGdck9sJTP#ZC6`Lu zNi$3umMq7BK}ce}x-OR>+mh@KL9JPSExt34mz^lkroJ$~5Ucdt*0pEtj!IRy${xq_ zuWww3gW{tz(;Gf-2U|;uIa?{c$l05ut1{T}IOp*K6I}iWG}Jq{dKP{Hf@yGCl(CaK zY+rph8vB+Iyx+Cng~mIx!fLnw}j@$I0ir^RAHGvJCg3P@DW z{t66cMbC&O+>eI^j0LG4OeU%ps{D>>}aOx^A@CQzE1Jf z2AD!*%Obe0w2*L8zJICzV&e|zY|4yo+}gPxhk6LnS`MQM=E^{ zpE?4->iUWQvaWk=zjdbzK|z?e9jB3JH~o|sMJ%Ym+?G5fjjLs(Gp+qX$SoWD;N@GF zoqy5zfqvi8aNAG=h=j>hzX|qRSYNtVc(@1|c_oaKH*JT+seGGlht7JgzQ9tbfkU>H zb6ffCuj9|kn3Mfg@8YBOR!ir#c!cYoCnOQb{XE!@WomQ)hz2@APQi-ZtoF6`P`+{s zF~dl{L|!EEm{+rpU^D|X0!NQ){l%W8V7VX14`aG`8lOBnw11`lYe1OB`yh1kYnW6? z26H0O1i#5bdNC*%x;>0I`En+*0%y>$$%}y0BIY0)a|KuGu|eolb=lGiHLl=Z_2BY* zcS+uso1BmSI9I9GS5}G?E;@Uq{a5Mm%ykjg3#k+%wl=t_-jxZ>xV&dw==b9wRWuN) zf1C5z>fz_bU-lIo4(T))Sm7pqTN)?d$AwIU505cvWmBU+X{jZ>7K=2CZ;F!Gc|-rweR`cn3u0 zd1)AflDx=z2Pn|}(uh2^}~TW*I+~b{XYu_kc~2XYZ9Noj6fBjgb-&CgohTXJo=DpCJB!`AGR z{FkKD`HGaINSy9&+u${Bp`cHaDW67zORA*Tu5<0e3y5$u-Q(U|4q$xV)!@}*x0~i; z--ugK&9gA-rDt`*fo7?&gID$HBE8l2j1y!9fO+QGv(~U~(zb0&d+`fNP)suR_qGp2 z7sZftg9p|Ao!It)^;jk>6=>+D7a3Th`waFMkt~2_Bc%Q=pd;KgB?Hqu;s){Sl=dO^J_C-o|cja3sMb( zQrc5&_92`AI;LW|sk-SX7~+df z03?uCrKu!eiuA_&#t%JLPkOfBA$;;hJoTc%z{P&TJ_aQ!N3Mj;QeYz${ms5V zO6-OpHT&9UjQ3PCa|n!aeY(pKW#iw-?)Qgbg-}q=D@vo|-6X*agmCpi*4EWk_!NQ{ zPL!qRBCzLzTXScH(RpAjiYBUFUJWC*6bJ&IG(_yt20?qrL;&yn+c8tH;_OL_7SGU) zfDzbnRY8anp6Mc$O-tZAVmD0U9#$;GY|ytE{8i7|)oJh% z+ks57NvohNsSqX`W7tq(ziP=0ZqC@`2Y11d1p85hU4f5|pg zY?($!ahnz1<25Yj)B_|z@JgFt_@IBaduUTVVV!_+Cu=k@ZA-BKd7QW1z9)HMVkU-m zvA}DlZZMe=aVDT{mg(E=$NCY2B2Fvyz~ zQ(rL08n#XP{sRA>3{NPGM(GYfennd zg;u~f<5Gy-`;^6yZw%P*HR*!mj@Y%|tF zk9nSOh{&OO7xpyAg@xIPR|5cs^yI~8j9z+x&PP|X*euaxFbC+$v$Q$fMiMOrLgaJK zoU|G6qM{eF{>oYftVTP~l{&Hl%vxjQ}c}peyxjF$GrQ^zlm$9z{aZI_Y^7hAh+4bd-XOz2t&AYZGNDA~DOW2L#A-Tw0t5A?A%%ScsK5e!t z^;a(Tkyjyzmo?wxapknD1Me7$0RJ zh|xVZp^7Fc)?$pAcb#s2@ok~@b|UO+t4*QgI(7>j7mHIHktc?qWnG)8|pH{e)x&*Brr>zR)D5JvE=vR zs5H;5`#F$Y{kw_==a(ef-3~>{WS-hQyFyGBOt7-W(!bH-8rXRAR3xa@jIK-UN)xyw zp2_Zjke6I9M42_Brs{?!t>4D;#CY4+@7NL9q$d}kvRcT1@m}6d0v5Pfes{@&1D02m zushl`*q;x{JNprP2D>li9Lo#53LMhDa!jBjY#D7kQV_Aq$l#XYV|+3atGni_T95O> zcQQa=K{_2P=Vs?I_+oLH{6L%t(2bS@y_$Pt#;C(l#9Oe zi0`~^Rw}I}McHBvf|Fby=*|qdM^<@U!E*TsR`D+0$FJBsVk`god8!x-weJjvz`8pI z^weP@zR8JULe}n+sSkqL(2r6(?;vC40Hwg!%Xq+|t{@%4^*zaP3s+eB+TVtgmE=7} zC?*k8&gE?jmeV-*O3NEt5o9G3fno=w<{qaQl>ElzgRv&k72g>h;LfEQhqtW~)@DWZ zBfu1o7nVOwxhB3y%EDx(^-x2L3cr=vc;aq(kyS94hzNmhs4 z&7v8Ca`#Lkqo4m%1A|@oW6G(+oNu&@TbB4IsJvi|vp2YCnW+|K?1ki<0|9#89j7PV zCVB;g@Izm0KXs=?Lf`hcempv1SP9Oyd>KzE>T}6Roe^zNaREeWL4Qs1tkifdo48f# zj=M&;U`>RBWz$f?3d8D(MDD4nbkw5TY+P-It%+hTJCJrW%aw(&?Q5kLYFt>2xs*~% zKg;-XJ0$yb$@OoOJil{?e^qJ|ia=|knLck5h74|1^SOZ0)Y+mSO)vUS?4=21=cB7F zva|>nP&;P_3GvY;GbWZ%#%90JwG7~>+Rlk>S(}(zzN~{_aWyowdO!z|l`hv>y3f4q z)+v=+C)nB%mX|a2PufJAwGN?uX^U#bJ4SnY=5ZuKJC|MkPHT?8{Ip#}SE5rE{#!SI zxzua_=plhKG~)0n6koR}(Ps8|QNNKy0~Cm&aqo;#2^OGEiHC&IgwjBh3UbSg7ZPdV z7Yk=X^${9{fs-+(*)U8#xeNi0$ew8Pxa_s7^DN8QTx$F&sd>K~6{8PLrw$s-f~P?r zWfZW5{DS!6JOM~>)he310p-?)(c3f|d!WVF5)(|qSM&&k-GgfN%Y;LkY4tP^LWRmI3}z1R(o+O9>Bb( zP%igv=lsdDCV$xPxJU^REoPf6`J`1w=(MB7MA1C2JRnMUJUNcroZ`K>^ zjmyY{9h7H9X6a(Qs;0Go5lg_VjRu*34qq613i)SHKxVC4TKhc6is9BOv{-LKv&)(P zp`a_u!Ey9w0$}k5>kPwdfw^_Y8mKLxeaz|>&R9G|LE`kk1lV85YN6ZZ`>MsmRkj!U zOP$*SFbIDHPPkJa+f7^I5$svfp0h?EeN1clIYm&>25fB3h^EQ@SZmj~_f`zIdZB(8 zvQIcDkm1csu?Tow$!RSm=_iqZUw!pyU{OxFa|#zpo?x1}0E{qXi=fxs0&tbvDmi%K zdnTp~9%oPn^&fZ`YzX(rv9NbUrDbLua2mFIC;gZInIISrjyLm^1M|}VIWo9DY9m2h zOQbPl*!&((tkzZrHX1Nyx4mlvh9h(d>5v<^9tuOZS83V=GDveVgZ$(SpA`!QK&_Cr zaGL!lH9JH{{s;kp{j!5j6uypl3jjPIxRs!7Z|sp+)iV`92EcN!P}=zc&5nk4Il&ig zMkZ$sE0I76`&;#-Ldk~QVhbr`k&G5tHEKq$fuaqO?0+d#ne?jcW!jYJU*mh=z z$kmcPm`$rg)Z)eX%x6dbx)^=n?|v`g@kLqCxO?|qs7js?0rm(Ju?}eTgn;A9&YH)V ztWKnY9gZ(1fd-LxynlxZ4{oiqzxBcmh~#6}o_=(0WMrR_a!MA^qq(cZn1X^d8T-ob ztv~b~V!fTc6&nI4^gl;W#FiI{Vu10p5_4g=8FSu14a3n`cDD#^xyLw0#^%W_)~&60 zt{z)o#%zG7279XI*Xe_oOPO76tW+o;$o+Arxss5A`+TYeF(}9~tCCXff4tW=89657Oy)c!L6%ynh6lb3w-8sPi5D4h1Z+ z-?GDc4iB^{4&hF;$0xtq1C#~Ry2=wV2uVXPu;(isDjfk=i2o%JjH|h}ef#!Z&}2z* zRQf>;77!Y|MD%dnXw3up2Vqrc^_K54;alucUHNxq{)REKU}5yS0#=qFB1VnNAk%Lc#Li8)iuVhb z#)=nzrmsooo~?s}F8wIV6{)tA=>oq6Iz)87;p(j);hvcUIJv+7AA=U&{~s51XI8}e zW_Ocv`yj{X43x1~&ZaYttOF|@DczXU=7%6wXf2tx;ZQM93$e^Qs*8V%8;io~Y*=+Y z!wWCWKc(-bLj|UTG2}HSKMp-R!$n`9Jv`v-XcBm5+%Z3TPfY$9b{qe*%ts%T(Bg=i zlQdE_)a;#mr7!dpVd|!>)X7oj?K>h?+k6n-!;jEtTp3sI{Aox@xR zo6YLvKI{@mihbqltlFhWsus)_21E$4woV?L)Q*$EPd;hJ(Pd=6nj z&Df+&ZccNOqs&MipnKorH_{LM`&fySCH-r?6W?`DU9XKdEqPwBr{ZsPas}1^E5Wm^ zith-iQN-ZjMrB}jrc-MzEl)eDNW_^eTrA-@9=Q09K@{<#nydn!@66LEN+X$zW0+}_ zpA_e3>1w90Lc-^B7_xT$mB^SL=cpfX8*$Nadk(d(yD!-98u#IN}57KvdJgtls$( z4nPl8JUK|k>O?y~uEA;GjI5`08JzA+KG2&fhj_t~tb5?!7Ct;82>79K*OxBj zTB6m|2eW(HlpqLzmz+MfhR;cKEj&4&X`d?+mgTJxRa%)C)$@7%2iW?6HHpNkM_EA| z#;0f46}9zaqE2EfQd6Q!uc8S{5gdELtyAq)}RhZG;!Zb zf;4K{_DxL(d6`UOn&$hR#Y@+5E@bvA2KY^EN|SLV^0CLsF8#^nHxY=MykB~q-nggN zdR>(lAV~~Z5T)HIy!J~qAs$zvI-hWnhD^#UoE5UMwj4#FxW5RLaW2pxyYFKSu)F|8 zK)Vz?OA>w{v*$c^V(9X_wkOYrRE#F5@S~||97=>q9WJp-JG`ie_T(3Zf!Mu4&eML0 zR1hxr(9&cc9UQ0{t(8Y_?)KEZK?4)e=+<;RH72?<2h8enxv$!w(SdUtV=S#@I6}Z=;wMr!7{=?R<`8OWy159vOdD zcV5rYyo-2$2Ke1m3my%t>775NR7p03OQ)`fS{K4g#*4&9gJ*Vk7Eu!C<5mxz?dyKQ zv`KMS#h_%|)4n*dwDXWfdtN_e#`$6AvmNK*HYuSQ{$Y23OA%a>=Q#i1U;N=$>{z3C zy~iqnNmBcZt-5^S{-#7tMcPhrx_lUE;9P_OA1bQCcZj69`gF}2pxH{n03HDr|KDUU z`hk}0m)xoZJSzDP%8rA06y}HLWrKl28^I093d5{+Mz!Q3Y?^w0jy_8h7HKDBPaBqY zs_iXHkZl0iVEuRQf6(FlT>-H8-T~!Gp+}WT6Ra2OR;1irk3>D(S;KM7EPN?++4IQ| zhQx@I0QzRFWD(~;IZ!?1STDC7#|3|2Tue;;Ba4=ESU) zq{)10&Wj(?*z2Qa8Q$|)hMGjm&9sTH0NIVca-zalS&W|(*uIv2*ZF_)!L6|*Xr(LlkgwWLE5O2Ssae7S# z%~@zR1k{%mUfW4|os7Z3S0eVkKr7oD4WKK+M&eswJcrW6Y@2=fEY>R}3&*tyXn|eQ z8}W44HvY?V)X$bPcX637P2=KXx3>EyhTA+oT6T)O$LWX+Ri!fi$7th#6SzFWja>;9 z%Oe8-ML@d0qeGNsW)kg~yO`sJi)=%z;_56YfL{&QE3 zViGoZUszWJsRVrbT3-Kb&B4?pS(7FW00WL?e7-uw>Y?S{P%h;^seC~qAduiVAQpKC z1hhB)_7P2hTQ`2uIU))R+$0Q8wze5z#%~R3HC?ZHVc_t>1(G80LWs z;pPxGuZuP7I%}utFw6zqlaTSXM$3+1%CmEHl~9{nj^SAlX$*(0`^EDd<=l9GjAARC znc*(1^Kk&(u>;=_&Q*>x{%+L2!&$`?n-+kV=-5IXDig#!hMb_T@zc2=od~ROJfEy$ z<4}e#`=#zShn8p$vKuhNYXsp8Hj@yoaWRnry1kJ=EjK}SskY*J;WC0F^8ShUTRHV_ zw+Y3xpMZ?!gi-KWf_>I=XZeINV6w`!&m6|*GcDYrwg2B^mxr>S34h_HC-O+GnuC=m z#$qoLhcw~mP-T(E`h7Ds_t){b=`KnG{gg+b0gj$JMR$-tqjM*$cw$D0{VhW!#_3vy zgps~@2dFeFGj6r2Zf>N-NV>>f*tZroxp#P$s%UO`sY%s(WoL@r(#rCXf}vOHbs0t@ ztCgM~4WQd|rQ%DXS1(RA`z#o9ny&-I2_%}>OI*!-t95!m`m*%1=eGf|#f20NRy85O zbZ)(a8(o`-WKx_XU6EE=|_ywSf}+C)^5at+U8(&H1S_3kl+OF5HgjVqI&A`E$dlT78# zC-wdML1(Ajdw16diGNFCUn}z|OyJE|!F;6ul&DSV?ye~|SW4m(*lDeh^towO3S|$a z#fW_UChgc5WwI#6%dH1lJ4Va{si_?4AvAc`Od}E>Twpqn*)QoXCxz~qz&wqRRqLX% zw_TGgR_;=3pn+a1;<6{a6V;fisVF^6Zf6jPQ0azxJ+Eju? zY$lt)J?B!Cu|1!3c>&gD&> zdCJIbH`AcmidgbsJJnJ2ZiZbjPT3Q2n?2)_&GU*{Q;|?mlqX6`N&|1Z)Bh%-A}@u~_H^ zWN(b{Qdw|*ySg>NoJzUSN~J!yj-NcxUZb(q|B{>8S=~q!&T!B_O=AZij6~)*CumLQ>Ot$=GTIV zXozkZSVV|dsN>K-tj1%l#SYv`H{bXDv3^;l7&K$YL{q(je|Qlxiv!dim}8=Nwm`rVnuB1fw+SiioO@9HP~U{{ICh zwXCb$hI?j<3rL4e!WUFuU|-onhqZ8)MxChQr!L#k5ug62MnO2zk^5-IqL}5=_LKsBMhFvL)`^I!LB2wu}vN z`MXQs0fZbWPkFWur^eep)HPM1UbK+{JvV5Cx9FEp+bG#wMv5{rR>9z$$^9R(VI<54 z?`3VW1mEYS$&zZkjqjb|CQnQeG&**zP8cC&aSZc*o=O*uC~AiFmVTNE+C0(H@(WSn z9ou?S3WM>o;@}-#qSvc+(*SK6!0=_6mo@io>~I_w6;pyxIt&H-0P9 zXosW;L+&XER;Yjae*39CVHjs}_G`!GL>y^>vCp@(Y9=wo84oFfGEZNB?y#8^bwOwL zkS%#lmcD>54q#SpQqwnU2$TymQB%V6Y3^q=BBrWh2wb#rHKn5}qlPUY;QrSCMMg{C z+=uRLxJ<6VSz~!k=wI2sCk+u-DeYr;b=~TuKC11W_V$`a`+)UbBYzh8J11P$bQW~0 zAZf2;sgZe9U~w{+*IzPdtnBP}h>S7Q%ybNQIvEP%EjlYg>WHCF72F|#)UFCU-7Fcp zUMGc>;z@syKOQW;SBi#n!?ki?11KSn4N5iPclk@Gl~sZi*Fr3$6-UA0u-E*6+r$b# z)deZx(P}DUq9BZIdr}=&6V8o$K33nQU|kq2L!$Y@%PM9a!vIF>gKOS2u}R6kn1& zBQu`a_2o|kO~%qpK#$+6qFSXiD{EsdWiV;R!+!nD3G;g*x;ob zb(3zqe{O)iLXoM|$PGl>fUL&xXA>kALCJvQ#Gq~kxw^e$Sys@d!QjrN-O5Ph#gc*l zVlV%p5WAF}bI&S3pa{kB^$4xPlNdM0$J9R=a@waI2oNAT>Y@2Eu4(Ej?tQ#ZdCSB# z=76)hu7exhGBWy~Qu#3*zW7P~6&t7_mdZN)Gi%kGN5f1@B92r+b~ zP;?6I7uOf?+VhdPKRc@t#hD9bT!|ZA@o@uA zY)(8{tp%BGr2%aC$nC;?Du~OK*^P#h`Exr3LIYZ=C7l!sl#YPXdu`4zs4n~kb`HZQ z?1Fokh-6UD;7l_JX+t>;rzQ?dEbnRx1&pDk_hEO{np;v<>3?Vvb*mNvurG6Nxtlav z6{@e%MIEoi3H3&4A_6~}<9Ck*;wejj+Vms|@ax7(+!O(=ThM0j4 zFM?Cn=R>-{WP2U3#5L)TF$?2XkV`5|^@Zzdm_UZ*9JH;ulN%3$)~Qrz5R`>qBWvLI z2snm!LNsdi?ZIb`l0yXut0Vj?BRH^q$hf+SarTI49zq*TAH$o#QZBMtfWK zo<{78gZ(T z$VuqI=0X?wBdD!Z-&HKg{CUuL`$7dyZ^IPUH#0X%wfuJ0t7N>io5;_ZL)CTAcZTWA z=WfilDC!+~%#e>Ru1>p{fRf}L$~mu8y+72F($_SQpvK)2j#D7g(B{UnQQ>W3CTn3B z^s$5tJe5&MvK+p=LrXAc?JYAwS=Xe6TW3t9rR`B3!mJ8(`m~wZ0yq~&vNDYcvSDK| zz@ZMY9R|X2SkTydn#-!cpYb>a)M5fPKOJqt&DEs>5NNgMF9_CwpdhLe1V6~;e*(lI z=T0D?=!g3K^E149Z;1Fq6aX(WTYo`~?CY>J0JArSgKlQ!c?wIO4-Ry%pV%tk3^BwB ze)@Ogv~%x^(iY_cDzm&~s$IdrUv;5m1BXKuXM!ysHP!0Ie*1tEn9?A_ zzcp3j6&dsuH4HZ;h{2Rt^*mhPX5V%c{%*^zxQ)$Za0!sB{ zviL0%d~U2a!NR#mDRu+#U|(7F&C5lO1}!d5P9Uh%t)&c113K{~`h9?-->v-<6++Pd zug~nCOf4Iv8HizMV73@ksd+ZgjjrxOA(J`uJu$YLZu_JzcI(s))4Lo{G}Bu0%2lgV zRMHK(Te6G?TK4tyeJ)utViCtiVWN9J#KQlrig$*!^S@;z&cCvgdF&+2`1=2P1T3%Z zE8;Rc_*6&5LYwKwts1QnH`tt|%XwO*dI%HtB<}s*^w_q-e81Ma9hrkZcxkdaC#NXMYg@!rJ?CpIv--EPGl42SM1QeG$gT)f{5->4o z4N<4#w(Ml$&&5gfFGc+IuPD@>F_22NJ!)<#wqAD?ohOW>^_|s=Q}iN=`YoVrO4mwL ziF3zJewfq(z6Q`;3M>ejy*a3jE5iK!qB;fZiB(Nc{+0~({3TUik}g2eFe}JvFUZtk zGB)y;=h5ebQ?*#@MKTYP<{G!fLSzOh8py#JI)6hqF0 zvXN#aWYs^xML1H?9ERu>-t5PFcFRZB?)sOxo&nX~-exUlIk%AqSzm*T!o3IZiuO?x z5cgH*PU~=Hk^P{GS;fNR-CSEkEJ9r~LreWzGYj^;KP=sYirvXlj_D7?bHL&frn(ME z>3>xHsHAUU1sjlu5c+35RD3YqMXEkz;LiivhE(QOEZv0zj`+rmVK-;x^oyC?RL_Xz zln&1)SI7N!gMt5uG=R=#BWPZb*Fl;R^q%a}JX^XEP4Tg4j)`ev8~xZaGSuG@%fcVgr!i9LG7^R|3Zi;5p z%fWnpYnx0=tm6tgNq8DD^2_8o{V&4SP!I!Uqe|#vM$MHqk5;#biQNvGGp5v`?##p) z;+*@Vja6Cz%L%7DM@bbEUuiT~^5SzSf=L{j_qgDymmCNfGa&K(!DSKa>JR>|}1Pb!w=x zfsW`YRJ2&p`S(6`4*;^LC);P(@*4X=o_ep&4tA_?~)Lwq1S~)fnoM@0GjT)BR67<`j9jHT1@QjO-hT zCZdfhCt z-Teoa=zWM*aXO$T@V}4t?Spe71Njk^YfGUVRN2DedoUnljU#aA9F_IN;hT%^_1!M6 zu8a5*!?he|-?D4wp4#VDk9v(*p^%m@Hfp}+!4&`Idl1hAEOfx2+eyWb7u2^HvW94mJckoJ z86Q9+8Nx&i9gB)CJvPkvuX#TH?E^As$Yn&&)*VsAHi-5itWgT68l-MaEy9GTtxzn< zZGzULXm%4;AY>opQ}NTau-qW3r(tQ!km*|Q?Bw)?p;g3BE>CdsXMd7<%=43v$xHEo zQ`F0j1Q5ANFaJ>!j-i^#_j|f=*+qphq6ayh*g`=^u#~%?7T0J~o)0_~bYIj)9rT&P-l z@3H+&D2?LXu4rjVY#cCAEJ} zW7LmLqMQa~4k5pfoassec@$DUZnQ@9BLw+m2-n=z{0aPwRhdcpb#=C)?->z?D!2Fy zuLHl^?%7_xdwd!AekD{yFnF8c@+3lLa(?t>C%=KXvP-MOX4a9~mr7rZAAW-YRfu+U z?pyq=%toPWidA~kgWz2nXV2W6+ZYKU^O>?-(T)wfadxQpFY`(Ck-FYpuJ&LH1syAH z+{U&s!}*kOpbb4`lny$F8ElxW$Oy%My}iU)#|-9VlagDB(T-sZ~6Jl2c`l6rbc%+B? zr1Pco+>dau=qn{V8oEcr{w^nmNi$WQZh!ksK%HHZX}^UJLm=q?t9L>D^kJ638na!` zmY4mb5wT-e+dwUB7~{9+PdEGb%pfU2BB48KP>r)a-B-0E3AA}o{<7v~%1w9U%2ss_ zI1${7)iP;64MjP^)wnE_w*L@D;!|y{rau)DSoq6jP7ig%9_szF()Jil3}s{`9D7v7$v`m@_!eUG`F%0WpwR66;l1Cy>4@F^&THxk@m7btgIa+5}Sn!;&rR6 z43&Yyg)Q5rd^!1&l8J^@5l2oGT!dA$Yp#AQtu0_ z;TN2-U{`I&gL7KzC;6Px?0<;n^HaGU#8M3YDUvUA*CWPw&~h^$AYyE!GIVY%glQsB zCCv=s&Zq&RA^>2TPA-mf8%~kzsbuQh4~}JwAZB&}TNNRt#Der!gnL!XGMSmf?!-Pw z6NrPo3c0{2*?enjOEzka2B)|f>&xy>k8=SUtL{^~1@F4@(tLT*ek#WM!*)lTn!8}H z3nnyE;M9l6t#H~ZF<3_9k#J>o$1P&SJ?HZc6q&oNXI+x<_k{JS4&yjj7OB4XzFF3C zN7u(Sz+`=eY}DxGJ2G8W~i*4liqx%=0VE83YNTjVO!c!5O z&~-ve8(M)LFSO1X*&Jc4fhAV~v8JVs;LAeGB#VZ1jMS7PZ1f2#=lZTAJmvQem#d8~ z%ioSY3H|#!20}J%>fS4GAAiZjUzyA~Gvc;J-pUv9Cnp!#q;yigvp*0o1g*gj>7|R> z@kSdK3hcE%kpIePC4~-|yv`4^aq5T1Rbs1#Eu;@8NGH3iVpk>kuh^lljs(cDh56JVZF<4CM>+eka7-k^8!U1v9oK|6E z-9v9T*fijhfj+a21Nc=KM>zf$}kkw62xhdLgq zdjg3Q3l>X;%kx0eMT|vwmcOny!(2W9S$b^jWQ*QajYd7In##~%X+8*DVOj9)9SXPe zes5OiMIs=H!F*i3#JLx2y{e0ucEiz2$7@5tC5Jdere&C1oBvAvQX7in`_&V}T~!Jz z2QSI7OsP=AWQlVMePW$j#t&+-){4Se$p+H@)C_iueCS7IvJcx*?t zWs2%W;EKsQgiH^SRXf;J&T(`kR)Ui~t7Wam!j!&ol?_Y5kDPIxEh^apM1wPZ0m`a~ znXW|NIs~?KBS2?LS0Kg2B}v*$IaCg3U6qTn@79Mw{Gb+|2M-E_;OPYTbEQU?icO3e z@WuM@`0~z!c~MGvV2d41E1CDh#^jTEDB=`Y@XMb!)!KZmE`a=bL?oF&n}6cFP%Evv zwu&X3q_{ecu2Skx%fZ|GLyWF$cZCGcd&CmZ=-*lF5kr>6hPnH?xCNn0j*1+oI5lVM zbLg!@B04m9zY`s}NHw9vrVC;A&Y2(-?d7W%mU}we`&6b(>3NrgGVL@Z8)RbjFy zO3jv4f(SHO{rl&6mccKsb~phJ^J&XRS)B8@2XwH6@Wh)V9ctws?;THu^v{cMB%nO# zVrNFJL6qd5_jg2lFLEIQ^Jt?RYXa0#5*`5=QCMZT88JS~4KPrq82U_-tv!nj9RF-J zm(*;bAkzVftK@9qAvA$JaqEDA-Lxr2n<*Y>s;1brx({!Tqp-TorCww|U>VO&T z_UqhmHwkWqr~dceJQ}8iUG@oG-T(u}s!z+5N0 zyZ08}SMDz5v|Pg3!|J+@DeFC=x0+iGp$Z@%m|NVR!(g*7^mEaIfN}H~bs}B`D1$Er zVT0J8dxRE0I9QfLn0*?Gmm`6q;l3F-OYH41dUUdvONCVGR`e~OLfW>|#ugfVeCZ}Q zuSY`Ki33Vdkl+$wH0gFdUH@;p1!KU87P}j3`+y2W9>wZZ?&B`E&(tjDq4MJ?5I^$S zK1oGV357bh$#^k9oU&~!$6cOw3@>!_08+SROwSQuPuVDy%}FBD7KdVT`A{e~0#MwT znwyTx0q?FBJ96sYHAZC;I_D}Q%A$K@gn4eg+9Yyt-)>uX2R=L{3Y_|#Y4_XYJ3Rab zyWeM)-}<4Rk$-@I4mU*x>GRD-RvR+Q@3#2|DXL^R5^OVtYaS<}OLrjcQ|1{|;kyFr zSYx-ElNX9eKh~+q!z7Ee*dyr)F~<>rz$sgM!yQP<#Sv%Iv|jgTx_JN$qYlX%@iKEv#N$C|v`Mt#O( z-0s@_{H*E1Fwvvi=*F0SuvS-`Ksk8?kKQhP!7%Nb{ky)1PvHv+m5{cK$N$g^K48nC z(fJ=DV|4E)x0gco6{eW4-`6ngAi-rofl#kwN*RGcF6@Sj;x#eEWso1y#h{FUwF9Oc zkZ$L@Q!+fbXQU3x1}R<#L<~3spd70TSrN7U0IQ79ZItrmtEt|U+d+$!9zR4P55z3D z{<*=TjsiG6o)1Jq!JC`08>Px;BMwp2PuNwCn5%$yBmB65a;k{oXTnnisiX4KFg5Rs znS}9Ri`OOgDQU(p$#A+hMme|S+Bj?GVAZ^6F$eOES0A%-FTW#BoCx*VH%UTo_ZV$C zU$E`+_FvARUhvyZR{wu=%nIv?W=*x_(Eqafr*Z*qx0V`E1p^4~2@&b#KoNbAy6tX( zk~9s8x8kIc3G3OAd#Nm2Q zzDi!ervl?{9$Hqmq=0(iMs&;BHVl$+jfF$3^aMm~oYp@B*SrtV?fBDZ;+BSU{lMugZkzh8WW4mkK3^jpI;$ANMxB-B!zg$fB^kMU>*p{pKFdm1E>#e%zT6c4K z$b`gm|);O<-@NOl6*w9iUXESBIMP6@1k>NFx&MoW3!_e5l!vRF+R-{|B6uARV@~ zyROIpeIB7-jlM7wM5c`@!9^}p*{VdrYs{^@aOt;X%6jAzF(aOcAVVBkk@iOL)#Eh2 zxbscsm7mja;sE^m(lI(#TSICOE=9px=48*Zx$?>T-4qE#sZ}k{;tQ(3Z$qA+abt|b z@V__3yh%6KaD7N3qc7ak`crwwSqXH(8s=X~MO@g@#wE`;C@1u~j9RR)xgENuE}2eG zpF*s_YuK=0kwO4iqZ!iLc^LyH^G^Z0rR2fuX$2gZxX9Rv4w<&Gvu!Z#Ah{Z9`Yq9Y zl2+2Ni6##rUQpI#H}tBAprc_lS9{0*JY8$;@*=+RK(w_Ql;LDt!jx^`oPd4Te#oK9 z=64?ajJ_%oZ3w`_At>5E)qD%`rk7;MEYNLiOeA=Gh#VsGo@({ktbT(j4c4T{y(Tx! zg_Q}ihwI$~ld6F_I;QZHvDW_I8}LQ8=dbzDgN@R6wZjsQ1alSUlZs(3_N3)+uHxL^ zq5QjVcoBzpozu8S{Uu>lIPx-AZmiU~w5E~j_hsE~w~aYz;H&8rYr2tNqR`8tYIsr& z6n$?4cX9O*l|{!=DfR0)%D?kA)J1h zYd47Dg85S}8AEcHziqFYFW=OHapkAdJybiO|`Lu#97{W|=k41%ReOgV6=)EA( zYHBM*@YYRmTGQOh@;)qG#h3+bpP`NP4dZI&!DLn?(_QByfkx$~U#uga~)UNo+~{5zBX)d|V`rKas`m zOP(Y`uawUErWvZHlMBiOKWx*yf2R^&OI4Oo#W+K53%{!tf^eFVzuR{ z$pKwdxOZS+@(-mIYM7ZL!5$8AhK!_70}#jZcVt_s;a6@l19gCD3AYpH$mUK38pwMl z4CpyO^+bZ@@f+}9hV0A4HWSx#cIA|1ptJf4t_wf#QI5^f2Y$}Wk~0V%NQSIvU@Uw1 ztF*jK>5N%Jc%7Y$oAC-4e1>s- zh>N%sybXrHMkoHkWt5~H=YL&PI&hRHm91Fw`wkHc#Gvf-j+~rT=-Y$K#UT$kv1jq) z8oe5=@XHtQ5!q4We2r;^8`85R^b&%o{wS#jgw4)WweByrIm3>kV;OX`+)+ceHe9?M z5X%ZKBO;{jO{6c#e^Qh@OVr__wa+ly^G?H$`W_Z0c;>q>n4yXW0q_emfauBJt7kbOR}zSNiC4>0V7&|iFR}xXbGL>~<5J@}>3%DTn=vWd zZ~LQ`BJlgEn`3}AI>*hbCK&V^#(qS-5;JOtv~IzKds)|-bktcSfoO+F2KpTEhXY4x z*zVc=a4KjAN6w)AJnF!pl{t}Y!!drJxG6ZYK&P3t_wDRpOI@ir32F%u6EHgg!p;jw za4Zc0E;CVMkbHbFy_}aQ@xg$Sz_uwE_JMmhu%iVNqA>ieua9DRw=TI}2X@HW>JgbU zg#hO8=)Q@@5O${T6*~pz^D)d276$2EbIbDCYKLZfqm%|8<+8V)rv_;lVo;bUtP^~W z@Vl7=QCNF}BSFoIj5Mn`sEoL+dn9WB;+W2T;!y&T6!p~Pq7Z)k7ISDD=yK-zC&fCa z1&}YB&G*xh0s(Z|K%Op)8wZ%vbFd-sPE-yBa>-Lx7U@)##s6E(o#P;$%+%;CcTKh8 z^Y%U@|GI(^i5|{*BbC|6Z!g*x!I(RpnVuzGaP}i^%1A5o?%Z$pGlUYdm}uWdqq6%; z54z7PiW{98!)jvc-W}Ca#M1N1h3O zq}w`P@IZ9F)2VUJSqfk(-RM->&hNxoR9ZCq+khi+eAmNOgmSq95!gkO!!*zzOMdhp zaJQ&U@u}r(PpK(8zgD-R2fGQ~=R5+JH~;76q!~7Vhk60gf9h+vZW5ju-14&CP^e04 z07(sm<{UN`q7!9m+?L;vPfG-K1P~XLGKbzFhTz-LadpEzmm-b~HCmvQ#Fc%bb^G*oG8Ew|#57luHTLV3c@+!TqB zNrph2IpY9&pE=0wgQEk=-RlS3NowO=;rJKq+XXrRWy?#FN;#(q&%EfK3#T!rRm-e) zS+VCo_i;?G3aT^p;0ohM#MppGPK|feoj@al*N2Mr#+w>d1D3}1ShVipEWrjUemqUs zBb6xUlUcc*WKDz^oYDCj18O_Cj?B=*uExe1LvB)ri543WTvOVd=1|olDc;`(QmqIW zky@%PH!^^vn&}l8*7f!c=bXw>t~o;1i}ZXAQ$d-|4jx0?8YWS*Y*I}6Fuvc7DKhO8 zd-<|4ale*f?b7XC-pgk@hf6RWH8e*>3)$4V<;IX>3N~H1cG;g+vI51{bDzdIRj-(1 z-9ftCE))?D<5#rvyJd}Eq*I!pQ4DAJM2B-S@ zS1VW9vNM7*QtP3oV~Ovo6+3I_!o+QJOygH(;dlNNLc5V^@K8j{+->d$Byk#}Vy~JQ ztpWCDuqZ?%b?i-puZaexlVridF270TyhxFk3#`|wx7XdfLL$N0Z@C3}IdR1C_LQjC zI#(_c?cf=u6!mk|`o?xHObC2inPfjg^yAd}- z(&yj0CfYiwI`(xEMn7(AgkW6yQk8GmjBh0><#v45KCZoyE4g6YlP;CW#AhK+p7pj9oK)>zY0eN z&DDuZ_BRA&QiI*NI568`Wk1UI;qC%r7Cl|Ft?T!h)i3Xla?&98$O!jl2};TA}MfanJjeX`My_PFn4_h+P5^6-~gvsM;FSAr5WQuyof#YD{RiT$ylyhW1c{drpa#zE1%9=X9 zqhyq&oqGMN=b(BkKHPfpazBH#Y#^z_ahCav_H=kxmT;Ww}~ z%7)^`qH@fmmYH7tU6c$CdyQ}aeGJ%P(AEnZ+P8RWB8Z13sTRzF$dL8yX;B1;Hc}Ma zIQ6eo0gF%B8K_eEfWE&IT?TJ_OjuPgb0)sQXZs;P$;hnyfP!B(l1S|kYrtp}L}EMk zC?{5Z-0}vI8>uphdgdJBEK7p7S7ku8dn_CNT-cH76ixVHK=JhV7%GvyhQuFyuSTi9 zIupF!gI$d9C8mMhUlISZ%wfBGGu>1k6`x#V^ z^Xb8EiHK7D9H@em0G_*xv zwncCW?v?ken`P1-7VGc+=nVpJ7FHY?)i->jlnCdP>5teUQXZ4y(6ANB8t3H@*U70# z=)x1~wyY#Do+a+?H89~aBtrmn)p1Z$&R7Db`F~Ps-jsG>sIXzztYnIdYcXE(Fr&~i z?sokOfw!_GuouT!V!3Gcq7)nd3D>+dv2#;Ij+WbqhR?A_MmW5YjM_#i`9;!LFTF5b z^$Eu&tsv&&ANks0U17OT>cav1rNr&p-QpZdkGElh8%r^GBL5~JHYE8I4M}x(!Azru z6mYXH>(-p+dz#Kyfq=Ue$y&Wq!7}%qG%1ML)^55f_MkCJiiTyYLZJA&R&zV&3078t zHOvch$t(Q_{g7N1B+l@g)vD*)=Kga8NFo+5J6?eP@wyw+OQt{k0F#fwfLUi0npvbI z*Xm2fpn?|_j#VO}crVJ6YRm-CU63FM4JJ%?UZ?@HmcE4c)+zcE9n&d3*UA!?O`{Kk zBh*bMmMd7GB$@?ZH;=Um4r{0LWbL4d;sDr0$CGNVF0SO3%o}k^jD@Q0NjI^zFHV1? z@u+i&{9XaHoDhB?N{tQ+8VlwV0be^l1}quIHEfVapDJMP&Wk7v0imvz_39>WBL+g4 zRf9+Fht-BZR)@YNPS*Up$;gQgEZhN%5|H?zDZaLYZblJ5#IZXBT( zP(%3(jQ?H=ofna$?LJ`Z+IP1*Z;lPSn%W=VtByVb@^{x`nXBd!q7qysLF+k8T3oTE zE^V|&gIV>H_T&i6wYM9#5ZN&Lt!sBrD-^U`E%f#W&XFb*J>?O_G=G^*2|}_S=$4~RC0UG@ z$^2&v}9N8YRe;drDY5OEWq{bvLa$2R~3gw_5uW<6FUAl-SO0&-qNjn2Zsi19p&J@oYIKLYmG-iPX`F|I#Mc2nN_yfvarBe{-|AKyfdC)H}b z#DG^T;L=$T+1lOV(fRE^rNRxgRRcaGEGiwCt0v2BjDdE*0p5#usFUQa<6m*+>CK4^ z?SD30)I57TDVH^Nz@7O?R~I8!;YuWTSaR=qmvva@7YUKteTfzav#xp+4d9*bIte`~ zy{6%lv8iP&Oj?S!kb%B*r4UWbuc6vKRd?L6x7J%lMbj$V*O;A9;Z0-T zb{wdROt_ryn&tdW!IJ}m-MsS}kF!?bC1 z8Ej>ndG6V9f&mH?mP4VN*!35>M`yZaHQ5RqYd9`RD4bp&@(#8(#Qunec>tAbspg3Y z_WkLq91))|zj&VyEE`w<0SXpXuh82rG%7{GWo;~ok9)IS1#L}GJC}Tu?)HC@1~4f^ znFMBmF~_A~4mT`y(;FSR1e}*r(`6r?!;?$Iq0S%-*^# zB_g6{y<+JQRYN1=LJ)`Je2J~t+xR0s96-;iF%2#KwHwJmYz5u{rI z4^6mwu#FHxo2N((;xH7TlOL2x{0YhnG8b%}MYM};V)~zmEFYVF8`!ryR#H*NG+5xk z$LmZt*qGF3y>6W$7KTVEpXlTfXjZ`K*1eK;KJpYbb?Q`FPvJ%(M`8EHhM|BRTyH2m z_<~w2Es1&1E5oO^hLC6(Wwu(;d+y{ppg`m3BJ`{^rNg_10dM%$qO4ntp+qt&t3#H@ zjM^7tAUy(l(v`vVnjtv9qh^L-Yy}Gh3r^VO>S|i~CzQ6s-G$ZMnk3+MEYoum-}fvM zK?KG(^!gmX6}BM+wZBqEUC{V1XFFhVie{q#*5Q!oMkw0XIjNQ9#!L4xN~~`;vtNGh zcJK~S0Ycd7M5_$wW3V_HpCk%5!*>lELh}?G^`E_49Oig7?ftT(cX>h6nnr-nTaBu=d(cglgZG*2SH-JUUt=|0pXS~LSX+YUQy!C~S z*&Cunn)5VxGL$8@gn2t0h30Ja-zfaos}2~miF_Gq$TAogM36Kf0I2u}DuSe~Y+ZeH zK)|yA98+}B`*Im{Nx0N^dqVdC-G(myOO@P<%x86EzK4%3sZJKCDJLnKR{cD388v(< z{e`?{*HoU2BmirxcVw-QUazOsOs@Pc68%}sj4dh!$&L<%cpc|s#^`baZQE@7={{kI zuoKPrU+qnU9Eavr9sv8pT3Q-SMn6^qNH}QKpnWAIyvT-+HqPD!K=Lb91meZ)7_l1? zV3Yu&&pp$2pdwJbtFb=E0^Y>D*<8tU_q6*~Un8;rI-;&&T@8?c^j)b`R;Dc{Wk;f$ z63C6gGS!mAvoaI1AdtcwAv){DGy=+oW1JDCp35pfl+oC2F-Jepays_42;m~#(vkrS zIIqV}iPm8#k=B~ovUAFwg&oLA=)6MvG&dONaXfgKTZ*zK>vKMP16XBuKu+T+U!WmV z^_|de=+kCM(EgAET6x)C6O4+?)qLcLulnDqu7>(soX*W@&ReEC1Ivl|rqhC9o5g+3 z%ke^5f(4&TxJIJ=SY5F$yvNEE(M8-yc2Sake9$9$zPPF6xF~HXujG~MevZ>>&oWN9 z#{{bxr*jGcK65WGzNot`d)zsQKCyc^b$c7cnpQTyFrG zS406#f*9Fs)!&uh<}?I5_#WsbOJ@&M=~*&4TmhXSbn)_c6kO*&U~zfw-QHyByd$!jTOJq4 zv**O5y5*gZE1GQ(YDIt32`a#83=0#ems3{bLeTAyaI8Y(X&;Ig$8o(@QRqND4r^mr zT)PQFK=M@68eA=CBRo__{v*?wg~#@!52f*JoYvJ(GL=sA<47JoTWtTf_ycsJFIY8w zx~w};l=EKX1*EM@c6(`;S9eeelUfm^q;w1OWv+b7jB6Hw1r_}^!z4ZbuG|pGq213R zN!Yt*X-)Xt6OIsJB*f$AVx$eFJ&0=OU3cOi)z5XY|M=qJ|1#i7#60|?-7sw7YB&fY z>FqK~_()0*8FxwQN<+RwiEh7Aue;uyJ5cVWBjouz)h=DX@^?k7;Nhvqv!HpP>9?|4 zOtnNF6{M{>O|v#PBj}X9+w+xanO3ep56F@~5t+FNW$9~BXe0oeRB#9-XXIyFn#lII z=;QgXKW3tcG$A#RSA=xKK~M*WDAvWmay5nT+y=WGZIADWL5LX!6jIDY?8YG43dUo2 z$uahnXaB}xECCOXuqWToYN!>#c?3apN`s?Yl}opKxQBRw>PueVj6o%1(@{KRobfN| z9Hd*PPkGLGMU*D%3h?DWD=Tgn5^B$Exc!GX;_l-S(}ofJvD(}r)h`wGDhB7_)#3wU zf4tf~rSZ6knyjApnG?LkG73!Pz+`QU>{O@aDyK=(IxXWT+{*&FxgN9GEsjoF!h;QhQv}8*W)N$J zAwrOWO+HlaQHKXj7>m{onUal)VLYJ!p1s${D(HE5lY;Bk z>o!K=GotWB@PQl5C2^xkyMr-Tx`(0+{OGwjHn%b1-Zb$)7_=Nnr`Q~jljdVF4R`6E zZX~`Y`-PY{-dCUJpnGq5Q@H>wf(_}@`LyX~0pES=s-2q_^d!T|skiOZ zCg6P3RiPw5hE8J5J|_X2`R8PeMF%Il{ke};V@xNsll8KSn^sukD62BFloLauc<*t} zO13|QjDYt+g#EdpKXt@<&Ap9I8Jvx=FYa$MSG@X0muN3OU`c8##Rcb)t$0d)j%BfE zD!!j`!(99e+}KGg3XW{or%zYr)qc2cv&omx9YS-vVr&{P1X<`PpQ89JqNe$+pZ8lA zcZlZGL53p`1FgZ|r*zjIbPjf|FjoiooD5v<>i|tavcEW6RbPY9_Scms{RXgAY7bpW zr+ECo=@RVI=JAi8;D?gKrklHcQ_%34x@w%|IX+DsV6a*ODy?)4bY75{+j|Ei+FO|* zRd-#=e)b}iH3D>!PK!6ISt*9>HCcP><fzn`yely&%*LxVGvO)hy)o`8y|C#kNzWS*JzQ2Hfs?vLLbMYl=`z@q6nY|k^NN-dZ&^@mu zhQG(8h-!HDQLi^7y!EvKDci&>;~4*e$hRQkiv%y+|Ls*H22af;55IC@>|lbap{qdf z1564In?`_vTuAIO8y;g@;#jzjr*(9g`w#zN6~b-7KO|4Z)MWPQdtD z)Pd->#WK}9vMOpbQt`)3#y!Q61IZKXGtSa<89Uwx`|Ry>5(VM#9rRBPA6C@Lstxre zE-2KUNZCt*Pa>AE_6rEz^aRl#!u3}>J=_#8kaXb@lk~;`^lJzl~t#5-TO4sVfjTQ1bYmS!B?!}O|Ady9E_WE#d}uV0 zNL)({VgRe&Qba7$(9jPYwiDlAbDd=vHtGM3IC;A?xXfB8G$9~}?@+KSX%k`xfRBE% zUP-H^na`0V{w)T%B#cSc)zh~)y&G$>>M#?$r2RPUiM|G3Gmub= zO+gCvFepIhk+v}s-RO1BceLgdNK72qJ3p>Gw^}?dUII$6zHU-Z0Xg~^fJjFzkF4q} zMCPNE6r|HBahl>hL3)2i910LA397+vPJujh&V4p>WE(16FFKI zMa?5Fl{aoZq7BJ5-kO#fPcQFBC#~)7Exwe7EPB{W5}tV{tK9tp8vQcpkr}F~K0bfg zV;O_%MZ~S(Ya%=`3UBQ-E*^6GxFECZi9qQU)nwQ+&! zLtr6S=pEerg3KIen97Mu&X*MQV%BL@sLilRL3e*D)`Ea8ZsrgoPb0HQ6<|B32MtKB z=Q&uX#Pug7p4U&(*XPCycUU096zUTyCUUVQm6)>;yPl(?gm-1%!M5QDp9xokT#js_gh-W3CTbiR10kqRJj}!>jRQ8H-ZmjJ{DSfH0(@y^$BZ zd1GG{`8F&Ps_CZ^FV!v*KLLFe3xSw@aI15??){Wi=7(KfP~WI3@8`-)ouR$%o^lQ} z?oK#mGCnRc1o4S-;>ioD+XwPyfAOWUxtyUX(a{Xn^3cmQ^AnAR1-M~?zZTK33&S*7(gZ(gKs;!At&P7^PZ z&tyGB$SmBxDnZhYduZlEusmiu2%?JX$^OYq2Tb>jY$SBOtGbUz9RG}cusO26DftlV z%GTqJRSgSh@O$=CTC~`hQ`0-``&TII>N%JX2erQRbdOLxFZG<(iSp|yRPA#cxb%8? zr{XSfd!>XRO>iAbQgSu_m!>;+O~^3Lv~+1}6!69hgAv_lr9!CWhq5=@A7otZFrI%~ zjtEsxm_NvaNxcXVb3^5xagDE4=q&FjRmXUcF00@pa8MMr%dac5URJm8iX8I;0k_9L#L) z-l*(XfH~7#fDGa99ohnQnGwT%*AEG0Xq!kDhbswn%h;zfy=LYu1db2rfSv~8^pMal zH1}VnzjYw5(pi+kOBpzufrZ%$yt(>{1*W)Kcp?+>BCiYMD-zm92aWEf>;>^!XaIPy z$Nh|cO`dca=-XPdO$5@D~uo%@IXC>qBa>xhMq>EZ>;gC=Tg-8=)8nJfI7{6c4@dl zO=@ia*`LCI^omFMXw#@K>1mA+-4K#Sv1UVKv?`f^A#tHR4w^RpqA1<+p@F+k7e?t0 zjhwM-GC22~NC#z%T@=_f!j{Q$2&t5~RW_Gy`s(HpkJ#0McptN+N%xD*Q1A1??ST=! zuWPb~*A(qJfNx1R>Rf4($aoF|!gU|u)CH$E6c{gMclAf+;hMzgnQa8VXCU2!6!g*u z0IAr#iJdT%O00J*M0kL=K>=X_KTRXlS>{w%40tm1T!c* z%evUi0&t4N2kY)4cV!uc8Mby&t)LyUcg0#f=0P_ui{0~>9v*@I^W>=!iN^VN6GjuA zS(Y-~=&XOXDUyZ&E&2PdsvE7hwUk}GffQPHvJ2=uZC zQnCD)@Psjm zf0u;iTwh*ZO#h{aI3nHB#~+I2upddbGbI;|isWnKD`Tv_!0CTtHB}bEmxEmgg@8@A zmHTOlcR*F=jvs~5d=2%7T-Ehy3(p`gp>}Wg+?Hy%3s2p+=f$~I@-itriqhlM)*(Y| z9^VIf{ht1C22Rit4?0h&HILaT4%BLgVkxLS6e0GQWCp|(e1%UxC7iyw%UMwG{9$FD z`M+3#SZT#h-+=AxG@L)*hKDXCN|_JLtAb0P!}K(ua0d#k;?w!9Up9McXN^Y(tPQ8@ zcA6d03J#?L;<=zjywg%O41%++ymg|A^pWa}URDOABZMoC8&tb}(vS*dr4r6kvdkv- z0&~H?*3IM{gJv6+JG7E5pjbD#dVAoIz~UAvj>~apUl$WLpn{`5>WF6517g-qVjY14 zGCRFhX(T;)7+CN$+8FPu4~RYDlg<+&?f6JUNsMLo+F55y8&M6smXhq5-xsns0U{xo%t5(lH#apO9c2YHm`vyf6rXrgl#%;V)<#otXHP)jQ4qmWB8EWWAq5}F zE?0D0{5JC5^(Xr?GD(ZET|&7;W0#g`K{fS1J&5XGSwX|AK;K+0Rl=Qo|U5VJ|D^P4{+i|pm zpQJgUF!UJ)8mQnEOKXByM|5!L?eM;75Wn^wd(!_1&3Kv$jQL1t1J`dDQl0B?)kt0j z5fI*9DPvJQFQrn#WLsnWhq0EAzFJ{>heGA{7B^nn7O{L@8Bn#MspxSeNVo))R4%^3 zg%uoQrm*4?teJLCYH4@dA}?NKd?hIrGieC4q z#IGYY%?20;)DBxx5M%b^1%Zj@TZoVhCIHnWp97+*3qIjs#cxZ3aJ2hy3cPmynJSz2 zmADZx2pizAE9s%T<7~B1vO@>r75`t@{rgQ@XsvmvNQIU2-tqVU4_x5tP$68Eupo) zBYD5-_ZbTN(I(Dubc+Vd{V~YQ!TJZeDuJ0`#M?An!z4q;7XA!pS>vLweKhNyQC;W= z$ig*)s8{r}+C{e3JRJogf0GV_1&}RS6Yu)C=BNAbCsjCQ8nhfT9Hw2|FB zE8{<_zY()w#l{9E@T=PHr(FS_LOa?=V)#?sQeK&$CP2WhCHg5PH?nt79JMvxmOzyZ z1Kp-B<-TztRmMgVK9=O3(72+SZ~TPNDmqpuZu=OqmlR(uO1pMk&&mgj(lpSxeVdPq z05QA=ZTS#9^-2FLL8qWX(5Rvg40IB{uM>a|?|vsf_>-^E3H`N1hGZE05z-KF7ZUd` zLUKDjz}MrR@v`)CZt*O59|mt(bP^D+B`Y;gA?Kih{N^_bo7WvIsZ}B=+D8Frl)X0T zn;`88CE7@sK!agKv|u(B5UExb zI~dx}1&~=%f!JN41xPKu@1toXCHgBa%4^|=qi%+ON$vmaE}Z#a(9Vn_&b|jH9r%um z#=xH^!}{@Msw32M{{_~Xnx3MUd*BgE@&=SvtQhZtGy#-8<^{7 z3YYUMKS>bt?**yt?!+8=yIg?FPbX$y{3D6Zmg)9UpahtPZiIKUD+`5cm85(KBmjD0 zs-6Sm@&*HQ0O}T@hq%g#>@xAHGhf?|M$Os8%1%c$%9?Rxx`}X@+3WJ@doCV{5)poO z`$j&)b&s{rOtE{aq}W)Y@&E`Lgzl}ylgDSE zH}K61pg~EwxEdK!{Lis$qNCGLjA7_X!?~%QRh0@Tw4pGh$Y1~^=IXqz=XuXFpsY%v7{`S=zE$^Uu(I-H8_oAf zhS5MMRQv@E%?sz=Ma|*n)3=AD0JZ~)z~rUvZS5UPSqYxITxk)vL3f}^E}nQ5t60f7 zJq`OzmF2>^@GD}5MFSr?-lrs{JgX{{YOk+fQI*R&OVW$$;_)`qfC3zxtJyiRoNuod z87T|Y1lP%0@0*NLf`L9a`e+<<+(@qQQ6|Ol7#Tz9Au6;Hb_`pYf=^t4E70e_N2u(` zaS1R(o%ncJJgOd`g2KBRh>>9F^>|j?&jsX!Q6S9th|_nM?Vd%dGDCIKj*Ucz72hHC z|6mR|DT%c%l>&oj3Y;n|S@C_2o%@u-p~}l=q6`lB1V77#r=Gc$t;6wD8YZySD`D70 z$DZ@b7%z}^5+hLd4OFQS&s?A8kwaRRr2J;Eo{>o~@NCsEF6xC&T%4+G*TA%DmDaoM zfUe%UY5A5V7dO#?Zb|Ld1p4{-Chm+*I7A?oNgy0gx*{TR1d5f8Nd~l`0Wd!^s^!tr@U&L|Uhm--JDFTKvJ+R(Z8X@L?1;_)iK1O&tj zxXZuqzl8nLG&^&LzZP(d6mFI?uDryMwhgxHr(ihVw`-15DejZXJs)&(pbA?r8n!^9 z6J60Ma)YTU;plT+K%R!5vjr3q_;L$CP+Q5Fma#DFt8+{cIGE3?Tbp6312KWf&Z&F` zqL|&KWUl08$#)8?Zg0kl0HGQa;Vw#YU@T;7UIAx}vaya{Ms9oWtH&V$8(qA*CLeJT z6R3mHZGyZM-u=NvJSZtUW(lIrTsV>z%F=T3yd>WAM)82e_@&Y_&UyH8Kpm^lj2;XO z8>}`Z_BoiF2`#?`!s+9ZqBGjC?9bPW4vWbx!D=^mqo_;SFfy2)Q}dXdp9(BS>mLQsRsgb{9YV{dnlGvb%S4t5^fH4 zXhQ}VWkyLz`}TV*$LMiKgsQP*BLB|KNlKc!Ef=v!iV(L=X`GO%Vu3&J7+>wX%B`2} z^!2-vs@;3m;9Gw}PPT@I?k3lZ7Z=InW@R%2bdtW0)1UGy5yh+{Y(Or)zo_1?vqs(! zM5xT;qPVJ$K`J-pUl;+1%V65R>EsBty0WX4#Fjy@mBx8JY*m16f3uCBbJcBODKObA z_TI_ZR=q)!T|+uGbcQG@SAsgkjci7p13~G#opby;)*ef~EI>eCRt#rB4aUcV)Q7dt zNv@2sxAV}D!b4fpxlL>u4%z6iLu{AIDOfsQwmHn*1#BT{t6l@ln;D+}{8cP(MqFpZ z3L!f7NV2I8#!TmszRe9&h9LVn-VvDT8trD41%iSk45IZhz3plRu2h6xFkD!aUk#Nm`w5M>tpyXo+;zJSw2xU#f9NdFeQduer)laQWc|k{ z)G-$w8jK>Wz|Fu097aVQd;TZ-EG%6YphFc|S;DewzGDU<5p`C(zP@z@w* zMYGGw4G&Maxd_)Vi34>6V3KP@%QqOf;nyWB z>3TJmgE}cGzPF?OhnBAqDY`3R9r(-9<007$JFuY$L-fZzEvEXoD8TD%)bWu2zgbi` zbNdrZ+ufGR0i0IiLV#I(-6A?<9URQmuXnOy-FzH9@1DGLu?{=^_W61tI2vr0=IY0E zS|lMOi(jQ2I1E=0XN&7t+wYSTlCAWwaC9#8zZKf;&!+*YBA;tw~u9xp+bOeqt zsIcxX3g6wZ@HdHDmyt8CSpc07fkjR}xg;T42@S_ecHj?S3K9ME@k(uw$wp*hl+b_U zN-WuHpKS->ODaFK&S4Qmx&rceR1Wh5#0(3QVM8OXI*tC_NwYz55bq6ge_?>8jxvZ= zJLmvO0dkF!!Nj}GI`R;6e1Ulhim@)weUugv%P|Ly*`9BScbAeWatmJnMn%q8t%owk zW{#AZ<-yX_ddZ-6zK5M68xccZX8f<8&D~9 zZbTJj&AbTJ@VM*Ed|M0CJT(1S5(Z<{r`s{uO!1d&ihPL(x$|B`>-bI$WXd!JQUVH{ z<$}S4l?1XQcyz7>tni=_Ls;%*MJr|JQaty%sE_+z7IKhB+e5Cr86HG=`T!kKctJ?vFZj%wy#-l6^FKF$i(YS+e!dAm;=8jFfRL&&XuiW1%(JwSakdJ)XM4e9JZ6m8yi* z`j76iF)C_CS}2$OYuswt=rdu#>`l=vM83)w5|022L&W`l7?BO=g-z4PTpUozz62}q z&`#M)MSSKZFEqLO6c6vp?^y6fn&!G#yV09{Jx0^l8vrw<^I$`KDF4dI^ygr!zPI!R z20JNaIo8!-$J&6EM?L4Q4(=HG*Chryy>`dy6YYk+%WgvvgDFQT?DBp`146%dmv4@{ zvDmL%$I@)PMwtTjscwS_W4#P)T7G~PoiatWAyn^={#dx3?RU zRy%C^x0d90@sb(8+WiS}ysA+j>CQKdYq#vueDv%aO9wyao(eSA*=gYmKw)~Zpx+kG z-h1|H+7^3-?yU|NFVlg%^3fST0Hxs*2`A4cYg#+U=mufKjn5Td*npcW?an%-*!P=wUXK6wSlboI9}3fhlmb{#I#a%LZ4XX z34Lp@ygtH{O|Q$otfrjOZYF|1g1l~;ZdiLx>^hyl4P_!{Q%s>jgi34>hPDAv>s0K& zyCXf(4@aSYJKkm~2?56B9uK@Q(-D_o>cJ;i1WHXhuhKYd4*%mbIzYudd{_J`boI&M zWfSi^`J!laJ{o z$`KQdxm6yPrv>Xdl-0F?l3Qg~ucPYS^T@UkUvfE5i}j^G zwqA)|Iu%i+xt zsGn6tLUKB5Od&72I)=mP2n(ktaMVQZ+t0x2k;ltc%?1cGo-0}EeguPCzR%0V+AlJa-+4G z6U-7&1iS~$|G9k1@|;W2J}eP`9u<{c**%4u>cGPr{Q5fjT5xPnh6r4@<3e>04fdNitJvNh1dj;uhMR2Q|WP}Mwv&jUn-Ym=xo z--i?Ya92ciWF^+}cl>Atd_&v6Ln3i74^(*IlS88g*}&9-uM9fzPORhT9F|}h8XDaJHIYvKOU#`?~yNZ_DPFBSFq-e z7{8J!;uhe*#zhg;BCRQnRv(@y4V-H?~*Sg58F;F&8t;)&fMF<@`as@UHAaplcO=OWi zED}KiRcr-OS3?MLH2e(3v<(kNM@69kF3SNH3JZ!RK>f|<6cNZI*Q81E84t$6VOCR31*^;gR5^W|UZpklQx zntASMi|$I2y`sL>JM>j+La+DioJ!RRE`zN>y`H^P?k&-)KFyu~w$=aCo7B3O* zACYnmk%;#A2g;A%MAk5tKIsStdAxQRiz$%1!57tYQX?ghZ*?}&s@BY>x1cjAeGlAi zOYS|((~`dIMAC4k$MuC0$u0-Ij`~4iApFJ%evv`Q=t+A5 z(!js#P}TOIFI3_2qNx;biSwXmkW5YLL7_6&5!Gcwjl1(K*EVA@s)N5+8d(lD>g`2R z zy~Qh8REU%{t0irKXO0;srM(7aFzG6dHr!C&eQD<)Md)d>f}}?h_oFZ?2ZtD8cG!iY zT}d7=FK_aQeZw}>%#@^fMR=T>=`gv^V)Vj9fC$zKCqGt6E;N2<DgMKRblG2jLlU$`=^h{OL={0zF5mGHrgxeiYcd9J8+PB9p=?{@ zySaenf5O;aC-o%QuZvZ|7uwr1?!{+oOf3VzXozFi3H1LnE_(N}Uf@T+eHR`!^3j~Q zrZYYjr1CG=14bn38lGi>P8z?efHWg!kCtK(J}{c&e27<3rZd31BMfJI4)rtz)wBQ> z$4y;XqkH+Gh#FrW+{#9DLXSLR;XXa+Tn6Y6!TX4>L2;aDe)_B7cuCZh#3X7@e^j)T z3P~U&atLk4dC8|vx6EEej)ZJo_Yw3cT0lUE!c=GDDdKFdqrA7}6(|ck^y9^W+4G+= z;slgCe#1jI^+SLp!>z^!z$kxQJFlJ?2-@Dns-2lr)JL#iZz2IaqZ2Sp)qWILf&o)H z`t6zx5CT1})iDoLC27rb*=w9~5rl+{esN{OumlZWVsYP6VeTWO2u>fDws~RH@@n+6 z%cP4vrX533W`tt|ul`>sT6mIg9J{Z6nmK?b^Lul{&=6nXzhjhd6mDoNU_HKw*E(De zjM2E0nW1FJIzzBD_An-+xj1^y&x7)Pgl@$lBd4x}a|hODxeddTGIus4adq#tp;Yn7 zd&u42;^d_OpPWbixFsAMe4Rl){O-Q$Z$_-36L@!=nhC3eTeld$NIl>~op!AuK9Be2 zFdL`|27w+Wa_ZJmfm}jw*W(t|bKsi-5I@4sDX{PfKX)F@>`Gi!l?Tz2xk}{PjGS5C?K$l{V{(<+k*WnfTx|%UFpW8evyRn8d&uK$zXbd>~*|ugIlo8D|%aYQ6UC zjEr_hq$=WHA{_S{Du#5nt_K`07*Q&KdeNhn5Ecsg$eY9?W|Gi7U}_!>Hu)rejGWq5jr6Up?AkV$z$$N~9 zvv#Jm-j^71o|{CA8x$i6($L!xm+Ht0rI?#)v1LHIY1%~@iZ6>cyX)aJYPP~oB-@x>F%y`3j(Mjacaph1zA=4p+(ngveV5*xi z+Xg_R9jtQ;xhLBAXhZ?PUU`FV5AX6*skZFJrY2aDNL_vRrnsDdUY@i1@oi+3Wx6hH zLvx>}5(rZApx!$!_6pnHMhLu2Zj}pHB{5*m+Dz=G#0Ff#8WQgmuYwatlr*l_Z_ORS zbSBIEAth@dBE>7SVOeJ>{*zkja>uqYot$c_(YFFDiE z=KV?nRToWGY0#QceMUF~r^pi>{IBH|bBF4KJr*5d#jloZy5DP&|0Qu8JGG$*$osdcK-2rvNb40T|_?6ZB!Iv0{?=|8(BUn z|AR@ehJ~oITD2aooy;$=nnPd&qnTM^Z}`EHhKQ|U#>e85M=M5+Gcqw|;r;NH@Tw=H zGEb&KP$UP52Gw0E+5_#tptz>4a)?#pnAIU|06L$0;jr?V^LefL)qf*A2f%aia(OJ;Yi>A(nt){W{{&j2k@qrc>)Zj zihAw{o?1p(MlVx4^p-O6vq;|lW)C9`w#%n!pCDBmoW|>%aR{(vX>(24HA1PqwDZE8 z`ftJ%N$^fxaR4XEt@&o@b3}i^v|()tnF&M8m-D^-W}$}F{tqggj#LKh6`i&Fu?tlc4>C? zxH_#YI3PF^`UDHcN5(GEF!@7)N@jOW?T&GkMUOSA>TUbNZy!&YUn@IFCPGnfH zm|wxf-khPGkghtxC%V(?shH2flGlq{$!ksZNM)7QhZ|l=THpkmsrxlZvMdTL2@+$ioC;CDl2HM{r$V?crF z#yPE!=`XBf9EBN<>4ATTFTyI-&_s>)#sa|OF#dbQHy2Fw4o#-WIK9pIjY}mEn&BA# zwEXpma%!L*5%bb7Ka6dweG>o}6Jd6BWM6Rb%-y`));U&|`1d7jGs?Um7f35}XQ{dM>m!1#s5I2yHlFn3>DWb*c;QiB4OU7&F zX<^aDB9b>qxSlaQi;f_Au7f#0kBwqeKY5F?mFTFS#ZTvS7f^4CU zz~IWGkih~{#j8!wxMgwotl@@)CGczR(HomI+&`=@GJe<;o@pALr&g1UESOS+U~v_y zXQFKAJ7<~W9w}R8N-q~?h8c9$7}Uk~HG_C>Uk`fzd({~h%ml2Xf;g(0BVP~I8UV#H z{xjUJcSuCuY?7FBu(Q~A^7VCYkr&oma$iRA?_tl4R)tfvE_wqX7&u3);3MW>xjY2O zUv9LeH4Y>~^O>&#D!TzLFV1m~!7>-&!(QB^lS$LUfcTjj-!$@}O8dOGFC?2!QYh^< zRguB>_7@Zz|I#Ej#uiOuY^USLUh%=)Zsh4;na1S(MQjXOCMjH&sTcrcptu1}pV3p& zBCmmz_W=ra)|w;QrcsQ-KD2j{pvJ*5D|Sk(C);}$*d9UgRA)4g35NP^8uPpf$Luhd z`d-h5UiSVY)!_-#@hKl`n3>j9Ta6O_F>%CwxIeSkCNR9or4`tXBX=<2>xxhOGbe;<+q?DwwEO@p4e@nAy$f|MpJbF%+2mI~1b9NCGd% zn~5?8Pd{7LrZ(2EyQ-st@A4As5QEiP-zpSX z0Tb{e*>R8pQZ)UBb)gA^1tAvxpK@h>3XzyDrenk-Ta8l&H+4tF`M*>_! z?^F4})S+KP3iuC{+Bm_(peb^`pQ=67uE%220(T{_Pl+WpQtTV^kULI~1cJ=qTMOf7 zmR_E;x-HTqyKNW9o<3ooV^;`iUp|2$vq~uLp$qka^_DialD9crJ6|rL+bhMhIz(eu z;z8eq;<=;M-d<5OdPqvwgC`LobFu!bhhJ*J4U=ss$^epl094;o8E?YGWSrTV(@h?T z@`b84v5R;8PEAb(_IGQVpE8*Mr9SM|(|;7c{bI)3`T>o-a33g6vD~gN{i9@hZDm83 z!k|Tuv!5b>{Ep}JllSqv(_>92=?Rn^b9Y)zXfk(rc0t{>TLBT{q&mHHh%e zjn{Am5f=Lm=^5KF!M&rBXU@i(^akE#;oXU#G{AeE>OB*JMQm-%6+k9FdfE|Pgq)|b zILL8Gpa}e{Sy-3SG0u^9Gk8xcO39DcC*S1>QXD6nT-t4lU4WcsI9b@P>(k+% zHA?1PokG@+q~KSABZA-a04ndTua9}c7;tOi*RW0e010aaLFbRt7iE7Wvhwl`ZCHIuO&0I7|mBYWmccD%1#_p1&)PKxh&*Hh!4 zaBD+5%XkvD;TB1`uf1!l#D;>u750Sj3M!u?Z^Ay)BU0wk-L2KC->T|+#yvsCO@N1> zS5b2igrdq1|DViYodQE7*5QcWppLpjuZI3^O7LV|P6^tEP(+hD@_0~T<7gsn`B@KPD{|&> zXL)*Z(=kAf6y{e+KLl#Y?d~|DJ7i0Dm#%gwgUozxfmggKp8*Z@Yac)lz_|tnY#tq> z{h&IQz`J>2WI({XN?wvGP?@?+@iJ6(Bc$Ea0mS2M>(H}P1I4-f`UI#+KwtH7G-==3 z78}h%@bq65vdg#;yHU2TYY8j1Gk^H*Bu0==n%8SybL{?5d4)x;kD)phT zrh&y>HJgC2o9HpSNE>`JXW24EC}Gd}IG0+c5QOdkfM>|>3s$>JA-H8@Pix$)VVjan z#}LKA1XiA?*|1S&8rfd0s=Ss@V^kplE=LcRSl?hEWIvw;$Sm9Adh9fP{mL#wPS%Bv z5Dn9+0J1^`oer&zcu~DuqDY8RqkehNU~8R@$5;i6Gt;=7$K6zGi#}iSElO2kk&4Hb zf@bj9P#eh){i<>}r3|SNfURIs2pZD;4tC;gfYM+)7b!;@BX~wv?pexePlXcTijwBL zcX`Ek$BKXp$Y1OaBhdF%0-%z{oTf|&S}!S?h;-qAQj`+^8`6l+pddn6K;>0w-y_iU zMY$GUHM}F~tV962v>01&G1*W&(%HDAGV6q2IZ=bi>d{KG7BTk6$Q{Jf#6y3DiPV8A zgJ^QCr;CspW5BZEGJGO@P&i3f|08IjAGk{VJ_Ge1cMyws0DZ850=-o;Gyi=$^ZT#^E=G0>E-FUox>7ub;a8dvHKLbj5wGbu3;4{(LLnGs>CALN-D zp=S?p*}eId_XtqpXAcVch!H^5{FKP0axWSvW2V<<;;}RL!g0!e1y8#K3Ap$wK7(4K z&wzY|3JP2tR7;2e31vI`B56}fjlDOrLE`2Er1swy^9!l9K?W7?yv$nd{N%M`09`Fn=xni#?2v%0dI3>;%$z=q4E2ntn z1KI{h{uji9U+HieYf=f$DwvQ_nk#xY^S=7N$!!(=U|5ADw6AFLy&G#WA;=2gdEW{L zY};fgb%DG8B5PeZ1{RsT%Z5w?i{Wr+NseR==Sf9uqf|AHVQiUPq246sI4;W6?NZMM z;@?xpwrg)j#)~xZ zK8o|ZGKC@8Hh@dvti_JvwDrU}wtUyG`g`fJ1=`1<8{VFx#MF#5{1@BH&1#PY&qMd& z?rLVNi^bleO{e-?H1SrDfIjZzw@mmc%1K0LnQd0a+_Q@YX{IZAAnX!~PkagYy>T)m zodx0IRYhbz1sSd9@V{!B8xx$)aWyiVu+Q~Q(1qeZ^t!bz)HUFxSz|8C{4=ZY;WyGN zzz=bHx&p{uQEinABNngQMR3Sh*lm9gK*;d1(Z_nG1+tK*i6wi8XZ7WYkPC>M7$&+b z_*DS+Sw|!q3UO=xZG~=PF>|kz!!a#S>a;ZParu}N)Zl?SF}?{jIVMv7?>Z>n6N z@I~Qd-qVbgoe~I0wiph6(uUwwrtVUi!D_vL^ck(3+XO2-MUIClAxbG;3#z_tBcyou zQ3MH|X!M|_kqq9h4TGsFUsb*!K!4Fs-4G|8Sg1hS*u6v4=Px!~C<&ckdPZq&@uII3 z)a(&UV3AXwSbkDNqHQdd5qi2$OCF5LvljImAaON!i@ZjK^Xg}waBY$g56|o(U}h=; zY6abSWJipJ!8qI~dxS~+Z}&!PoP_aU@O;*3iU^)FBxK%TWJ%cyO`OO|CuLVYK`SELX$vNm)K_Fx#dGd|RMGM)x#lWYJ$G=1 z@Ep4~juXMu7a|&KQ`L7{@p`Hj#qN|;_9w)f=z(d2x0CDPH6m}u4KyB$Ji^)N+ArRs zRO~CWBOzu@jml$=VOOu0T6(Zfb=-UwK2@Zkt4mbabCZS<2b*@st$q(bPtaDJcNYr; z6Fl0AA;R%21Yp$TN&J500VBp3MMBq-p_zWBr7Xdd z9vR>=Slk}}eq*dg9bL?Vz`kv<2^Nq>+}7KT$^SEY9d~C-qGV)&^5^KRGqrSs1ZBGj zMOK%*Kla`Hmg{xih^|}+JGhmhzH#jZKcHHyg-N~?^=U5tNx(H$4Yj*1;kTg2*_w}Sy@omwfQo!y=*huhF90l_4&5j&zXKx;ZAK#aoT$9&qL-$V| zZs0fUboeVwuMYkG{uG}kf5tISaLIJx_0%Fz`y31;cW@3skd`>!$FA@4>u{$tg3m&N zXv%*%g2VCkb9DA5$h+pcO1_T)U;XL2Xe-bS+-^4l=#rQ1v|Lnny=`VsY|rTkqW-$l z*8#yg4GOfxH$=mJCZ|JzmSiqK?TElUFO9Dgad3@cYNP8gdd#?9(dO&aIzdwSz zQz>h-tpC?u-$UHl{81KzeyK#Erd)G%5Ua*FVjfclr{68K6)SB9A$ZGA`E0@iR2JD0m_B z!7>D~HlHlf$NOynKS030r(?Pp4i;Zvw9iZR7|t`NB3DmWn0lk*M_VZ)nKCBQe3~lFi-aM~p}K2Z6u$NL<9Ixtd(&zdPLv z|L|#F`?Ny!$g+QTXq3F9t(hntIGGFl-1c>PoDc5w8IWIacZLI`oj~t%m{lI$eCKc?Vf&gIYqL^t_jm zxYD!607hEsrAy;SgB|hc{K`ekh(U-%4U6X6AnJp0zo>P?r8F>H)wEx8lwNUUt}bKH zU7zz)(s@0psjJ#B-k&xMY z>YU3HTeD^i<3_0}K~_5t5*pXPFVxIv3T}~u8sFXKwRnb83b?@Pnf<2b+C;O{Z>luO z^726XHF5QGB4{nwJ&e-#`RjWXxxxd7P%44iM4+AbX1aO*ti+Etn%dqYB_tO^q(0J*dVu47AjOTmU1DdMtWd576okE!-(q6{BaLy zZ(^k6pPCzCX){49TTQ*RNWdIue6{jl7Xp6C*5%3+!Dq9Jq9w92(xE(klPnjfbodMC zp0Opp-~=L#$_(QWSi~=#{VS9@wK$oE5z_C2<%GVcgowwbAc)rW^f6v7h|iGg`fTxU zl9T{NcQQ~e%tuEXe@q{atg}Ax6idvfASrLNQqxy>+0A&CV2qkg8hc!3_7O7Fa2sY@ zzA`hlWPu&)?y<5>a91)|D1~L=%&7I80VHTd?eTXOO}exrV^ikR92Dj9vjm*FqcI; zJcBJA(KUOryb@~5K4-%vu~EZ)hDD>DS3szqhSpr%PX4`s z&vr>$9EZ8Kg1Eh5Gk%49B1orIcd)}_N!-rh@r{C9@kB((7)8;LWDw$?%U+m$7fOkp&6*>==Iwq9MSLtA z$8WcS0~8$IFPq%Ow>dw+Rj-J)RhtA<+tM%BM^qw-A#8+?S9dx6ow=9oA%mr3rvfPp zQ_q858OdWK00^SeDQO?Z5Tw!=FeSR#;-a?B-Dd2m?0X#m3@BjK9S0>K%sO<NyHA z;HC?KejH7XbGy4o{Qi*9HA$sJlhjxIf@jYQuf)`j`Cc*5(ib?Wa8DPI;_1Rjz1aTo zvYUf{RH_7lvIx~lg~Czc(Cw0&3EOMCUpg{+&(G%)sKlURvQtS(*)z3n?@y;NM6c9n z!=rchF1`8Z*maEJEnV|WnJLVa@2#}{B`G+DR+*KLyaVO06jpvRsmyoqz7`3o7aw2E z%Kh>Bn7v^cN^D2sJk7ETGjgXJqE+BsIXvpwY8>bfP^5>4)WzO+gEGuvcvM{@x63cv zB;K6P1VeY)c56jLegG@Pl&9&LzZZo8cLSO5t%!D|G3bPL^VtUCM938SG#>(uYgV(g~Y0z$+hLOrX{`SxhGXS*p%%oJ1?t}>IElh1w3(AP{ z-4xwP+Ma2&8ac{UvnX{S+EE@ik{~i(P9jRsR(CFaW|`3*Ityegw)W85!OAUztoUVk z4JzROod*8sPKJab^z%>>oOB!)(2&&IhSjM@pJvf?W7u4F=-yC+lv0_$*?Q@Wq3S9v z{Dd`?#(bU_ta1GL+G8{RsV3{90CwPAyH0D;LW^@tbzdBZGqON04gKy4-z9ia_iXTk1RE}uqjv=3MJG99l+~h`>fUVfgksT z?0C3PjR(qi0YURN8C30>l={hK%uTi^yAsA5@W3I!fw6m}kQHro0YwcK1E&aHKfE~3 zX|n#3%dXU5?vWt^j%=ZGO@y#sI~6N_@8I%LvTy#w)NdIqCrh#y8i=;YXxy3n-9z*b zY^6UPNnm$bs;JDoGcy?e($Q1_>e5Kb`T{;Zp5TFT|Ke(tC-Yf>xZRFHc;&V>PtJK{ zD2#wcklX(gV;r>Vd&8~P&65qSH2XsZkd`Nk1#D^u0u^B^{;A&hl-JdFst+4DmYVVc znfPtA81U!v->b=x7~BKS9AAhC9%g-g_$(FA7Od*Ws*GZ{pw_S-Z4Tw;!~$IxAUpr1=5gY6dxe_r$ybl$;_pcIsi^#MpaD(+7ubK zpkKsS&j}f%6mxeO(3&@Iu@F1m%jNAQ_}vXB{$FqQ@R6aVF3O|4jNY@?^m73`E6XDy;{)s!LX`e7l^zU^OTNp8vF zV||bW&|2374yZ$pGR1{q*muXgn?B=if-h6hfpO~CeN3;CiS6hE^Tj_<;=5XQi-wZ} zihbr3z6Wji!AVu&JcdPRA^)msH#xOcQ^zeRL=h>yZ6m+!_Yar)d|`trZVLf&e>C9cuP zYIeA!pwwA}y%DEbI5A-nSPHR-p%JiVVfCTmagZWDJ1QJ;2^q3!e0VTGN2@$%U~1=n zWI!?5-WQUd`w{kF(yCm3|DHOr!GQ}@m@}xTA-HWB3z2b`aU|$oubr2z)1)|(njsQh z#S|ZE&e+?5NnaA)wJ+SU3|AVymk&3VGojCu09UqXxPfyfHXyUj->1E4*4L7UwteEC zW6gziC;!2RqIdYO&Z5Ke)cZ&=wtbGUA^w&GvrYI=lQ<~utZb>;dQ^C=2+YuKF=wmb zCHv-{Il~`PmTNK$2B~jh4n%BD>no&~x?WmB7q%{B4RkpUlXv11N^jPR}_F(#uBMqI2P%X@AF8LB0j9*v);cc76G;3}naEJjN z>)25@%3K|vDm>_;WvVW?IeA7~MQVaH5O*CK8Lgvy`oX&5Z#!1iEfDsR-AMUONa5?{luoF#elO_--Q<=TdLRqMjt|wh$|$75XGZ z+#lC{#;x^*rXS%QF{Cb8Z7{r(O1Hn({r>uUk<8BT+tAc`m{2xl4c5Z(+*8#<*HGqk zBcSd^icy&yt|qIwAX#(uY6B6V`x8gTsNOAnDEt)xlg!-tcNt{I( zEOmq0-G>V#Vbx%O!lg`@P0mSaubEg1ZP0)DzuUI?mE{r ziy~l=97)7cS>RAbB!vXE z#H^Q`G}+1~%bQ$yXDev)1${aw1EJN*jV-x=AU>c<4X7oz;!-XM=~G_T7JWz?3kC8!7Lo7bwTbB*O$XS>mola`(`o&{tWP|0I z?OB-`UTnBffkS^uS$^80Sx7_Pyl|Z!5{_@A6syMjybzT2xSt2{;uMCHaWT><^?}<% z$xezOB}sAnHZ`C>sFctrufAgZQVlFntsQWNj+`rSk%6`ttQ1frDh0~sMW)WI z3ZCSC9*ROU;Ofr^Ymp!BCNtO=OjO){*t1#_D1u=Ht0@0PYAFUbSQz<)0*(roz7@%6 z(E(vq?6j3q`b%PmGp)U;#GR9O#YK?>s7+e_>NDbx=TfJ=R7tic`zR3x>l~xeU?^}t zP+)})TmVtBAuMK%iGov>wny!#wu3f?u{Jau}BddaSrPK24h#xz%hWaLH9R#pK`YWfl10T@@f*_f= zjNADwX!$NMkBtV`32g#xr$ip*Zx`@$a->?B9lQsXT(dJT2i7{auf{zho%@iQ8{RZg zMi+fqG>v(amb-Lu19uhRqQqA|zf;+!75=e^@9$Lg=+H9}a&aCY!%V&5!s)JCq-%bR zgK+A0iTft#(Y1bwi38s-0VEP(0P_ElvcoJSUA>Kas`G78|uoV49y4oC|xn^{cJcJ-)PC(I+xaPB-z0 zmv?>W9fq%l-#y$zuXOTBxX!(!RjcOC$a6FHQv@h;Fm@@>4py%eo;&d-THYVYaS#@< z#}d50g&3$x`h@NWNG*1#=16Xgh+|Xu6Hv_9PxM2r zaCqy!b3p)&xR+7yVSZ{xN^e@xZ8S`=)wI~rT~zv}VfVd&v^qU(LFgmIdGm-%EHLU& z?hD698An*e^)6G)Deh{RA^=y~#LvCm_?iEfqc=TwVk=)C{@4-VKE1J!9kK4C8+q6C z8cAmZqCqd3@7Ijtg_z%9cq+p-V>?g3=mr6=yM-;L-_ke4c993C_<&02;ksBI3Uwl+ z(A9h(01gt;-$viIBlTV)k!f2c$+v))g{~7mN36zM{^2dHM_lvj)hmr}{8KHwwKd4k zE_P5rp{N=NS-%?CPzo%0IXDB1!Jb&?_h59t>X^(lfk$Dz);SdsYNd!70CueD;0C0! zqZ+fg%y}Ma0S*vEAp?JM#A$hPHkx{!Vx?jkIE^+UE9-^`NWWOL(?6tQl)>33A}W=x zMS13Gzrz`h@BL#0=jqfBOPIxxhG5Buo#MRu1CJ{C_oMS|>SAIF@YM=HGd-f0ToTcT zsMPF+^S&3XkQE&>uDx4@0r%v+YI?4WAZjf{*Ecjvcm|&>618Hlhxtgh0u%8>hm?gn zjMI_kg9&w)KI{@&SLvls=x(pyGd|l4nkmQe~bag-q_xm~qM<6zt*cYG84wOAcdt-z}YGy?cnZk|d z#ezRzE2(y4Oz}vCvaw{uFozulE!ez+?#r@lK?m9Du>hu9?h?v|Lo8z~T^^`Oh2{Xz zPnMZ*a@X2}q#igU!K>iZEr=c^Rp1v8_Z0yJa4=PN$;_gu?%?vV44R89Gxn3!;M4b= zDF`7cw*4JT*`;AHE*k#b7jn{zxrykcwxbmHaTUJ$BRT}!JNI3FL;^O5f^*UrR`xDb zDACUKl>Atdr!Tn0)Ux<4*|E9JaJPA^k~KQGl_XF?2Y(~J8eu7CY$dILSkDJJFk99t zt;_p1+gDyV)zZp~d@Gwfm2A98OFggkp4fNEdO5+@ z(JBk)E$AAm8jh!*PKxFIhS0+t9-t6X{3DQS7uCs|j&-v`^5J={e*K-Z?>mx}09LmK z1By$`KX~6OHFO3ylL}|pd<^O3S9sLWhdm17mcn##`XO7zsu|zHfi~zq{9nS(ni?@7 zs(iO?8A*}Zfq|s38$>hJUN5R~6BFt+y4KU)0z->b;~ds-v4S;wj7_N;(M9QJUEAm= zR8&Cb5^wNReEotDp852N2Xe)$2d?3X&mKr#dBAS0;eE~#?0L|5fr=jsnPM0BRgj=M zj>0vq{wxc`0##&c3HSC-xPpUfStq_S1!2JwZdh?FhK_1SIx@Fm@{C^+tVT6!%4R*8 zuWQ@}gk0+fcX#1j*$t7Hz}t7+8Z&Sllp7pDQwP7 z?#W;38`TAIAoi74>rZ=2zihGHlfp8}Z%O&Brn^z7_J!zi4B3b!McOXc+2wwANu|ZA zNBs|Sj}%Q@=Gk>MGLlQWSIH8xaR{ zmshK>723WubdAiszz-q!ZFBhIN;6mPLY9*T!od>oVh4NLRy)@ZVR_# z^G(dWYQKhwc*R6);a^vjfbrKZ}Jk{y>yAoLH#(YeOiEdY?mzx-EC85o7 zQ`}U)@`;^uur)g1-rOik&0Yc-!x}DLK5h|Cs@%p>=(7@1KoHM?{F7dOV3a;ZT5I91 z*_t3n;C%3{YTC+Tvr8_JB3iLgat%&-9G*s>p+82I7*a+))&XZC7hY7g8njHh$n0xP zMghroNF__Wt`5=EP#CS_C|NXJ1i95RAkqD0$5lVwytX=wVKX;X{s@~z0iUzOSCQf6 z)d|uo=L`%sEqX(58N+79geY&cFRnx5Q!m!V*M{nbp8wWZD^8c7$~UECMg8V~5Oj>b z1Cd<9zK)*8C;~aqlelaML+UDyQ9!QnOWmudZ0Voc#Jy&@BW1@9$(>LB0Z6OIo3leP z+0E9Xp((pwNW$lBu5=U*xHJEv;p& zGoBy)B0TY5W?U?$%sz}_~Mb}fy2yiP-LGJ57t>_@8IXr%#HhF(qo27e9fG41RNX<-B|xoK18E$j=KzV5&3hv90e zJRlwk9sosr?fps`IjbQxd%A7Ko3^Bp(ax}TupRdT>-Uv-U6$cP>doQL=Y%!<;`jLy zMfVV+l^M`XB@B?-!1L1dGrE_XAJ<)_^L$3*_QPpBF3cBjoPW2yW)6c>7^};ZoZonX zc(*IhbgoUhM8qB>7G%SRwQ0audn!!|(pfcZT52te4paQULin2I2qSlu2ORC7`5*3s z*W$bw;qWYO@*O~A9-WGnQBr$WE)o0LHLJTJ=K5Y3ZclA4};oqW*5Haz7;DB zo}iqK@4HInaZ0;Wy>sZ%tEtHJ7KK<|K|3{wOahX;(TFt9#vAMOQX!2yd#;H3O(JJ^ zCX@%kG8dND1hWM9({)^5)j>z9>ztx@hhoD@E{BJAY!-#@%D2vbH?!GOE&e`ccJAQ6 zaa8M^vGEm_+d7jkMjV znV>^iCo)l}UEehl8vS7fHI8uj!+6i#J>`4U|L96n7c1Jd)&OZDV~6wFz!MPq0zo*u zxPQl>i7+mEcNt42x)ynCjsG2N(Q(qFJ9PqX`=+i6?p6ART%OODy^ixI@gAPfUF>oj z{jI1&t;@S8F#6g$WkW>@uB>b|bbj=@V9UWD0p5NaNB3V*TJo<;z{E+;c2YG>aYsNyXSiSvfXnwOb&67_fg!0k8_NGswD$yLXt3ETMEdEN+wF zZ}OQY-R4=gG$J?Nuosh?6mH8WAk$;yFQ{+{nPHaAe`fiY&sy&&eip5hZ2l{$&j$hs4=wNLpXGGCNk|56>X6>B(`PyZN+x(VJcjE*Mz zgs`;K6eyDod9Lo>l(t1oMPuE5!Fwc&sg%8RQ5_4u5}c>F!6mu<-gItd}ka3d|I+o{sQ%-UsXi zy6^f*#`GJ_A@EW$GZcddr&zmqcn46H3w_ss#ip2Pmcg|qg9skhdwU18NXFhIya@2r zszQ8~nN&`+;u)1H-sMCLB9FT%n|w0RZNAVHd#+mKR7rXDu79Ekp?~gnLLt+t#6NN!P>?Cqv%nqHWXa|WnV#!Y-^N&NQ#c5aq z;Nk4VqrkWxk$X@fAAdb04RkLVCQnxh&FnJwZ{V?nK^tBrFT{(hBKXdRF#+l(`=b`s zw8wB_L1uC^SeyMt3oa6|L@de#ML(#W57+cF6ET1(*Go=HQ*-v(sKGBVN|V#uw#0fo zlp-PyxX4IubnaEbLJZLU760|w+DgNWlwr~|Flq@IYQ;1vmQMj62nuFElP}J8J`=-+ z-TQBks)7;2q&kC)2t3xB+&};o*wmz^KM`XlGxOM|1K+kqy#!kXCJUx#@7ZB2qnyFZ zU`J;2gA(_6&I2EhHDatmNTpI*zK0RIYC=O%4olS@Kh@Z(%l{YA^@OS}r|>;r zVUAbxVbgXxavAw9peIwBKVh1truriG&${LxwvGtgLr>VTW9$66!(bk9hMBYqzI+Ai zJ^~)dSUE`q#nF0bl#%hm>!aUC8>Aw-!SS5;f4zj@?Jq!O)wc)x%YpA0&M(AT-3wJo zhTnin|GGbEPxNI(1n?tiwU)Ow-R8SCdn@y($l%>$`mMmQ3%*I5*}ZZyxlRJn+_}BA zOr}Xz9Ut<9#-Y2;YNEZuJ6w|)BfDP!VjH zb5e7hmUs!z`bV7g3Nc0XxoENx^a^hONbf9M~`tjLeoFPY&? zMj+<*hSuSS;kkFS*b=BL(-bNr!zrh)+FG8qC+6I4NecRY^_3c@?V_(u7R>4Oys*H_ z+#O0_yts~ocGU|ch?B&Ki`8z4{I}^Zuz!J(;`WT|EWtV;FdQm+;Sq)X~izAqlVlZtzdMMi|OhRfiB)*Tk&*)}^$fLOvy5Hr%B$`A^O`ipq z0%$dyGwXYh^~*aR>JL@&*|LSjsR*U@sWRD`q$e+By|A?(0M5FOzV42qVH+|)DSw>!mL9c$W;kPalR^OShHu5xAB+)dolJsq{lCCm$8N~g#BnN zma&cCy1>`^pK{)ZQ-57i*YfXB%)~0#Wk*tZSm0V%xQnSp65R}p8?ZG^9~ag+XeF-; z)-68h5nnMP&ZG2m!@K))g^8aqT(44YHPg*JnSszAr2c>I><>JCYy2_B&JA~^8~k$W zM<>(gxbo{FmN_CY>5GmcI+ER#;m=@758Xtn+RNK@*?j^0R)J!3ZZ&racDax?5KrPR z%!|c{=mol;X%=aV>Y;Dk=ny1F7J{0xxx*VlUzhdTzFQJVNnr!$C@06qC&o|c*(lRj zyM1B|y6~xRO$j@y#!cAM68dfK9K5-wlIPao7Ux~5jH4r;yVUx*WWj^?x9To;s{3c4 zj`6;*FQ=Dp?z~V|1te3siH%qC&#=M$zv}3VTV0^99kBL5nUrEo!Cy{$A=@+Fl8Um! z2KF&{eWX8<2K0|O`HZDSLv~R=G(J4WjuWa|VeTFydUtR?JOXnoJvZJrE;tl8!=m0} zJH%Y<^NZ(zBQK`jyJ^s?AMPiSeIP(t&!sjDeD~7fa52NOmZ~U&#@e~b=Y{=)6aLE@ z`*y6eVPi6QX<$AFc6j-QRw zdve(RZzYh^Y~~oME#G_`oOD<`Egu_A%DKqBDY-Ioc~AqmebQC-C9~K5LIpR>vjUzk zHPbZ`Rs|IS>0P#!ZtAJGv#vhkvEz2m15Wpc35oZTFzBHaWU8GBYL&1{LB4}$1PX!{WC>sa0 zqrvJ29*tXn=JV`1GcKh-#QJ7%a~OL$9%?E0SN4L{&0)zjtXKzOBXupYRmZ-~-M=() z=Xq&0Me}s`uj;0Y*f%>pAW#zAiKH|8hxu6LG#fd+F7Z|UT~%~2efhCj*Up%B6un7@ z#_ar_GC3H`RCqh6I^E`8lC=f*O}Ia?fL&{IdTSQ#(QO>y^*gbbP99CfG;q^XyTuk4 zo>KJmn9H45vunG+e#LA2a852wcT+|P%oS^H4?6%TN|fnXrakZ%89@PrEKQBTdicDf zMdSNG&l;-g=)TT6KqWPhys+&I!Au*LigL;QF@$*0CP6 z%h5am>!MR{EN^+DD6G=ZFg972-{uM8|1oJB15F@M(a=jn<&!bRY%$x^{4`ef_HmBc zzgvLY-Cp?gZ5P9jbelS~#QuF5V_U}ct1|NF?Q`7p=XSq%JDvqPk7IkYZb#Lxz6LCr z`tFo#oo(j+;WlY{8R^%oQD6rw?+?vQ2YAdLJC>mi-u1?@de*mfLHET zI+kssJ>Zk2fs%q0a8>#bLx4(&dHsCP+nPW|4brQDI2E3nZyFH}kbL>J%eO`bTAlf{ z%j#xOgn}wq5qy!g8Ai&zvR4DA9z)A&epO~G46gR_{>*W`rkebYw`ygF5n%`*n% zBEh!%+rLB?`uUqm|tTB!5KV2gx;Yj0tV^9I#C9yzR{T-3^fod^b&yA;!MJr6rfKAiZ9kNhnQwxzZK4yE3EvMSf5`&I2 zUnx46SX1@LF%<>pHoX6WudLOji+tQUtzuGNecI(X-FG|-8qp{Jan>>phlx{^B}Isa ziZ0Yb;m3m{o8ufX4Qr*g?7ttG={ndVI@r5|XuUbM`wP4jRT-0AaIH^ZuS2!}UDnZI zw2|Nc(O_s?BA$=hM+KQ5t;^xdmQ^`H>%uu=Vx((#5MyJ>{xG08>{VIqm3POAhKp3} zcAa^2wFkYhH6dLPCDd>`{#F{|Y1RfpMU|q;`ZGsTS$!#u&D%q+yi;4ly6swS`yE)X z_=;hv|07uxLrZB(X-MTl_;-mRB7=HL-MSd`by=!SVnp?h$%$BjPQH={5D6{zM41S8sR%|hV`AIVErZ-ZCq9yNQUYv z?*raA2jKY(AM+T!i>1)KD}O$xw@}B{J}2=YW{#BU^8)YDROqJJ-xq_7O01H~aEdD4 z!A{#^z2OG+#`sv7(lcyvLuzb6Xv+~Qskcfw*;&3Wa$RJ*Ld{FSLt$77eP4aDS?c&- z4q3bG>ju3S4F8Fz*jSwd4ZvoA!MhmhX1~ZG3DzD3!;-=MTrNo&r5sW!a%U?9^h5L zf#?8IS<5eAY>~i`w8v{`9n2(oeyKMm4pymXHsh-dt0&qZtuv*2S~8}p&ZuXd7slAH z`mb#BlNzV_$RDN0H^C`@88=H=cT&o4M*IKP;fG?AhMHTa9V0oq?e~CdroOF1Px^$o zZ?#$z+`HUM7}EYuW~5G#Gi^pv)1CdEPWJ?_37mc_e{J#p>X}L$Z>kpKo=_v4=Qsnu zJP0i1iKkbTk=S{h*kZkns5??mb)I~>+5$S4g3%?lf@6jilM2=KcJBXJb??N6sGB6>0GOL*)m^c+j==13G=2ITDmwInfF zPLQkCQ{h*6ffe&(#h#qq&;dIC)<12Wt**uQqGim7 zAZOC+9)!*;+#ZLgkkwel=mX7Thhr2-|A~BLb+uFFZdx@BHV_m{tSVzoc=o1}zYPs$ zcHjV8*D_UZ3o+af0Q3!p&I4*W36(yV-VDWe)H$z*7R(wM*vo}7X!UZmI<^=k+-8_s zG#)}~9DalEY16FO849D)-N+q)oW7B}q@m!MJ8(*|;>>P9W*xXQjph56m9B|b-(6iW zM_`I(UjZIir&8D%8jh48OlL9;xypk9MPM@V7Da5UgyY z1`F(X0!&M*{9R3Obe(d?mshW}w-f1_gmh2)8Dd!~zvfBIO|Z&tVN%dsozgR|zWJ4= zZmkt=^e9ZteoU;qa+VWt$d%b<|D1RdjoKsJU|*!F7_1B>9I}4R?&}Kc#MVut0$rC9 z*m_uT1YjDb;69OseUAhs*yG-l6M65#6*6r8HY?OHh(lB@cQg(${v8Jik#1n9?G4KcKF|Ss1R9Pj;GmL+l8{q<;i7T~?o&8HUnp zi;yRyYwy@SyY&q^o)?i7{}DTtas-`owbNFhN~swy@zUJrSL0e5CWSBY8vv}3oIJD} zT{~36WA(8i0GP(`f;=}Fck=Uw>kQ>H48*Mq6>!f~bnZB)ZMj#582(S~w?8qI?V+k) zVPTlWo|q5L37{p+j=#0H49g*%l!r_1lvJ?|XS-kkVB%zy9vs5#;^Ev$Uarh22(8U` z>s7`}Bh;)5CigTHM7Wgjy>8I|D(I#MAAUG9f@Sxto%V#u0%X5Do`I0xB;A2yOgUE& zX`tHRDkD*1)tqk+XP(XBJi%ID)&_h~zeB}sg*yvonbYBjy&bxD+~0=nZC1b!sTk-8l;7- zypao2y!UQnVtdIo{5#>)2^f68A(Rj1S8AC}9UOMEJ+BUYaj1(XeU2c#U#(T^f)Ub? z`^49s|3HW7%FIgY+wN28RM)G(mHIQ!o#*i}7Z41yFtfjUG9c(bhA)ZQ69p%#|LjD( z$SDWs8%(8pgZ;e&aYKHBTKw@i!XKrn^!y0jcZd|Gt>|kv95LKVuNs@LOcOiel*{S9 z^~R!6nN&ZDO8}J-Z8sUi6kNg zHZ&CcU5V~E?I|201(x^g8vk5@uLhXJ)QzyVl$PBgnAGK7YU#2w3ZQz9a)s?!t8}cU zy|;}vciERHiB%D*ySQAg_cM&XAY}6et+6?8g=fFx>c6Z}e#k-{@qi#{n}eY-RZ|7O#l>gA!kMpo=R-0^IXVX~ zX@DKOJsA){-5!~6(zDDxv!=NiqFNbRUDnRpPYKd}ePtZ7>vKEUrJW$l@UET2VDG6`5>|aU0vV$CQE*#*UK>)qQ06u?g*YWrl9zhkWRUm7 z8FBhBLzfh9PN&E$KP^5DxFq~U(JHcBh`HF02(*Ph+r5cn8SZ{{H)Oqt>L*IpN?I5_ zVvZpNZ=PQp8a=vMUTUjXswz32sOGis>Wp{-(VrMami(F!bO;1@YvhH>cCccMz}RKf z-&fL@(C=78OQ;w6xF0>!g8LRfmY;LZm0!RW&JQXjuD44d6K11(d%6yX7%f)HL#v(w?ta9DojsT4DBH8P*B`MC4{f%kmBQ@+2~+dn7upe@f)-e8x0 z&)8tAglURx|1>vU}3DCZqS(gt71l; z$Q_}ZkF#YhOyN}AT|ZcUXAqR@p{Ey2t=WPm_F9cUV5)k+`Y(i^v|_k`r-q@{F&!lg z=sb&S#RGOQK|&+J=u^J~wQq@5)DxwE7$1wIP2hnQ6k}e_jVO)}Or9COMaN` z{vkQDm1bKV^2|?$>OCV%0IC!gz&_#e?~W>~F(=G$PYX6F;*gJh{gsM%!)<^k^k1X8 zIdzeyjYoEYEd}+2Ux?2El&@-Um8m>^zYw8;`(zgsk8K0{4vkn7Za5i1BY@a6?BoGf zIwBYHcf4K5u~fWeFKAYoGAQ&sB01#nYM>l`84QJyEFSAR6;i!L2NGDxv-t#bIgwJD zL)%!IeQCWER(=U>9Ps9idz6WwIhSrIJX)j52A7@Y?ni>pn)xzICc$2qYG~P*=U#+B zbB%7BckrTifsg}NiGFEh;*G=7>6LyEr^BOy4K;?uRu2-?xXCpV81H6?Fgz_UDKe1; z`?EAkGIrG?bl<>8hUJICkg3T)_0vl-@D?-g{%5-x)bQm9L~-*VE0`(*y&ICzq649$ zQQb(3X*9)Fmz$dJC3% zGCbFWUMY2wy)r%OCuw0v05dtL>T~39Pu6H&p6$%i5&4Q=wF#AzEpy$5aJJ0^jm>-qip2L$ zt$famtnAdVBDD9xety5huF_ENPj$;)Ownd23No%AA?E5sEHiXyt~I0Hnrr|0c`y7w zobkjkVSvUL@sE!52tJJ-PzVB61dYVbz~?Cy(4~`P!-(R>)Ie4?`E9&}uQ(nyxG+Bq z%us$(in*iS4;)H-h2uHx^CbLNFYLDr)0kPhZ5RShsm{NO5oHISjjp zq*|d$5OJ8kVws}4$d|r26;i+1qtjk3tlGS=L9M$M4Nx63FKMooLxMB;eZOkCz^9>q zyq*TSo@^^0zxAePBQxK1gSyK_D9V%6&*~6b@mw+CjqpMJUkXPtRe_q?ny!5X-DsKr znX#NtvM#_e9gidsg0s*02()|#`r^0uetWYb{jJ?nS__4Al<-7Qf?+03+cY<;z?L=15>VNb6+9j4_T3X&E0~lol%yjVh2N`SyHYfq=gClK&?TNPDKl-<0TA`v^b1ghfv6F zcHj3m57-r*+rRv-5MgC-m-OkmBm^^xF2dCm=d9l4(IGmFNy_L+eR9l5Pl-82aQZ^( zI}vaST1ECvzfQj*X!1_h(!r5=n9p#fC%s_XoiHC76R@p3?^AW7cYf7GW$rrrk}IVM zV^&jjAIyf$W@CA=f7TyzWz)Y^Au#yLGhEGX^v7@>KQ1gO6AqjSoQTp?6pC*BZpfH- zK?Z!l_=J+fq)XtGcEOt5x-kp?9Bdpwa>AaKmB{nSXeOnWxRS@=F-;pJM9m?3e2sY= z=Aau38t>x%;Ml5PHl?V4!8BWS*Fxjl(;F(AK7?7QfkPXsC`sSo)@ptbSz?aq4DUvD zcZRsjLh4IZYMEytBXV!*(!l}Sz)0%gjD)ysnBlC6f~IsK%TL8=okhnnoPt(c`1?C~ zD?YkrvYA?!>X5m#7TcCJ84hjSSW%Zwh9uw;Gr_1Dj=@LJ6lg$54N9e-_>07BVLWUs zX=PR7<8a0hj5$(JWYU|)xhXcQH#U|x!+!SGgsA_B$6R5g0o#0^%>R3h(^Xylt2s|0 zyQQ6MOqll?E6Uu!RZE5^)C2EB;&@%P=_soJNr&7wpC`+3xO69#XBg|gBz9$6AqFqd-hhovED zy(*%EetHB7&Grm|fKJ@4lZpHlGZvT7ZBiE_qC|5xpwqYv8b#x(17$Q~)n6Akr)8Gr%$w?d^%(f_OX# zzLvgvT;O#JLVenUfTgo)`v;>Oa}?(tXkbxR^!=eM%?5sMoEb5&tpX^g7ix_y>No1C z(8`qp7Qd`hU+6pbP}O(8Et5nz5%;~7Btz}+6=TZ?KNPdcgB|_nHcCn( zX^B`+yOzIiB$w%OL)xO^)CfzB3AkJFJ$-hz`OxkR3~{EjB*Td99F)f=(+ z!b2^^ld!HZl{wo02!_-dsfjPH!q<@#eyepVbB$#dJ}28)d#smu#8+nNGY5?gy)=6`Uk(_7iR$YvpX zO5dt@)ozgK&0cT4iOHVVN~C~l?_nZVk+oy_Ygl_ zWqwdMBVkjryn2Y*4Fz>>iyPqMRq~XB|0*5GTWQVr3hTF{3MtaxO|vORqKut4JKoai6@3<_ewQlluC^1gA_{}|OH{nm7Dr_QZ&C^YJ1Q%&GW3?(^b@Bx9XET-8&`$^#4D%=|GwO`W=MzmM zmAFPv^d_n9U98E0KcLomhke}VFAr~0+^Aqxvl-@(^5usa6D}gweESXRIhq=iEE@6b z0}XSF9K6bg#im79*%n<3|6~N1-bblBj_Gu&R z^qvw~7z2LTvLY*TCka|-7=bgtcBPD@&$6yMV zi~R6tE?f8}j~{3w%|px~wZ!WP3PSihjUDWmGsyo0(wOj{W+u;FFp4;BS!)@BN}VNc ze{KkK{)<$x4l#OwB2)8oXn~rW(~m*4R&YN7%fe5cUPg`5+D)TDEDp@371Oo=EFesMKL- zm-MxP+VaZHjw;uI0NXrHu6Ps-eRBt>6T9K`2MJ(N(8+OQJ-IF}{?q9DjFG zPxJkP3_P(0t;6C)M^pym7*4sg%G>QJsM! zx5)3aqip#+{r!-Mt%&!g`ApI5>Nkb!D777I;=I)Z!dFc?cf7f`F9MSn?u!3frmXch z=>fEWJF)jw9%?bV(-INU!R&qaPDmRI+HmpTOFe&bZySv+oI9#iat0=Wl7f;2d8hwKFTMm*nTNReR1A`SJyh3&-uED4 z+`lu_Q=J*i`hts!p-=wFhx5Xg%sX9zL9U#?fMV*oyF^u=QyGk0=U(ay=wq_}c!Wul zYRc5wy|x@7DJFYs(RNmljD&FB9-Y)V`t!{gzIBdMLAh z`%6^j6J0m4ojK7VV-T8gaCwC3&o)1ItUQlt;WgFZ)j+sp26A*$V)A0rBmPsP_*3L{ zGMStujmW=t%oxII7dk&giPPA>CRxX&EEf&>c_7n`_r+_L?W7fKq3~VbApvNRiYj|D zd#cw%(5&)Kw(-_wxF^adB&%qtk8B>jOP!N{tC>Y=O!xy&{gW`k`(|(VBuQkcNo;aN zrECgzRPQ;!nW>!io~M}B$+t3ZXBlL9t~Oy?a!HGg7#{=cq|;DIzl9eI3p?HNkrdPl zyj%WkKRm{E8kPeG3hZFV(8#HVvztaw-|=?gZZd_&Iu8hg5<^`OtH&Z;m=kfk^Cz-9 z_f#cL4ota=z2U%3Tio=(7Qh%d4Lx7Q>hp!e;iKEHYmmZO2ka+LDiJL?xk`HT)K6f% zUSOM81~l-$a00IB$vvdudxgXhMql@(E3+B^N2KW6LdQ(}GpWosX*+(Uq3NrCNTs7B zlX#=1;n&t=ZS3k=)B-nWC1+Q_+O4cIZE?$X)BWL@OVS+-ADg@7`NB$f=O8B!)gns*}LJL_C)1o9;f2YzXtY#8m%YAYK$9w8?euyr&aXY@l zhR#P&YY={;qYX)>(*SfCYfca`Nf7d5c?9b^3_A^M2*BbWs+D`U5%Fd>dLM`RFKN#H ze%0KVSE$jMxP!GYWf&^wBmy5z;uTr9RzY877{=mb$s6C?YZc{NZs8Wh({Pr(8=SVblWnadn2cL4n(V-c=wO4Kx^Y>=0 z_WcbNI?+-5YX>t3n8ewq+zW(b5EH8p!${cA=VbB=#W=B6V?I=6a>%~?-&MGsVOoZnj zQgEnmislW;wI9}};dfe(C=V6#pPSz>5@Wi@UT`grBXMt4{iKtkl=wJIXm<|R;$b1 zn719H1ahI4q&imHz{@>^B?r|~aZs54+AZotPzL6CY#K^8%I&B~AE0_(m~q!Z8PhDX z55M{;`=cU*sb9+R&^>Xla@`FJlLr8QUH~V;s>oSAQAoxv}xbs+7MLJ3i0Y8g~#!8Cw7F3zuaIJ zf`*VPDjsUF;*xZyGM^v}l`%jB5I)4d{+I|EUHw=2Jpo(OP3yG60!7|%0lsJjvup1w zqZqKE08lCrAw?=qYbaVr~fn zB6Ek8@!r1HY({rUttqQm7hmOp)(k|vRl-N=Pa-fW&jT;8QmS)=nLMO-55dHcawxBw z`L!;Y9SkOOaDnT8n~M-W+j>gK)VGnN`U9?irbzHiqZ((w_dOC%eS8l?Dx4#C5f?Eb z?${CH^Yw#Ttxp-t8Vz99%2otJA|j9M1Njg}j#we`BcgWVJmn{mGUFCHk-AZPf+GOu zFlS8w0Umzma{Zr~hQmD(?*8M77Mx{X1V;~ofU4`ky|*dW1nd9(dWghEJFtqrSbJAa zikCOo19n??6ZJK+4`m}e!-`;2k+mW}F(z8`txAM9(TYOz!biVJI$}vyA$F${Sg8jB zl%F`T?Ki}awfFEF{wt5?y*Lob?vQbM;Rv442!ltJYbOKtf1>UcDgcw&)j@@~@q+-i z;LmqGbeD?(VILGiw%+uq$`)F}*mZSsw$FqxV1%Z+j7)vLSQJhMOovy}fN0Q>6cBo5 z<}F4=XIR%sEPT)S6D;X7G>>4Kuz_3QSAclwEsLWj83C^+gqpjevB67I%HpJEpk|2D zNc$L^WTz8dLzxu6x=;Kx=gTVXIyJOtS&HYAcmCWOf8VQ>7U;V$XyHplN)vF!TcgL9 zQdl)gWB&Q)FVD8u#QlWcGapKNZYNtbXg){LiI|w6P;V&T6T%KsL_qI1B7veZ zmC4xPr{rc(_CrTh0&q+74DHO9G4<6bKoT0*&nhBRrVE0uZ~V_fd10s>kuPWC1)Wth zF&~;#5g_w3S_$U~?kmeO|QucI<#dFXBk;OgWS> zoiUJ1w04v!5)ob%bF{o|gC90S8_@3Z!vfyx0k$i_K7+7o=*5q0BFi}V&%}_ysj*U( z2tn{+p9iq3I^DpK-g}F9JT+qH?zC&J&E`By8D0VYBg{?T=Z8-MY*XWp0lGokA@Fb8 zR-;9VB{IL9w>&$bDPHd>!7BX^^z0p$4&bA)5EhN31#5N8SWtlUHIwGl7%KVM!xnrV z1CbEDfdkvfuTaQ@3tJZ4(2>}YWPeux<3IO=F)Ph`xA@PE9F#hSHW?XXiGVdkxuOry zDDd_1S0jJmjQhy=jDvL*?sT4Ir#`dbWVea{#d-0saIcv#=Y*;uJR3H( zb|T7@?MlCkqLb?iAwd4CceFlSMQHLD469`C{*5TY;pA91H#{L;*-WdK;zWq@m*Ulh zjP4pM`4pk(tWY;=7oYNq@kLDd2D_64jUKmfVPxtZauhyD1}`R>fD{u7GVj&~{CV_} z2(?1Mpgwn1eZhrvZ?>pC98LU61W0_7%<*le*9IMxXvkoD%pjT#C+Ta$knOP)hx@s> zDAl%o>CU;%S3kb-C{rnDLMehm+of2`=G~n@0VKNZFC4QHt>DJ*TJyM#ld&bZ497KK zb}Bhrw8?KrDv7ENw2vB$s;Rgft05QofJL8b%R1WHyFmUM$g$C*q-iY|TzR8+o5r>` zF#pr%1t5i^_YPAlzU2kqbWrWWLZcf4zs(zQ0HK`aPVXG`f@=~%x&DX!Q+$?aI%m|d z3*OjDHs6qdfjOw7wLP0;6kkq$@$q^$QvX$(6d6}KvG{nlWZmjV>$5iCY6#N%>$)M1 zb#B7F995IKhi_$QhyQEV1WezlWkcD?fB0fUjOSwN%En<#+t;G?BHt+P;cSAYgB5UB zvuIx>>~7W4?q9?3IS`%7?n5ON8LppdN8O@`)9> zg~~z*+bPlg%gTY$pXmoB@Nlx>s>~yWjf6Bs${ZG&qi+P#Qf!xpSe2qQy`!@=fbrfM z-)vT-^TE-9GOVKx9{3DRZ!~iEWrz5VECXP-WN%A^uu<5@*>c|=FI+Fx(J0uB9!#Is zt0fdXfQhXM@3^l%4htUSmU{vS&aDE3sA%Cea7#(@3v;((U<4+?@CGP8LZ{+nG3M4= zQV_u4DWd;~x_OKlW%|}-WJ4j%&H19%cexMVcoJOUYqM43nEU6LRCcv248L~58RqUM49zY{rS#%u$(jATe8on&Z)|!MKFOB?}S^uX`VK64e586WW*ovZhl-H?6R)3 z8povy8fCe@l+>4}mwtl)rvulRql&A8*R~$lNC5-r%oT(}7P|A!M4Ix=Ph;^z&MJv!Z1!2X-EHKjxC zTWF*gj$H0GJu790hPq^J;k_y00$4Ja26!pefM%GZ5Kbv zk?EEW{~MlD()VMAl?EwxaT^8FN8ViA$PAeG+t3s&zBn@iwu49W4HkVAGsW(dZVA_Z zGb0VFfd&*qb{lJ(37!w+hWcfThi$`ybthp?2$;MhXx5=f#urflWkBS% zw=FC6N{-%p`jJRNQR*-h$4;bVrxHMR(NmjKLqEcm zPcUsn4OkxGYW@h3M)dK{0D?gMSJ&R2Evpnd%Q@eC0Khje1Rnq+L)8DB3nh7b5)(L3 z@y*$wnD8+OPE@xYLQ{RQ|5!A59<}>Fsl+86(Hfo~tsFkLftyKzB-G{Cku?!L170yd zTC~B`z?I&tPdmfC@E#9D$|c)q#X%n~9W#$n`tjF~L2^~zs+~TDW%Ndt+NZ+Eu2B78 zH_uECXq;P9jLysE?kd5>h8{73oyfrx-F>;g2fUOuF!$l-?5WD30;uMJ!C4)r_9>9H zojo>dLG{i;y-Dv?&!oWZK^<*&%{#o?+=UEu4|tWmc~dlHkF>Z(KKoOvy_Q603&e7y z;_X>84nQsbrembw`Lpv%yPF%n)A?){L0VPh9fBf-KwhS z(vwY*s>pzbWou15aeWtC!fyuUdXwKw@@D8IUd5X^FWtPJJX>wn8n~irj3+b4-?&U#63$osFKjTNxQ;=?q=(N?anU4cntY`EiC69Gj{u35$z|hRo$NOGOP1OW^p< zp7c;D03^Zu-mBMz_B>LIu8ifodxF^?`3y{GThot8w!Ok#l$b0S2PvGeu~lA!2I;`Y z_zX)_YBVVCId0)OptTPx7Lr3Sv|bgd7R0S`qkf?h?$-+zOZN5}J92t#r-mbD;vj5) z0@@to2PA@Auythiy96}$b|=hIA~0$f4l&P{7KdWIZL+yc1^f0fZtYZ#`__`sFaLFS zYx5TBA%&uFhU5NVtsP>mYjq)yH%7jt$sj=B#sQ*03%M@cT(I}lZo-52v!#hF51cXy zxhQZJ6-Xv4ism>1fee>fH&R@X(t3_R_1EZh{h%$gQVT(uG&nC`UDH4=MZQ{N+>H2O zYQOMDMh6(aHa>8@7<~*hRs^;i0!@>ufPr3j-{~#rJ8rSWG+gBI#D#78D{O<1w6y+L zbpAGqB-~IGU*vs&(FnvHyUHj{v%8Cj+oUCcD`uOU$3Rxm2|A#<#FJ+^$gXw`7Dba% zLaU`10~IE91zO(yOI?ZPQ8zk=IL6@O1OLXV!eIKM*G0q_RrYwPpB%5RW|ubc_7zyq zagl?Ejk^@$k@8asWY6N6S8G$tEjfa-FHWFB3xhYoTwjWdsK#>WIa;4q#aa!{*n8}O zEgvE(T>UhCN4J!nzKFY8`u@I{F(X+YgTEFc`yzY|9MI$s>~d=VU%$mkr768TRjc7k z#`6k8tfmug!h3o<_6xcd_F-OhAxmoQ)g?n|KgM8`O*5tAr&QNz!z5Y} zTT?64ZwIESKw4CrqIN=3cnOLiK&Fi^yg>(pRHioU8g^BGO)lbsyMXWZ55lf5k+F1M z+FM+jgyas=R_8`1hMjvpC)MMBP zuz^s!ICebt!UfMOZ~Gc-08E(owkkJC5V0;)_gR#h7Ga-`Hg8JPuxO^9PeO*E-gHNv z1AssQrsS$(Ja%%XDrhFsDpRWX&Kri&2C#1+hQnZ6a|aLa*hu{TC1We2-GCvFI=U0*i?6sJsWjPqD z$Ov&3RFIi{?u%}J0@?UbX}5oSSRsi759tyjWD}wunT_6NP`b;WRJ5%S{t~{8AK3^t zg0E;9K6lt-Mm5l;6QkrDZwmN2nKxr&}5(U{?E#=IxIrIgVsydL70<8BkD99EKy>hr*Kd#Nlclavmr-rpP-Rb};jQG4@7?q45ar%s6UzzwHA}|% z#G%a@P)Vu+%sWw3q_smV@9m!GLjaOL+V8mZp3T{jq-R20n>RQ&mwE7`PZdcN#h%We zzZ+x-@U$@vKseRRc$`7!kDK1|I9D&Dt$SyU`ijMxT5m2;jrt~D-=l3#)^Q4n^uN+m z&&cNR$m?%yR#xUlF!z$oM}Cr5X{s8CYum8XjmPYFZSaPC>UgmHFm8{vApgAui!&O3_ z!O>0EFkgp%E^wIX+fu$v`5)g|A8uhMWy9Z#OtmWc%;>J;|7$$rY#F%fxn#X+F#LEx z+6P$OCsIZLIhZ7~*)R%3zvWtti(rFSTEtgz4#>q3J!4={ed%g|-$3ZDa%jN}=E}2)Mp3y`f_5v!lO^ohB z_4jGCzQHYng`8H4gT!|-=<{7|sxNAyATse0mn zo+Cowfa4k}+~UaUCqdG06=kYVQo5-`gUd9j+j4l*y{o$!6vT{VN7$^*^OvUGbRFx% zaH5Rw8%>}o0yU%kNddQH>}{m=3~C2*ke%Uv-}(<)$4)|AaqJvEf|&MJ;Jz(IO@Lk0 zY-G*YZ^R!x?4Bjm)jLE_7jp6`Y0G+rb@4w)BJzB_Zw1S_xAV1WZNs)dIHV#vlr!zg z8P4Rv)kCM6QBryTJZ7>v4iZ^jYv@EE%~xHqs;N#+CfESA3e+3U91Ni-3msRW?8U?>pqdUo zp;*nzB-M`b9K==3K(Mk;KMx4u19Bm_yP$cXN*0|v7a7_XM`()#@|h_5JHnoq78a`| zNf%t07a6r@rf^Ibqr@Mu;rz1hla+Z35bM)#4!mfB*VS% z_;heU2uU4BLOwS7CV+;=Ntbbdz39HEXjjSV*xSL~V3Dh9)3gzGn58&jK9ng&>XGS4 z6^|^C(by|dl4nW|fJq?R1R!GH%wJ+brr?*53cmn{%2r#=Wf#iw6hDFgBzI_ma${-{ zYr3-I#iI2lK>4=++RRhsKx9|p>7Yv?j0_#TDJ`BjNWfL?r5>9U>pJ7kS~X)21t@l# zo7yjcC;TZfrJXYgE4bRjD1+wO>6XQFF%BiF9S{Iv;Ykls$1Q?R2Siqk@H^`SHBoAt zq+~9hwD-hO4Z+F4Fr5b^t!}wI@{To!?XN$A3|9<(bfdr2NPkyN{c=*%RrjB2$7F#l z`7E_TBYkWg_0gGpV3_gON~p}qRT^7diIc^2}UvQ zspNh{0u4ZeQiNzBi9(F^+EK<6!j8_KBbm;EO;_UF*y_{lg>A<$njghQ`IYb!0)Gc0 zcU~ZabTfQA11aC0{a?$1akI6|mWc1({)v!q89Z!}Mpn1W<6juVgm*{bZ0j!T*xI^9 zFc#}ck1I-I8N$rL2Toj*(lmfauJDh$nTS4mJqg;{(Yl0p+C@h*c`%@(GrANVsa{u>DeEj&@%qQT=8|$}z>W?GnOK9{hP*v!IopogK~`%}A5Lk|1F6Yj zOAa}ORV{eGT^bHA<0C>sPZt>pjF z$5jlp@!S@}dVN!s=1?E~Wa_9q{ui={(<`dxDo|4S~>Tp%jE3`_lkX-&aU*|Wf>=SQOk?LSj2dFS^Y8wfr=ugI+=Ng*)wF;;!+Co zS}b`rL(*8&$^_~9oo8Gu=|0tBJwDsSe*$#|y3K6O754o^M{pU0QbUfRLh$c$3A;Sy zdjwk3$&XRlOkmR6(%5l3H2ow{|E`f1U0XuMqVb!s=39tW$Qvkg34E*Z{Owm21QDyU z-tV99A0=;z5267Vr|$weGC!MfgLE+`g$Z1wUhapp!1(lZ=Q|ukX0}&eZwoU-MU}crI}IhW$s{^3@%RK zoL_iddC$6B-UOqBY2kG@sq`-$343qx?pyE)r9*fjXL?+N5J=(=%Ck7ok}qI-&e2Z_ zqkKR+LV$!*)+dibNkp*01}n|jeZLTfS%)RB57Y{f72}Lp81k`2Rvdmt6RC~GV&$m3 z%h&@TI{(C*!mUyq5d67_8n&fRUpOGAaV%G52Tu^;fWgVw%Q_wNB&-MP%{d-ltSp7< zr}wh-9XSn`TGF# zlX)ofBkx!#Ll`CHOiX+nn1$zZfw}6gI=R}kfr3@DuNoEF;Lb>6na)ZzMBAFO#5;L8 z$mGS!n`~O!=#Zqc#)wcCgOEZf0bo}l%KvGb>x&9JLoYP-IJcOzD8;mAlqEbWbUoeM4)B`=+!n zD#Ygz1A1z%?R^7#3K69krzaA9l+)_&*7q$xYxjGU48@vy6Zr~$8@LK+(@uGPl8eRi zbQ8C+GdKmL269q6=Gda*fSHA(CpF0I%{W&wi5&8r#WTY>wtRJ*FnSTM#Xw~5^WgMC zGoXwhfs7IxQ`i2YK8)%jVKqXcjT(L1_#;HDe=TZI^yfWfD1+%s!5S3q>$!g7REwkn z0kdstTh?}yCQ5DY4YTfhjq44aHq7w!h`px-)*&{g7tH4Z#XIppfQ$5chiV560>zt_ z&VcKlr)B|XmFNnTifxq#URXoesdXE@GM%vHbO4DqyWVc0H}8SAms$y})AK2wn1T+O z3-xlWzNhrSrX9p5`-4+0bPdTS@YJ7UE&L81=F+4w|D$zt>VN!l7v@}ACN33-yhDFo zSZ-H_VBUno?_*wid-BzGJYC9zGR8paNW+m>yK{65vFxM?{>kz(uZ(qT)x|>dP-Mit zTXt+HNVI?dnJprm23f}#_f-##Gt_l1hC`*<`Td#L6A$teTDse?gt}`Rdqu2~W0ro6 zn8Lvtv>H<*Qp%gWyHXf!(CxkT|0+^U;q8|mYA0nrIBBJsSW9t>!R=#6Fr4kH4qt;XYy_EpJHoA|ejeDcD4|_IR zA4)9AbSVyH{{`l8SJpH~53Ya$z*yn(gJbx}rk?AfmKExzsk7~@yYaptSQsvyc|$q!psu9J}SBMC+ub*Xe&wcra|4=2<)E(yxRsx!4{)!fj*nZr@WRk8yjeN z1Jh6)oy$?_mj*}iaXlfDKu(d@3DEOaF*DzE%mHg=`MVXVF&xjbRR!1*vRhs8{Do3y zW{yZq{>&6MdvNiIqPO|KTq?7lbRoejJGp)+cYt&|^Pm!B&ZZqnQ2{=^OO}k(qknvq z$A+#Eh+7_Fw~3$oSddu|`y>>sij0+x6l6rxrS)2uL9(7l>Ls1PLCxakVOyc}dwROmzO>!wSBcCD7+9x)YQ8m1JZth%my;%hm$geVWxpxHmT%#lNSnDHLGOs+DSs1A;d|< z3~^uFAKV8PVgndx!9%v0CM@Xt548#@cgCe^0^#?=smh@y8i4Ks7&*{~sSp2m;~2Mm zS%-1klQpWN2eF6~6bX)T2g?#*5aL}Qxxw|38qCVI0&WoOn2O@%@SO`Qrm|+1`$J_8 z<>CuLkM68>KVIIV_HQHNv^wYl+C^Ph;gUNZ{R2wR)g4_ZT}6i-o+G#&E-C<8gAIXJPP9@d6zR?6=vh#Q+Y8jhPj%bxCfk}7Ta=^4V@dmsC}u;^8+JxJV?wm0 zuoDa7O5Zd(51_yn$+4;psCaAAVex+*b1_)pCjZopuPmHkaA%AZNKp${sGtr>Aw~l? z^KN7udzgbAC{50xs{n%uQ8FJrb~-?o^yIs+spG_lF*;9g-Vr(MlrZi$*V~&L9>{u1 zS*)AIP@?nV6Y$_eEI|6XCD5<#q$&?^+^Zm9mc0y%*#7q=!oigJ=paHGGX^23@i91L z20^(9@kK%V(>{@So6jhnJcY^kMb&vIW-C1rB+epUnaak#L4*{Maeu>GUS)0(K^&?_ zTv&##utzfc(d>4XW31uwFv9m`4qpEX8j_XGEfzTVf)g}r+&SXB2nJWGl9~C3zJR*| z0ns_k;U>uIwG~Sw$+yXM_A-Hdny|0*xtVkvvy=|2VwUDRJG-vFOqQ*_L-fG2-}oSu895I7W#J@*o^4Q7U>xmZFjDjymM1z$-S(GzBRH~;$@#Do zmcF}bHv=0Z^r9?i7)tglcfq8Lo#Tp-9D2qiuni4teFJxS{XV{aNRq2*OQKM<{HRtkHm%#@&bFVzc@C5~R1V9Wbkr`DOa{#> zj~Z1oka#ty{iPhxJue~nE8KT;@pNa(EFUlj7$_<^eYGb*05|&9n5ISYq%js*`sUye zVFH5qZP2Iyq|E)dYW5k$pxTFqxbOaIhAqiecpAP{Hr|UxNOu0GzNna`rP`6Yq-SV0 zY;2{!(rN;r{ZA>C62lcC3YDnmGB(AFtEx-DZ-?zSCDQ?WkEzs{=P9PGoad8Hu3 zDnorOAR&K-sdy97t;lpaelguEpmN9~Xq?7b$)T#cT5qB} z&lz$Kp(agt$nOAoh}^H@fX< zGEH|sT^CQPyxhv|uc#437#6BFkeMLp^87_~K}=s7?a=#ImUNjG6Rd368Pc7*+kw4v*Wx!K!T6;&~kh7oWmfWftg z`(#xqc>hCWZ#`7=Z1u+~48uA-rQ^Kj#&gf*IXCm{nqdy3^5`pe`wi-IFI$N77HE{L zz3;AzHQPMpvGMZ(4B_Lcu!GJd8%GNFGTlD!(_w^jH_cyjwg;56GlRxhA6>plkiCos`g(;0z~F!t(qGi^_bl3L@O)m#l8D5nT8tcS+?Y7gY8^o&nJ;%% z;Q9_CHhr_9$G5$2B|+KDtQl+dkWEJ(10XSAUQv`a=tUU(AY{z0Fg>5pZz75 ze-S|uqITUYRa=(R9s|mR*p+Nf{O*kE-1*VtRX0Om6@FCAh}~OKPL2u>lMjExhP5md zg{l0<3WQ_KtuA*!3#hdG=Oo^;N1kkXspoaW+e$!Yd7sW1Q_$C>@mi1z<3rUKYW|%y zY5>2Uyb$l7LEvMY2+nEAf!EP_&gH+wnJjZ0A$X>Ao2C!1{*EO(c%(zrdA0FX>D(2t z2tddy!u`DF3AP}*oP^27hi6~x4B&)vXs|gp!Y_iEatb6MStG!uk?u>J0er>2RCq)G zPfF{l=J^7%O6Wx5p$!xu3UOq+s-ocLTiuDX!Qa4YZ6c|qY|oR7q`tpA5@Mn#N4E^W zcwJdU)3Rlu^8bkGI=9zi53wGA*=Dr#gL=M;UrEdTwPrmls8{!J_Q#K|)gN?{t1}^R zkrjmxSNMFNz9x>G?=AoKbyKtPPu@8xkQ0+msw_+HjcjPH$Id9vC$8;e8R_?Quo`~s zis^EBq@=UJ4NA--;icJnBs|GFu|65i z!uckwb7skhb9E099lgRV_b89ZRlc5eM{{TAVC?MHFDA_~@=zBGhTW_sHe;_A%CYcEDRsI zLDMIZ2&~*IS*~6cahEZ#y|I3f%d?%_?NFeZQ$j@Yk>~H9`1CmE$EtCFxFfQDq$%Ey zQItSw%_yQ`WXfMtWOhO&IN}h^0kvj<_|_hsM9(!yu#ff~sCGYy7n`vy{ifudP#u6R z8-=M1rPRAp2|EnVVgH5px_F5{A9kF*Fvd~dM}+n6U?2i62Y1H36b)Rq=FV@Sw8W=Y zaxZ!PHk{lsed_W4FyU5AQ14-oEd<>49WF|T6Vip*btx@N;<@7H^=YgRp%`v;z|_$n z_pd_NTCdo-jMk|Z=)l~{nu&uY7&6&OcHRHL%iSk3_^5F@2)3Jv_vR9_Nh%|zuPxc80oJD*BG$nF9i_wX2{-I9XaZa?_ z%vM8WZ0U%8hW<}pH7&Oxa{9J^OSobVoxK9!T^rfhGp^^>1`~lS`}s$$Vub@VSLIlk z0CCUlo=@&ZH2sOTRzz#9ja`Hg`Sev)07#ofSYewFve&dkzj-m_?BX@zs~IOf0oxkm z8YTlUIDu(OMg`@l&@-oTO02pn^*^;SGw#o!ukw!#L9~T2Hngk_qml5a3aWRhEs0e3;t=ZtIzS zF1=MTJ@dv*2bZaeQeGO-4*EQPw4uB6K0ZcYpU$!qjwt>9Hq~BBq~h`s2L~a#hh@dt z=D{~{YO4W>nj!cMJF8E@hcpUer8u1_#r!9cgrlboG14jp>4e%17+C`xjKv|i)s&-r z8g*{9`JVY-d3TNlcL4HLvih2a^;936#o)F+3yHd?w4v^V0o_7m303ViiN~1H?4Szc zqM6sG=F$kerMQVGzv%Jrey!x>yt+m(l65;NC}{Y@dLX^gf9!&=pYXr8LZ#%Nxb`T~ zD*8kU*d>909G3>@^He8Z29)+K*>z=Q3OaIM(zS6m?|$bb~fOmy32_&&RXB_NRe zgu$b$tiXgtB{t1@3~sh>LO1@uYLNr-_i^aKY_;h!ne<&gn18JjuhVqCx=Lf%qyZJk zX692~2~qD!%#_%Bo&#*eYj*~|DDOyL^_L<0Xw`1#JSozX_I(6y;wM5QHah8j`5TgC zJF4h&}oolt~ClalEx7sGgL!P z<|%=LeC{K&_sFbg65U%M*_on0NKfZ;dL-BmTm!{{#hS|1;M6#TH&_{X<~js!XRuL? zd^L@#PCe>cy-U-SqOYKwwIcw05Omur7v~(;CBpnjh0T47E?k+f(wf@{^BE1H_&vcu zYW6mo8%8U?aas48c@r)jO1v*V5Q6yQgCJD%s*kR4+sUZ45lh}M7gLL%)vDR}suCZk z=bKWXU$O$i&U{Vl)b^Ih?q1G$(aNzQ=>o>Ni~ok;I?_Po1VtEa{@|20YL4AP$ff1qW1$;w4GwK5SFlgB*H`c9I|gy~Ug zi$=W}kF}I&2hjCYkEbcPO?E50IkW8^Okq4Z8nsnXVneF++{zm$knC%Vy>dt2>kPW} z=-rRzdP3Tm550#p*0aHs@A`6%tx08JP@TwT7byG#6m9uyLBQ|JHYE+3&XAo6yh|jtu z8+O#@?nQ%by7&I5@w*w4|6Ik#2o+`u2nIy!Di+CdU{m`b8}z4-+|sK)x=LN19G#vT z4}IQ>Gbhua?Ho|-Ti96YQD&NHi_#VQJpV}ttk(pLM-sbNXp{^Av_zo*8u%~9d8N9t z&;IBZWdb?}sQsQsGsNH`F!*!OxIQz=cNiQ(w3DE2uF`QqdI13rOuOYf3Y)dYAfs15 zf33D@7EbIF#M=)@fYFjIL8M^DnzdLK{|*XGHJZEt+ZUlrFWs|!{FIVcM;Q7&^DB5} zzFO?~C!-(zeB-Gei$hdF>=Npnfo|O=EB92fYaSEww{$4}6=3E#(fQ8Jr`$gyi+5tc z4+u(oX1HQe7(}c}-p%eBs3v3aGhQWW$mo~v3o34pogNrA->{j(`(+Ap*j|naukv2c zw+ePL(dk~K0*xqn7>1nGfUDOfZbH5pZsG>=;HT$F!*fISVld9oW*zLq8tvb{ZoI_2 zi`Ov|M+x~-4TA8IVdltbmW4W@+R$Z))9F-cp?2^~{HX3{URQ9f*wyY~Tv-2wu4qMP zxLxu%pgR}n{}Z%Nh*DbAp#u&qeEj+vwgGA-X;$-nsZU(cFnIK`y+dSr>t7q)3x6A4`Ou3i8tO{GMtwPwAoCB;F~Gj=M1fq zQW=BV464wbM|y{l_f>2D;e6bYgw&98dPtir)wu5Tw^NqCWLN}wEKMk{`{c4Yq}Lb4$R7lKK-t5Za5~}a7F254)`Bs&I$?QYSR(S zOVTE2JxS5eM5{Cv`q&=lC@uCMs3Rip;BeDl2Py-!kOQ70-Pr%<=%>SMtfrg4Fp}fC z_6K>}0BweU5%>Bw$Sm;3JzW|00~XCEaVBvJ12^E|YKXkNhv+n(wlx5jcv>a>yg?d zrH399iMduTV{EK=#MtnQ@n+XO9m57=r^j{Z!*-!KLE3xy#x7JYL6ce;uHo9?dN(RH za&&X{zv+0)a{@wJgt6f*%hh_fT@iM%>_9&D2Z+3HXjd)d6&6;_TlE17#I}Q6i_yiJ zO#U!l_3#)k4?4!hGpcc!3rl{X7|@3-U;2VpSEX%{Q=)NJO~)W4ua-NFV^;Ygs!pJW zPHYP_uw%!`N!ox>8*+Kq@44#@5HoA$k!PTAphr$7;vXILSr-CiTnr6ByA_V?tZ6I{ z7Z+h^+S@UzC1A+t&2GL3?x0O2wy=T)4H0doK@*eI6{#LP;WGqIY@S>=eVCed-mgOo z3i^#8lYkNANxsrOddTnCnDGJZZwEwmlF>wuYiOIE=zUoRW2@~)!BS%7oX(&g81(2tW$Cu%}E5Ld05pP zZsu5Wqo901c>o4^5g&WFO^Tu*8XYR{p+M_gpIT4K_kBJk(WB9Z#NPjNu}L~S+Crog zPx=`^oVU=sbtLz?eNJA__W8a zn84Vq25OT!F!{2=(hctLJ))?|`wSB_NcnaQz)Y3il%D-iYe*&Pf zeqJIK{Q6hSlxw();Zj5?DYfmL!T#d4J$ULZ?y!$F8f)f7L0fz&`bf-p3&t?YI2+2r z=Rmd8eFE+ZT0}B{P3Mk`(0)#$u0_;Mj3d;A87b)qEn#oC zWT?Cq5&o&?D;gus`ZkUyOC;$116tcJVg$w@3ISMWbbR_k3Fp7n`%oj#-%SO6jTMmL z-`Uy=YR;oNFS1sF>dkq+F9De)>=TkL3Ag}=$VLaCbj@ypnEs3^7M&?PXc~sn`?@J8 zvdves14qhjtcWcpR?_?USG!k41QVtDcv^p(yT+o#DGMqEU7f#^jev>gw9Z}%g7zh0 z+nWyO2qUjBtqgtME9?{F8}CowDF)^*_#lu`$^6-gDp)XoYl+Fp^+ye|DP{=>W;%6I z0c(v=uR`)#_y9oXaOQKEh#D4imkwh{t$3(qQ?3QwZ+pkK);LiFI12^#8{hB(8-YE$ zKAch(* zf1A$nXOg#-0=2M4r;Ya$kgbUc;W=UAU`~`q{FN!)GBmyiNl>~eKt3hYb4)Jt{Keq# z30FOl3C3s9x7YY`)Z{2X;51Vg!WwHM39~-By7^R4DAb3r$Nin0^V-1ch5Ne9LHOV3 z2>Q0+Fst@6>%=MW{35O=O;(|g_0#7&q`mQAdF-&) zs3+FfGnUQk*lvg2sOBQSuhum2yk_^o+L!RX?Bli^HL4}6Hiy5yKuocj14sj)y7THm z_z)ML$cv(!^Cc!aq(4V}H4+;YP>nYJSG=MRTmhJR_$7M#7o*!!Lpu*l>YjjP0`?JDp}Ks2LE$`jq# znj=1I0fWc?r@%&>(>IHOwd#I;WS%x|Yo0(wE^GVGS$7vg(&HF&1#AA!_$RXtTlWk% zIG&5}kxs0YbzkWVp|Ji$w*qWJZNU=(9O((3{&j5s>@>k{mh2@wk^Rl%+IU~{|Co_o zuvfB(O%hu({*)>?=pUYAB*>at^{1Q%WY{2TsN3uAIVJA<7?C`Sp5gs~X1$#JzM#25_%=!{v1l7c1~CGHqzxT%Aw zd-YJQ3oMwXG>Xob@4bk7$2dW~A~u^=a>>d!5IJB5 zOY5mfBTxhmoZ4<1=h1ILNvU)o$sGiNXn`OnRaICZExBDP6ICvcIE;iEP;4Uy4h{>X z(VC1$n);jierbWW%vHr{0z4Zb&Olf))nA!SFErJZ6bR>YiS6czX5E*&_}49xQd5(jP!4~>>Wll7y z)JO27a{PU{?9y;|KQcQ$>pIUiGJ~H$?_KWoL}26CQI}}nn7=jQP%aswiF7Im+xgy8 ziPgCtM)-~NDk+1tQy%LWO_;A#;K={B?3EDr^a1v8>j}^^ur1D?MpuCq!+8W_V!T^5 zCqBnp+hYuLbT0MPNS-SeCJCL9j6WmR-!rmN@jqEQ`m+-2@>Y8k9d0tB&+l~G6NB3D~4dwO9cRavn9M<^0daIQb%LM$&L??-cpqOG24Az8)1uf(K zLi`z*Q>QRF&^Ox{;9}TxS3!5R%Y}FMKFYJ0#FUZ<3nR zOd}SCVgRMYk(MgCb4ivo=#;TBm#;F}5O$YY{GpQdC?kylu0g4m40yzXLioTfKij^nHIy3P%U5Ms$)fGhvre zSjCDAPkW-l-o!;UK}{%TpqXBa1XwF-M0bQ7<*k^g1QHFl1l7469Vr&DY6hsOyb)r? z_RZWNXv5BB|I$U!JH7tjrt_m0Tm{ft+sa}I5ydIP1wnV9K-Xcvy{P z+fq=rt8Hf-JD(KjoP!Xl@dTv=+Na3T2Y7qs9uBPw_5AouPX6TR4g)A+~_$L}ZBqZc; z%hYlF9o`0Ua0I>KV7C4S57!=rU+Ea~(mgkE8`H7r5VMKQ&K?J8+Q zmwx$nMhharq#2xoKt{HAh9=3yvEOcDtvu5HZVc&SA%>1-?6(DzGdR(85LK8W*v;cb zdUwVWnhhS&VQlUl*$I?npsuZ7)P(ZUI}bhP!x~NB%d8pFEH>oUk>Ng=9M6?0HZ`T) zJ_jH7I)@5R#}!$x9!f;7PXa)$c3}kXmdZ&hr5%yJ{!Qjf)+mI;XZM3``;q!v>tS;O zQON8Lml8#C%8`NIIRtdEPKA~$s$cfxu@1_9!ynU>T^9P}f!l49>Z18no6?89J;Y5{ z@Ac8qb?>=2IE!18vjturudQH^%TrmrmkSule%6i*$kIXnmyAJXXAAvH z)dw}JFhT(q_eugm7wCnx9>rMFwtM;?Fy)mtq&EGARtr9{^NqoN;DPzvmYirqic1+n zVnl%u8a%thn-}9Fi%S7*tYsZ+@B;CE{K$ID-&+mzfJ0<_VbswmiuIqL2dE_|*^eUa zoVTuxzk#|I0hsC8;}B~Of|@XJZsx>ZHeswwlC8KP{bVlH*tUYHdl6ihY01hg(?BB3 zYnk|^ajk|oi>4;$q_82I591ercT$r#h{p`voP$#10}gCOEd5AikW;Q(3LJ8Brh<(l ziP>?Q?s{3onKnZ+@uYH~WciO710LvlWk<%utr?Td^>>nl4{P3h56^Ga8upYj`ErHJ zPUpz*d|-?;_9y!{MQHjdt$3e)a9sGIO)L>W3Cr)7CkblOEXC=VjahmOh?8Z^d$bvm z>x&87-Q|Q^ybD$gZZ?Bh1nsDX_YHc~MRjR%ZZ#zKtDqLL-;%5X4L} z<11m`xgi`6?$<-xK{|`Tp@O?(*-or&VZcg$(VBCRx4Q#%#zs z<8eeR^PPB8wJ=riY{g18n9kR5N}kL5M)r7LSJDei^f#btIVhRL!PNA%v!X0mN}RQ; z(Ksc1?y2Rq)v)6&`?Vd77#2DOT%VrN3@D@~=qguTpst zOEbK@N`mv*W2)(6cCb@YFgJTr+Tq1BL}+BPQ)hLC%QcQxP}MwwOr7s*2;*H>cz2Z4 zKhUr?N(k8B2yW`I8b}no06FpPT6=tL&DI3rU7Nw0dWKg!q5Cbb)=8A*U z_g!2LEvj#8Dd{LPr?pijLe{|2D9n@$G}#6x=RbBP=N7}jX`8)hZY0XKhu!|2EF;u;B8Gz{s$`%ind-(@xF-LN9Hp3!_rX3c1W#*gwf-w9 zpTLl4wq;f_=y=O9_ikDe!b3y z%?0Og;FEh-*0dh6s*?!Mp&74ac9@8RIj4G29+;WF#>A0;2HzS^Cn4MLVr01JSUXKc z>ZiE#aoP+zZ4?p=qVb;h(^4c7u-^;)FJg=EC0k(fn~MuCcqrK3820P%TGFThL%}WZ z)~30jBr5qK%I1fGSHmA+@29v}|f&u+t9e0yTa#!uJz5%JW~? zU=uCzCCc%thq!zDn|;F#L)&!tN@*zwjgrDqPen4gAbi^1Hk@!e^a^4*C^kIAguT8q zX7_-^1EFvGGMVXF-OI?v379UV*zpsdig!~iND0Z208;0dde`~?j82sFNfE`!qZ_fq z`V6hq$vfV!K}^I=I!uls$$a|+-8)c5C+yxd89AbjBkxQ_%mfLcb_7>lWW-6US*f*& zPJw&wz2#<7efWQ*t4{F0q4qXQ$9{|`=G+k`$v)rh4l;glSTV7J!D*UG+mV0B&Os*Z z6oJPzd*dPC8U?0ANyy`Z`bdGA9l$~K^fJK2rAy~LPh8*Q8p z6RP}RL&FO+@UBDQ^KOT8`ai!!hikLw79@n)Fy596T~OIZ$e{si2Rxk8AGT0h2})!r z|AA5GM!EpuV{s;K^sO@2suMM5Har%mn+r`p%C1}XxA%j2Tl-cFWx!YupbR;#*zE`J zoI5aI-$;DUgfhiGoK?4!r{UNOpPYuRGS}0aqb(-IN>;bVwtFjSb=wy)Zl7#M(N$>0 z)={;ts~TcMHO51F6CQgIjC``<1N`0u!4{vf#Z55`lmCuC4-}WU;RUAe>PQ1T_CCEQ zu44hf^`h5C<$R%?=PrlY>s?>jqwn2G1ex z$KYt$*aSg)vSxYD0I5)gI(oR3M>|3)7vF^#>em%YEA8@{X6<#=9}4@JaZ#hdZFAAl zB~Cr-dE2bvcO#=b2<6$a=9(84$od}#1FA(5?<)csYVc7y9RN{4Ci(&U+*vLLHU0Mu z;ve^Y*%Oy}R*r>Bm^RChvpWtmXnPeT3Qn$5D-eU8w^&%#wyadtm%T8c7EpL9er8kB z>m7{UDDs=-@Bh@*dV;YHsPM8)Mj+>y6>5Dm-qYOI;1#LKXABeSn^)QxW$Rys)836Q z-Ks2k8jtc^Zq5<;pBeUN5Jw$oF7QpS;CP5d3Aqp#z8s0muJfJ??@BY+6jcEGrYP*( zuabLggbAvzPQXE;|nKyXeci1J$d7i`1G6@deLl;Ll7%qYq}8 zbU9YUNJiCJi5Vym)G3obQI~fpq*w%b+=uv1RU#Qtkaqqfav>eKu`j$hA%n^gv^H3b)7oQdJk;RHK zJ+U--&0bfWV|)P2et8eo68ne(56%Caa!Ws31W!Ae9&z|Y2MX7UQ#x1`SM~*}7YPwY zl1v574#1XcW|SH!zBM&>c2ZcYjI5oCwZpGJbOXCzD~FLC_YYb9w0&D;X`bGp?&D~S z$JjoLLs0)>&NkH=Q%;3Wsq!ulk4`!CWagDJd7Hv~tK5?Ub}78^3yI&@Pmcfed{=A7 ziz6JqdYjc=-HeW4|AZGRKFmaOq5>4)vGH7?gT$Y{_NPA1_97_k;p{aZt_k&QbSBD% zu$z4!jw~Rn7nb!sp<97d?MMc0O6d8i`S=e~%M(~|`ufs|Bv2(StZ61%lw-j29g9dK z&_|y&jMo(?qK?PzJV$O=oF zSRc#O=D97#L$1M0$AHG>4VI@rd_p+N@{?170KQ|?+D){&&*K5457%{xQp(>RMWqo} zaxx~vuGzFAb+^|I|gEbk5{kpGJ0) zzcZ*>_*rj_HJ9&`EWqR&&i=wub~qX_4M$5&wX_l80A3Z=d`46}WO16h)x<=83^yLbsfDC+1lz;||IVfVC5 z89fa9Vg2YK{XV`EdU%MUdOKUXcW6A|!H^U6LyX*!Etnppxc!Pe~Yx2Fl@4e2{p}jDc01{mJAF|`;p5_HcclB04Z?>#Fb54o1wZ0@8%iGcz7hT_F zJUxNV+sf~)64X)C?-$^aU2#)xZ9qNKqhko&UOsY<{rm#^m-w-NuG{#O30;dbXzomT zm!=EZBCNw~>H|mWejt7`{BvR=HSI9a{qM%MRXHN&qm`&we|NsIs0QFQ%6gU*1w(mR zEXHHB@M%!prK#P|pFKX&a+q#%7=Nd%Tk%p#CxHP>y~H&XnQPU;$?kYJ{xCA$H6xji zhFwD2`+7h)TXR0Hsg*%VDn>wr_0p}zOImp8$=%LO3!p<%An~N9Kzqz^lnVrn>v7XG+Jc+L4Y*gdRtP-?J{0qx4qc*7-!V6 z9v^Gd*e9(QKi|AQ0HS>H19!6`z06&=Z>u@f7NU)jUPXhFqcBHGs!sr^j1S(pTZS?G zH^uX!G%B|ms}Vcli0EsPXw|-IX(*STjhUbTT~wZpI052aP}WeyR$LG@znSl@m>D}% zHq`lBOg5eCA(Utz6!LpqAboz}7W*LgfN{ohp$sIdZuFD>tgje|o#Os7fGXQtTBd}F zAvAM@x3n+lMsXKy(;ZflBU5>TZYyPsC5Z@EyGvA5z7_LXN9>>4 z^5-K5^25SiJ?^AA3pP_k6IO_d9ya~MrPjI;MwrP08fDl9X0J+}b#6x4Lw^Qiz zsN;Jc%#gPo#@6$kkCnIHf?Qof+(>N60UPvPptfjLfA4v^Iuci4S)^$)%%2$^k?xTh{;%sI`addPR-3&NPLZfxnv_Jz7V%)lIrwDh@sajSAY&|Guf-oW{bj0oa0)hDgA725MWA zR*0WT3`}D0dtK!()$srSput#t?8zF;kGV<43a8AJ=PCr85u)>~sy5(k`k#{3&GBFj zM|)5P1C3EFsXeEB83N+$kG*cN6yKU_?PZnTRDq>V(Z=f$r>qERx=jjP*m6Ifz0@VR zVf2GpN<*q^+cD!@(jl+>;ghEvIJO{+8>dzA)5`SZdmgLqYp~ueRS6kFwJK;wNH4UD z##58(_xNd_(R9<;v&TkP-#n$Vip1#r*UR=TKm0x9%|ETE3XA#(8oTbRx=w31uL2ds z#n8LXZ&NZMrIsq=z~o_be8j9}VjcbwvA<4hlT9#fMq!g#>#LDaku7(9ShDulm!&aX8;TX&BU%aTA;9+U4Hxnjdq zV*8gziy3;1uwmC275m#^_1yGcgc&s9RGJUprI9iN&$WSiLAi@VtuJk;6j$yL^!Yp0 zx9Dv-+Tcbrg2#_)Jqno;a7yQaQ*$z$Y*3a?$`QeJo+-QFwx>^DFql;Q-0&A0McVOo9-n9QhXQ2fjlk^u*WJC!nWLez50jnMw>b2Z(H9pVJfL zw97u)l*U3J?Q4*|S^|;)Uhu>zZwzHtR?`@=pTw%$;eF^EP*fA{0^xz&gwfYg*$aAj zD_W3I`kOJ&44wzC7h(iqrO3h#vr8QlLR$3r{T@t0$IKb%JBzN;sa!(Z+AK@W5`3jhmT9OJ3TZZ3qjtBNSP zI$f@3fK6m%+gXdQHG8p9po0=>toPuctWjVBC4Z4!kvcT?8T<1r!n@&6NxXVlXZgGx z@!$;`+~!*}eXQ<(DJo-1D=(h+6mW7m1gUh4XP#@Tf1PHpj$lWFQ%6#!a~thO|Iu%g zj0lF1WP4|fb;i8Z>udrT6Gv|JXT6{qFz?^yVleCOOC6v&>1~?05_+KOEuAhtDZQ-O z^DlQ4Zoq=-bRRY25Sc!5!s<684T&WA!*2+W3zn^ZjHx1k4KGkfLbEXUgx^3YQuP2f z$B)0~<<@}S$bPDBG_+(+(Uv8B$vi$dVLYtN&g$^!hpc3$E?1kMefV%YnF2wapc3O0 zd(-^YUk+nP+~lifEjh~%3nMe35>QBBAr=w8+a{x%21TG!K9(IZR$#djx8olUiwC|4 z9`w8NKuvk%A@D$J@H5V(7{96wes700Uv)qb0fi?Q^ICOiRi&k$L>UF%|tQZmvINCP58@P@LuoIq#BUn$mSp zC4u=SK;{{H7Ir0rd}<#KqW5*SJCVPaAYKvaPW2ZNps(L6blo-B?L`d>V2?%~_G3_N zi`jS13^OXvKD|NbfeVCfh3`~}=)+r#7!^y_$~1iq1X;ekN(Dk}5qgl_YFDC8SsOZ| zf4v367podAK+p*yJRNN`1I;JVMvB7@=LmjoJ1r)X{`oo)o5N?+vety-$%9Pn*9#|%Q~89d0@*Gy_g|v6Q zj!=R6LqS4afRgX~epefn8-w}p#wb}Rka6=|Y*^@j*13E|IvN^efR+yMWOKIVRS@PE8D`#<+sueH^V3byij_ZH@$9ulUt|@FqRNF zeeSWMVkltdHHjv=>l{0Z2UDskW+$S{r^lo%Ay0IYgJf4rmh*U@h5EEq8+)K$H)_IG|{oer55* zt~ivbhW(k%d~hwBj3ezYSbz$;zA%p0(M|XAiKvyB=qYVuUU%e%IY1k*U7MW0XnhUY~|Vx!!GP~8w=6Qjxf{WdpU{AxwTqY~pVH;*VJjgL zt+JTQ?Z!rzbBK~Tm+li{Kjn`sQMe9~;U-C8#!4;KXaTA>&x>HCo=e6JEX!KGCgce- zSgF%)iL>}XcKP4}vxC`Rlo~OK$dG!EIAD3Ykn@CazSxNr6vNRL=k1s`t(X?7N$eeV z5xC)g{rEu={j~0@IIlL8-b)-)I0q=*9p)L;5aiD%OV(WJpGrmUvRvu({}s=QF{ ze^cM`I z5FP_vU*8z`W%fGdw1{q7^NP)JrTjzmdvQStm`yMjkVgf80$ zrZf{e_oxaY9K3$=Z>68{-mAYqRUL3bQAGCu-K|kv(=W0cYo%{TjxYHp}-mIPPBcTcCTbRZbWa-aW(?CRQ7JNu=NezKdPZ)e>1g3;)6 z*TDT6+T&|>{tiEH6*ST_>^})kx`Me!$B0SiUD@HJRhuJB4^mJz0&(RfhgFtp&r_2? zq~v*O5{-`Pf$zLTL%)*&8KV zR07|sv34P_Zrth&pm-ozLPB(9B&d#k1r5=uH!Ay^ee}A##HKF~%X}A}spQ)3!Lo0WeEY%xNI= z1g$@-EqOa&#^NRPjlNBn@cS43X!e<&hT_LAX`-~~_24|jUCg(&DkwJep{<$H356&m zb}m0Df^uO6?%madiGlrJ)Em1Z3|*%Qm?#{73BUXj9oR_zvc(70GEhxsmc1%67Kvd$ z2LM}s=mV`lhZ=JQ8hm|z9bu97l0FX0td0JNzdRmrz)A?_-uc<7%K`Dk00l5}l^zM~|D;2! z(MpcRNznf*i1HOSlY72jKLfo{vD*O0=nBK|T}^~?K;M6BluF-biO~%TJuSe+Q6+Tq zARGCY~DXs(gG8Uf?IJ zMt|2eK&+&9FWx!etF8z`8KyZM&$2!e~-7w`a>jZ1{s$B zF@NsJju$I0&m2qmt`<~xOEgvoOHgc^ZFkn*r)PLvLIy#IPIvPN{$+t>7eOGH+-*o& zyC0vb9ubg<2Ct{zCg^ZoEp=p(cE|^b4kbwO^Y#cYe@@K}jW?hC(2stncxf2@akewD zGS2cTyx_GTGC1pkd<^lw7Q)#q0a8l~a-RWe`^MNg)H~fL-70x7Kp(sTJDJOl$TEda z*u+Hw_M0^nE;-T*p2}2eFq|IcOMnc6<3X!fd4%VHWs7u zW=61e|FuD9;JTbn>jUcR0HL`C6h{^2ppEO4>S_XK|KF$Si zly4{(9#3}xu1KNmaL}s%%Ad6 zReMcNo7?(-a7yaWz`$dv#ND!n1Xaw+>mQg(S~%oP%@REiw_4~-1J7cJLN6UqJ%49EOZ|pS&-`G(JW}Q` z_r~Awy;KM9COo1)jZ)f=;Hzf)33jwkkCceYx;mj0UZ`Hj5?~8o*I8qI2YuY|SfD%~ zh%cW2Cu2A0NauL)0Nyks0D$c!=r>}fQvLO^0}Shgv~~)OuNAm>fuVdb!P=`o8tj!k zy+i)B4Jg>8nLBc4ae#=&B5xV5hmy*`B4+&9w}>S|7;g>_8h9ArE;4jp|FIPo;=)U3 zYYiqNX`^WDuFF}!1;H%FgmQ`YktBHfw3C7;UAJ0L8<~rmi?yFGsvm$ zx+#|`ATd&BcC#bf?PQ9W+K5cEp68OVD;u{^HJ=n{UZnn}x^&#V!M@!$E$Iu0XK+Dc z5`2^lhtaqvA<9El2vTubG#F36lvEhXI&YSLC{donWK5O{b!&Sms&(-=R7j)rS_s!_-QQj>aR-W{B#12)XTxCekDJAgkMujXb;Rbo<%$4dE{C;o}hpXoUKfYFtEa~u70onK1H zO}0D9IQd8I^;RNbB|a3y78s)yaVdSZWHz=(g4w#KUDU2CctR0=!V)HsJ}+; zo5-;rw~2i$>}z)4qJ3(62@Cn*I{~BOxsho`m>NocoJ@ow3Soeo4qFS)5s-gHw*6Xj zPv=lGpzP2YL~|uqGs-D2NNmV+g|Z;k@5kL)k=6k)mzV$17LduY`j%A2+l&DAvwnJs z20Bo`X5cx_p6TxBaP#e3N2ot-{^HT$jU&M@Zw>Qrct6Nhv$Ibh6k5iGEsDFTx4dpl z5i~f>rlo+?oQW}a=s>6<3F~Aw0+W|tc=M*Pj+ki5OZSyMpFaF%yl02l@?J@}3U)nH~{fd&1DPw-%0hy54fIltQZs!P7kLH7-C`(DZNvp>6 zk)juLn*Arac+vZ9CO?rDCZWkte|V4A6|G@rAljvjfHTSQ{CpQE-tL%Y6vw>KM@+Cl z)O)b|)#>n6)*w26ml!pqavR;QAfL}EiFbjf-8y5j*lOed zPN?a8?{%o234@Wd&5d1MJKeKxk&rALjnF9Ya+@DjeA13NTX~HCo*WX=_)=WRzZv2r z)9=0sf~=8|s0nU^lgQi}0{ac*YXNvvo2OAV0iaVgjF3=0a-bFu zyIua=C>D3lwyX;nkKcp(R{pW_w#6+%d83f_i3@PB@)5S#lFa(HNI`%^(_r_MH%BRR zi`df6|9MN3Z4E91$wFIzWY=doWtvRhNn&5&SG*xw5PLo|z-y+@9rtM%0uv0Fzg$@B z!Ie4P)AaH761xxlWF*pBA95*{yrUVe72*7818egq`A4Tav%+!mlz?vGNN*5q6K!jL zgEw5Mpv(uKzV6o5A_iAPr2>Shj05|(9jmladBo+=J0*T*zxqZui|t#7l^J>#W`B#v zaXR2NY2PCWprnu&i!-syp_;~`7eb49PAD#qmjfG{Rj8Me!DIze^pc!iEtUCS{Qfr< z2j^q=YgVy_M6OpgrpK~1@&hT@)`Suo-O+?)ugwF>Q8BErqE1MscXMIP?rfcWBRY$^ zekkpRY4KX7{Q5N&BX(+G5-@G}#>YXuHoV zh-|IOJ(T>PufWPn)g@vZ*-_G$U`Ea>wMQ(8eh%L7$)^+M7p9F#^C0{k>o`o?$o$R7 z7dF@Q9HnlT{<7=-ws&WwhN0h|j{?oq2XL_piSo3UH%{ z(JcrFCikkx*Rb?9-ug2obb1<{(4Qx2P z)SeKG$2XD^MOKhl+Qfq$m=Rs@X6UW%Asz|BjT@8~18-*6L=R(Egbo2;L9$RZ4oStn z8H(=0!Z4@;sNHTchFus`=g$-XhpHYiCI(Y+TAVL7VE`){R z{!tGD5Z>Rw(t1rz%68+^9ggUPp~Fg$_6ZW=?DUl}rGr3%oovgv0v?#&sMcYEVrula zO3P($E?Lik=ZQRRZ?_Q$^K>lpspuMt;(&r5pSE=i@J>OL=$;9Wp-W}q;AY!L7l-Ag zn9(vXycP1rFt_yojbSoT1E8U>Rj(}YeKV-E0Q$-`ugB-s+nnpl z{2bAJPN_l*Oi|oYIxqvwvIa!ex%K$ zOqT=?yYGsW*e`zen3qOD`DNf8=Pd7S zHTIz{e+v=V19}Vc-OKH%>g*=vt>U9N{Uor6KhahqW#`7A3;$u$>T0zfaFSW+C%u@N zuFyGn5!M}B1vj7^2ef4>*6T9Gp77VCjuZ^uD`|<+`rHwT-b@U=D(PcX;UcdRQnk&# z17ZQ_SkzUNq9S)?r9+xt;8|RGNNobT3sk**q1Zp3 z>V#u|aRW=6<57o;Va)9({Oz=p8qLF-dn$%~@@sceBu%bpj6{1924hcu1Mqi zoW2cW;(U1HbjAY`ON=ML9$eWOAcf29{Q)6Tm!MW(zV-v&{NmWk6rx>#2(*=!U=+h&8pFr?M&bhpBPH_>w%sSu?zrlW?Q0C-$+ALSwr?(?SIqs>2>d+?&9oH&BcF1a@9P^utOy30o9zUrb@+jbOM6657+?C2}}$1mj5dQaW@mqB{T8Y*szzk7+yg zKJ`TZaVvP@)zu_G_fnam!N?DC#TV!}w@tRVEKAg>Vpk4v+VK>XTT#bu-{bno6{Dlu zKE_N4O^jiUx{Xtphp>U;_FfvGT^bw6aaX%t0|uB|o{ zabRvg2r^_{D-o<>I*2~cCYVpC^>4g1|7sx9xM_yO`*ucI>18pBEcy8h1)00F zwB3;~-8O9sz(=9Fm-Jn>2h(l(7r700syrqGratVKz`V}{3TER1N0zi4(L7TUwRm9w zLWH2ao2lC#4ji)mbgv4j<|=YgzsjMk_0$ar5Vtcum7b)hc9yG``hal^A=)BUr$oNkvo=IWzBh>PX`s&jvs8 zv0kbO>Y4h<5}0ey1phdT1L(`3!^Lng$|bz}(hlm=%Q{jnPn$!wLYe?oDw+%?9v%xi zz8X2dzJ`qM?`etBdLa5ez^7QfyoqGLNqfhl4lT*XSoG=x5SJesn>SiIxm>(V0^KC) zA$51C30LyNE=l+wv#YE;b`!WA{~%Q@n)F*BKQ6mru}fD)PcL!_!#nF8vZX5T`@7$DVA zsJ9rHKVud*L3^=m(*nuY{}%DRHs%xlO-~QINh)B((sd$kfA#N>Z{1ed?k&fz-U7TFT%1tn>6e&Co!Nkxt2%auonQK*GNd zit*V_>SRw!M2ds2b49*BA1knI<}3`XQ-Q*T()>eKV$N!7!$uffM(W$Fe6?TF!P32) z?JysB`=A*!oH-Yq)+C;sQB>;Gxj#iq5xtu6{F@$NZufjJdUcK8C^SqXKA>{UQu$)D zW4RiU)*oTmn^=8wzdEqB^kPy1YIsx#n3)o8F|nA(K#SZ z2d+IRmr9n~`>bY?R~=W_vJAs!i@=i6z37zlmGcfW@onoguCU0xCtb{0&w@p3ugDjS_-fjX(mDZjHwQ(8HRS8xtZ+#)YLoBuV&aFVK3Og9+?b zi?_zZ`Q2mBJ=(r=x^`m?ePUxQv+w?Ad4|JiCUS~wa}x)?*hhPw7n&yH^k7LR$*d(I zQ^33#au_%9m}JAMmB$P4@KFLt8?b=>V7B6RAmmj7?bRdpcscf6Q#1-+?!$mA7NU&6 zQk#XkF7QmOft_7UT&Rq%R+#uDzlFsUysCq8(t4+O0^YfUMsCc5eiPl73wkg{x zuRL5TYr@-h8ZGilkD&sjEBbETCHJJyLDS2Xl*=TBE&GeHP2vO#v0IPALODF9$ zIN2!6QSE!ZN}h~&pb-SCUI5}!=X{MgdVliYO*^k0VPl!J-MR_&Eu#vH)|c|JM#Kl) z1wtEcc6mQR?qFCVTy;-mr2u^=3DyA<8l@sF%8Vnop0JdCDEBE9Z4w|FMl#KrA%0u{ zJfg?hp#gpomcaSBz8B?ap841ejt5cqRYNJa^Fl@Mq`g4^AOXaNZDE$ZgWbId0_Jpm zJf`(eveYF4<9v{^3=Yr%0Ph`Iku2LVlbnBuoVPGKKQ5|*`{IX3c8;StGsbATqq%1i zZZ*gvn6>Q!iBoBI!Er3QpbPRla#LTkn)obQceZ-_Yc?uZbK2H2oNko-%(_OKBQ^Et zYPf`)kFWoB=1aE9qTkl&t0FsJt3EVn7_`_@sw$-o$V4ZMRW-cs!EoLL<3?+A4GmqE zYD0U_t9PBYoGgoDtf8+d=t1WVQ?%l$C~{A5#F4cbL|l~)xH1${6D zeC|+L`COUp$TEhvGnNfhGs0T`XyiAYEEKBB`>^+~ zT`w+dT`z#d_4GlmV`D{NWSuzC7c1A>s7`80Ik4G}kF)b+Cjot*cVAE17a9 z8-AD?R7ldH7JE1r3P@EU?K|Y6o?=K*%7l_U>W58xX;Z;SENfW^fnjV9G_XGdV&uOV z*#O3t;yL>tufu925FjENM5EMfLftI;vGGXT`Bova03=2Lr9>lr5&uh+VZbs{JtED?J((!Sbp2HAbfzbSpoPxSe=Z_b34)2SUXnf(DQf9qC#HcTK zZRgFoZeG-Rlp$%s2|rO=nDA;3{*~o9WlM@GxQg1xN}47Ml0tZ^Q^EJw4zAD->U5yr z=qDZ&mA=UvJbtP-1~8Om?t|C#zvyjfU;L@9nH)J#Ze2f7QCCS^*cxzW@6jcTkM6|( zHX~1k^afmn4GE9W79chdHMEvPEciP?NheaPRQk7;c)+lP{2LyM?xB1&Y{5 zl`2$b^mk91-U=UgJ*R?8o9WhM1&orMh>~XL{OAE?)Nvyh3bPs2+Y^nPi}$UV;(u1c z$99ts2CLgXjfVh1VB5~2FYUSP4bSs+ON4^^KL_Cp9&GFi!p& zwOo_^l`!hu3llt$E%Fy=Si`exMz-xu`F-d7ARZCK^XLV2vjfH7AC!q(;(s)SkuEI5SlFH>$H z6+95W2mBw|Cz#qOMt%lOfPeJxw>G*D$^bz(3qflC<&R*gavQNqeZc#eQ<0BGi31L~ z-qO^ZCKZ>=XFGtnXR@rDVYeTrarquThNrR0G|C_&%N3|S zjwUpb$5dme8Vcu_FJSH@692GcNtk>^aTD0}Tms^oik1o7Z#oY4)?+qcvpqi%g&tYJ z0+Jl`zJKnaOr4;^5o{xPP>djjRL_ervRc{GKx}Y z1=tucZdo`pI7PY9X)l4pXj^kemh0hX9I@f6w#}Ic57*g51`-x=N-mAHV;S6gi_$*F zkYBd)3@%@%)oH|=pv2NiQ6A4yd!w~ji_Wcf%2I9`n35&(Do5A*IBy=fiu%G3p@e^$ z`EMO+=Qs%(6(iJBCq76et?4Q-X?^*|L)PYP$;|~Txv^VN6i|J?t9biySf~r+i&p0u?3n-E}*~p^mGvMsYQK|22zQ z)o%|09*z^gK$$0D%1F-V)dJB{c3*X%YVLgjjUjlRl!>F-|e zYjOZY;=YCuPNC(ZK*2tV=zRZm0<@bS%Kg?i@M#sM&dnP!iZ%tulw3jbC6AmMq1YKB zXjhlO+DL?ei&fV$qpMefIzdMv4vKZ093Q@Ws<^0|(OpRPWR$i=Hy7$)^C<6~75HDa zb}wCbzGGp){Tgl+jGC1Q5vqduQx}t&vJ7zKBtZ(&d0cisV~aW;GaB}wuG24xwzW~} zwLD~{d}T3}rTX132AGwCsRnV!bWw+b&|h9iL>3Xb_DY}3CUmcx{m{A_8^%9G#~`=H zwBo*6DEo#3fsi{FH^%^HyPm?GJqqT6Zo4?}J{@Kc$FOaZh*&TOw9pqbl3I{Xj8`m%lh(FS`q}J;F zIHebh1Z&UA43uv{_F}YM7U2bVXnUrdpKe;praQrT-l?&!=S}D_(H7GD4gvkMcv6Oc zk#M%3_&to*m%SV(`?I7|;i2To+~1&_dUUV@3qQ8ZjKST4)TS{?X*+4Lf;*uD8o6JF z*T)NzLf?z!sgF2;U8_f!Ot#!JKWLaB>B`^q3p}<}H zo!>MdTy6%xT?KTMx8p=3kzUNd2O9nHX-ZoUJn_s9v1I7j~ zTy`dIzL$!JRHVXN-dqi8(0_~L&Y^l52BP0VcP?=Myo3hNOKn>~M^)US*g$>1YJ(it zV9P_Rep2eQ)W8l$N-I=48hr{6lefnNo}W7?C(Sd~AdUJ)eeg#44)jBH7uExgGo-Mp zM8QBGx^2Y2&M=dKP6i%CbhbrfU^h%vX66YWvjo1{l@dYb@HkK1BdV}Ec7!Yju#e)O2adVf?Dl< z!O!wUIi7Igq*6$_N+;OQAH&ScCLs|%r?N12FscD^Tee1st)N$W_orZ6HczJOW6q~Z z+GOpUS4?hD{+a7D;SFU5eUm0}qcwYA0a{$eXnJh0zDB3czv5+x1Ws!KaxWFnw4Ot8 zCy4OK&&LB&#c|nnI#Nls+^|$Uiv@Hu!T0FR!zS4IB#lKAu4-cL_ou{2ca=$ddb3C2 zYhBUCkTkr?fOoR@k|vb%371vidi}ha_NcDglpX)^x(+E4Tg_a8-6ywdmyIODoGxke zRWSOY!2is0dT0HvhIi?=qi5_qy-f)F7di?ZyS?MKd{@C9EHw&vAJo9QR3OP)BJH~e zYC8$=tyf>eQnr(RZ?k)nLXE=<-SFmo=yn$x*jkaEHv)>v#xG-rpY8G3k61o3PuX$! zR>jAOyDN2Q{;4@Otv6I#Y5pWr_H8(?=R=1czuRx>23iihUO=U{*7(}@zUwr5tm-wI zm!8APt;93%pzwXKNZiN+9Dp}pS2vJ@4wMiH^Jh?g87{Q*5CTgedp_NLh`i{A%4kZA zC+^j9Qa)Y2#rj-ta#NPW?2>tv4o)}foOmy>6QYMmIY9CU{ zZD$>&mj%q8#gTdlYHYNV@2-rt(SeZlz@Lku-$e#ntpemS9UJ?E?Xb(MY8}miCo2a= zyNTV!&v@eq=#dpT{yp?@bxQ*1`Sg+^-33TZtT$EX6OyJeZ(q>O*3o9uX0Lmz3 z46<<)<}?!p%w~y={ub+~ZNkT3uJRSCzGH7$LKutx@dL z9%hU%Rt4%akIS1HKne)yAGN(q833Te`VX@;EWU;9)OB=vIMK*qzJ!90@L`Z1bKV0VY%9prJtn7Q2c5dpC0O(hwvvpwtiEtmA@@$6U6s4v`KdzKwp_13wL zxc}cSY@)rgWsX#eYMK{2u05$;%jZs=Res?C%?XeJ5yzHoF^7VBYwT(Xl{nz+jw)Yr zN5Bbsrfjg-){{>;U)=D6e+56ud-~UWez9^`)lJJEWHM7%Qw$FH77>ch6`zjP;L5qz zU}cV=v@375P`J#D&%5pztx8tJijfcJ!IjO~Ld5*P^q{rNzMi#4^AcUFPog=n%vGpc zS0wcWDo1fXx`x=cyrc4wuy4NuRW_J)k147Mg(x@}W<-`)x>&_j-!+Ytr?qP@$LsK9 zf}+Yi5HJtOIuG6``EsK#aK&x~NcwTow9g&pfSvl-tPs^uwrZ#NXv3sDuZ~5`Tih&? z4pT{#rx@}cjqtiSYmd82@k2=2`R@!r0o`;fjlwCxp}GqtJMge%lurfyDK%d+26wT{ z&X}MW^QqN^BcQ{}Xh|)9wn&WV*4$y=a%VGCuoSDA25e7Jx^p`LAr8u<#x#dSy*Yvx zV~h@MBL0WnFuB(v%Jfwyod#bdv8j^Y71#0E0Ir5v+?Mxm0=3pyqwBOFhC)9&FZl5E z7Yrj?JMto8!!$T8Vy*^0JTiPqn=NoSR{5^;8YFO&I8{Bt6Le`#|H6@jhw|`h&GaL$ zT6{_PZEni3UoCo8S^fIMkKXHmo*o;K(UoRB>YCZ5R;7``f_`b>sMd(De+6MuYX4Te zl;eFug*$Ijfv$6s&pM=f5}nn7)y{@hgXj6-_8Gd!qV3g5Uu99Ut(qH=o8uKNeN+iU z{wMgwBX8TqfXPfri$ky^r!KSY`;pCtax&lnj?#rOIWgdJ!Movt=ArciJMtE?Bg``+ zpnd+f_WI4NN(Y&Ib5o(rL?}%c9ceJ{)?m;;N?Pq`x!z_)`$XqR6tI)-do}RTm`r)+ zifp@fELHAIz_E5Nq3f6#ZmTuM_&pM9IN_8t?`RA2b8{+RNi-qw7Ucbq`(ORelpj1v zpUeD-s}L865;YL_CbzRlLrxq(cL#WchjQO|$n)3DY%02YXML5tL2k-qMZ|y;v*2`W zQ-ee&FdZ115|l1druJ79u1^u}&P3+9#~xYo9_|j59xG$cQ9}YVr5|bQ7!40xo~v}A zrN^oTaQRhGkP!s&j$;Q8AL$;B?8{nywY!K{9y>Nf?Gtz15BsJle3R|K>fa{uRPeoO zdpb8}6JvHsE^DO}%^iZa+Eko=n#dss%y>R&;~ascuS?Peetn1~lB<){b92Gjg;6yc zlGe{pzyl3AdW23@k*=MlJ)=V+F)T*n(KNmhoH!K2=4P>YHh6uRn}`EwBo<&fBI&i| zAr%E=w0nytjab4nhPo+YGQnyr18cnG(FyXVvu8z#0rZU9L~Yt58)Nt6V3NOF?lXXG z0g)JJR>w^{^FGHJ&2G5jsF&RRXjfiorOj=A7v1^5YKOeL)+yHdcRD!EuduF@kz`bKudaK^ZP^@@_M>t}#gr$;^ecn!Th1&XDuRa?k)be1@XN54kni|mtu@5}ibd-W zR>Uv7>9Ekg=Bu7n0S>SgVqF(h-|0KH_{U>!7fL5wcQS(Uh%`Su)i%P2-PRF--_*V66=nFH>3c*ilFkifyAG zP`7TB4R$(#Thr%>ex1)2z_IEE_U7PZ-O=rYJWB=VJD_SM;E=ng$aJ1u1DZaGJfSsW z5>~bBiRru@N65lxz{1Zp@FYQ~)ikIy(LSP zx-SljLOGocpGkG$lYPyzusaouPz%Aqo;g8|VZNe*WCNfWcX1blI_%Ktn#skENt-Gu z(r<#0&2pa^oZ zX%L#N!^%s>EuIz~47I3N70+Kok!LSBQ;i~u+(nr1+)WQ4WzjK5y4JN0FAJkNW4b8d z&G?Q?ll*l!jD!xMeHj}&{PdTsqR?JbY%>1>>Z!Qi=P0YE@OL>X#tqh0-6Zty-?m=N zg}GaNy5rf2j)PvQdw-SU4{)~BAJrnHd>yqzOOGOjEzV-ZPuq@0^@{Bct;)4BuMCzmC|YYv3VJ=)}O*1I`^E+^bbuw&X6e(Uc=c%#|#)X+8_^MGqZW;1@n+p+sNd84Q@(1eYI`=bf~OPvV5KS zK@cEEf*${~?9(y9tF-bwL%T6brges0^TIkA7758Doq!hdKrpgY_~dkNz)S3ho#c1| zpGOxGb>;brS$+6g#nh;XoyKq+IPCJASEneByucjujQl4GjYdpky!9$Z?7v&O917Eh$gB=jkyxIqm03ZbbjDhRopWVihNi0 zqPnq4@LKto0{@T@!Px=lVKPjUAEeaZgmG#b?b+6y5L!w-;1?=*F+@u`Z~o-mc??>C ztH?Wh8t2_zoHe;9_ixCX2kEQbxS7b45y+A78i!Z~svK}W0Ws46`25u`Q-(icfmH~ zx&C-}cz~wpeN_`*NmCl}jbrX&C+tRhC8H5_=5}{5Z8l(yR06ZAq)6|30 z>Zu!xM^f6t;{BswH|KXP)V^kUKo?dJl6e+59pQRv&5Dzq^>}6o>(5wwY1S8H$sH#{ z;as#^W7JzaDcEwhHg}vVV>dFEsV!#`YCOF&^p}M+ymkq$xryR|OA^02%$2l_RY`h> zhCB3%W?xmF!<0aPGT8}osuSQ(AT_wV|BgcXO#TD9+h&)@-M0jO-tp?h)fW6uUd^SE zShzafFm9~w3@`Nj4Gy!zCI7&DFLxB*4kDqM<7lX=q{n3v+i_e^{=gXM)09|*apx(; zZ#{?wps8MRk>c97-A6mP#CYHXToiJPGld_Jc)hcxXF>8e$6o_|6L@$qa0G%io1IW& z3PR%j+_;V=Z+(OBQOUIWKRRMB8ic1Rbe!nZ&(9KNhH0e4c;20pLw%*a=FfvCLQ`R zho;I%;D{*>se2GTI~=M!1_zO)Bo+Fa@-C8RGiOa*N=t(B>6R&{5Kc)~Ra87^kP}r8 zEBPO{sl%G)`9shY7gP3_bW9HEw_8-OAYT4Q3oc#2fu|ZbK!%X{#gHeEL4bx!vdort z5SQafR2($B>;|jkpd6(KN1{stXHL!*ExT(fpBq@!~U-y z8-V|Xr`^+Rr_2~{QmB-fWxp_q+6JQ`H)M=hz6@AapL!eDXtt^cD6>S|NqJpkP_xGO zW%@8JA7Xu2Z8A5KJI*a61i*aN=MBOorl35m5`cI_HO2*Ve{avRthJv%V^cC%+|QP6Izpr#PH#=?>@ zFcVzgdZ@^P2)7Tp%PNbHQa$y}*IB}sxsiZ`+fUCKz|Be(4dSCwh4J*olH3b8;EV16 z)NA=m6qWe(yj}mxbVJoAcR}=5TZ;MfZ;nxWX0*?wTi+g$JAL&{0PFWyknRaX^i~Jj ztWHeRVVtZ4FpOcT76BGH7UO}t1f#?DM5z3?`!@7TT3a0vONyi29(T6j zAVLy7{^iv^*#AYT>~^8*r152MfU|(*y}~(3WrfF3Y==j3&P&AzI_eUo+RV{d&knm# zHbk`w=enoV$?#oN7~#XX%wVddNR532aY7t#@u=a(;z1~wCuJEX*wxMMWIGv2Kj2zZ4!Ry8dZOQn+aP|S_$0{>M$ZunFI|$@h*k0YS%rHph{z8JGy8(HUs;m zn~rHCjXHMysiBRBK+mCmrx6u~6@&S`ygj=N;_d5(tB;o+((s(xc-0eyKp)KW?$;#C z19m0Xg;%?&UfIls6J44~PhKShbtr^iTwo;Yk~MblAML!L)i%0-483t5`aYfRd}CDR zAY6LNMXn8L=x*ojp7&Nf8QE>*U$;sWaV>_fim@dL=OXGeU1A1Z{4 z!Bm)NYHW~t>ihBT1k(D(xD74GIh;hB_$6Iv?vUrO%QVzbl$l>-i99M(=8y#af2$#k zD3o@Lt%&^{ZCfQ_v$<_i&GI?}ONE(B3lgYN6@w4p`RSJS5}zq^#P2a)!L)027CgTR zZ`{nl`@lWG^kF?-E}LNA4nVhG{%Nk-gx>2rM_-0Fdl9QskQH2wGdOy_5^>x+G@bkL|8P3_$4m~G7);Rc+$M=#g81P zr&E;kp2uI^KD=cB8UVfJk~zexF+)YJPeMu-GEi&kG8R6PNUeA&tj7fvduhWmo0!|zq zLlV{W_G0b7F_ywBrwIiy8Dy8CH%TyuHG%-HW%LqF;N%9-BoU~`{VXQBB&*DSGC8b{ zA!84VdOh8iy`eH36mnWIQQRcaHQ*>qhEjUKW)uKzozX3=Hy3q#-?nnr)pEf~wlL4K zinQ%0n0a=H`?;kvYuWQ{Hq*9VIu!5IdutRn$ed|xTJZ@~jT?bAP8P!9()_am?zqH9 zhJjFGmo`(s_V>O)Dn&n;d5wwm$fZ>W^gKFqZ(B%!{cXy3E%`L|c~XcB zsaSBC_^<`I7rMY9rhYA94gNJPm3r#JzbmZ^ZbjoQrDy38MlxH|HLP1=bYcO%No4}~ z8(R1+mc?fU6eRb8gwEx43|#$$F1cw)S6=7kxzB%#vYkDDGDjXELwK};SnUG@+u%Qd zYi7#BQ?XU4xY&o3!-d4@7u`qkWuC@EjT*qFv)zmQ1jrr&)9%%tbpXGij!u{ocdM&u zIISysQ}E0USJFaKx~$dZCqHsy%FYIRIHqE&f^~1VOu$7m`@iHEin(MTaK@V%(BZ9$ ze(p9);Zwg4)7t5$wyj9d_K+B0qpl8nylHiQ(Y!7xo?UE?A(65a$XF>DYTBB*X+(J& zg~mv8=;{#vMnh?Pldc_$hjh@T3}E;6;n@Mh(Ks%P6W_>EtIra+bdnE>ynOV+NK7Nxy^xqbO^yD3PW-!CW`hi0&+8X=ut=cERqfexEUmb*AG$1mmKRDs5e{bx!u^~SX8?S zcIDWx%HK~9%@4}RtlnXtVcr|S%pYRn6E|3K*rwR7Ot( zyZRu2dU#aW=X`IhKhu!$&*j4BQ0icwVZS5OP$S(=sG6B6SW3gT4hb$9OVLxNa=aMb zDd7K0mg<0VKd>Q5sz}ML*uvO{dGB1QMtON$wDZf+ShVvq{5^zwwl4zNlKc5=IqgB^ zK%v`t-j7-M$Q;;;Pu|ADwVsQy{)TfT{3Vq zBlV}^z$%@7c6qr?|BLU&CxuDdVzOA>lprWr0fzK^aR&Q0IGEli`QtU(|6wKag|Gw! z(mZw2Lu{XbYDnU>R%C~*cd+7tHbXHnI5%Hktrg&)MQP9=ZSV2m%lPG8^fOK)bur4) z0tVAtmnZfD$&3e{-)FxkEdh(?!Eo^Vj+wm$t!Dw16qNmyttTR7udX~^<2V#Os#%P zgPk4o@02W`|5-JhFm5;}Wu74$Ajt2{*8NCkAF;s5_v9+6jIk{{FJS4p!W-XpynBDg zljl5imQB9w6!h!tc;3P>4Fo84iz zqa|DJ>@9gx?hF2Xm`o$H+#&T?PtA~8p#syyI~TY*LrZZq9N`zao{K+Hj?7cam)&(E zfB~3FlhN>PbS(PycArZs2#LlklisRcna_NF7i*}3jioC#xG7OrZ_Nlq3y0{yFz@QQ z!V57Tx9-?*XhM+K!fbb9*)6nS%Xu2e$-G8v?_qV8#Qx z9vYPl44qov$#XIXEc&_zV$Rves50+}^aCcxd-iMYu429=_0k<~mokQc}p>kWzDzV++c!v)lS zM$5-+Bbo#qU2yY3`7y)}g8n0P^W2_`*0gjm-yq=y_JMpq6+>MyHuY#Pn?kOmxeTn+ zZhp^u>O?(>z0^`U*N`@p-QHrW??z5n&J&%?CiU6ODX(>c^vgme4;8dpW|O1%E+6}5 z{*~)_PsJ<+PW07{SNOC~(Nu`+?jMUg_y?=42N!hWmfeuj2<7M@BVdwav9BqKhn#uzU08dtDqDWI%v!4k@uopQL9nKvSXU0+2{hQv^ zLU?T#=qWBiTdev4R0GNjQ7|29ZM*zRlr9zpPCZEDDTpamKacy+bnF(;g!^kuYzx*l zsJFt_nkCGo3Oc$FXYezHcQ43>=f?UcY%iOFVzP<#b)HQvJrZHs2}t?a)L1Fmb33^R zG6|&Ef_Na(i;+rdK%Mi_x-%GN{6CgQ{Fv%aGvYEiQV+B<3?WUAxLxH<4z#<$sT|(j zugY!g%vKGWB{G8C`k#Dtj08Ob87APqJs1QBGYtZ*iN&ZHZBV;r>JczNzGUOqSBH;j zCb^oSZQFDBy^HK**%b?0+T%)1EKf0x_yvT4x^WUdnLpE##)%|glP6K& z`b-G2tO9kwqnEIbg>2L1PHct4ZA9FDPQ5J#-&`VO1YHzJz*bwhf}a};DEV}8`}X^4 zP)=uq!sXzAgcDAB`Ep*A<=nxEy1p&|z)SZ@2l8-8bVM30_57ac=Z->5|6h=@pPSvz zCuM2Y+1mb#;y;=n4uLYCheu%{l)U$z`Z7x5U0Ua}22ap1fYTkdTt>&XqWQ zA2vTpiH8shhgjLA+*#WsZV*B+9IqK0?h-bAf~s}1U%NbEuGdW<99VW<9l|#Z{!lJ{ljVGl2j^kgaU;yA z(L=_Ikr-1Yi_EEHrD?&6WTN$ky)| zA<-?r|Gdt7S-l_NB$srpxCSMIUMTBFG#q#7Ya3xq*#-;sv1p1aDoaO_cMIkSn~Q>P zl%u%&R>zJgieVrpUOSd*jnW+H4by&~NOlg=R``9Vvu#b z9j;%l$w8EzTEJXiZ7HOtlHHI~m8wrqzBwcRCFk*sIyfYD!QF-YK;7uWp*v^yHQwQY(%b zN3hPZYrQt#K>G&q86n&@Q)!aRKQe7g;Ns)Nhh45cEUoYU2>rg{+w{DL!k+f*8{A$d z-kcZ05+y?fogKp)mGs~-^!3w`k>|csuHBu1@7SdiIEc^cjkSF2gFZqgHZ%(o*-cEd zQ6u2LhFU$XeEWpZ)Q!Dw7etc>+$?8}_exzbwpFlpf{?BPQcXpJ;+|DZ_&Nak+*fC? z!M4WhhGKVla&XUbC4$Iv;ihA$c>qrgp~fso5s+N$pfK^}^EwMUhWXFx`;C8RuiP|) zgnQsE`>pG&(7N^4Vl3&|8@?i5hc?X<4C)?CRStO{>=0qnjFYGh3zHmSU}ZHre*{-{ zrkkev_F9P*le}y2@i5SBXm60!qYSC7mMsK{QGdF}0UDNlF?>qyuFN^Dakf5fiS`1F zH(b!C#Qa<0efCuQ(lRpJe$)Yk3^Yj*gGx1iMopCQL1-TP zai6eV97-t6;Dg>5rq6#7@rZeIm?#b$Dy_qOollOIXfgk%+>pzC<0XeP8;hDvTH}^u zNI8S_ay#&Ld0Ig|+I<6SGxu9~M?oIG|`{}Mt zDa|vBxs!GF!-k5jL^3@)L>OFqX21yLX}czjw2>oYe;eIXlwd z2F5nzsM0VMBlHF8#Lq8%;lUAIVc*-trS6xdAGrUb3isce!?)yw@Y9?v{qXQSuwRqU z$*`l$@a%px-s*|nKa8EYIS4r)tCCb~;V6kkjTKe3=Da7yKP2{NGEj=Q+F~)P{|3Gq z6xzGZ==7ItA-=tUT64Ukc*^p}Hbpzlqe? z7b*8LrSfy6)UtO;l*{HD{ko1^~&?Mc%)LQexP2 z%_7?RUAQCW2B~FTyAWn|I)DO=jjz6Nj%~{`DB$DsKW)k$QLFUQHeun8aoCZ#;8+Jn{fyc%HGELLPz-J#B96QqJwslg?N)Bn|K%_jU+$r|Ya3QE zf7pR_c{A)KS6*p%uHbecy@6u1dzObK5K{zv32`LDh@q4Xa_wB+JP_D-x+1s->YumbS$e`SdcTO8Zmgo;Mje=DPND&Mbi6gP=gOfa7| z(S_@xf#mH0h^R)UHPJ@RSVRp9`B|FtnUV$W^r0lT4&TC%;gOed=9N;#H#vQ{EtkI3 zR_uI=?JCEXyZ`*7p_XacXUdcTh!9XD259aiuNbZv{Pv-|`fdH%}9l?e2kJUOMn3NW`s*XL`S)8w=sP)xi6q;lf@4+Fuq zu^l$&%RS1eQVzxETDND(jnjaQ64rS)hEvL&b9;|b^JL*Fg7^^1#@IeBl{trX_Cux{ z`lSE`jg>Y2kD3Dl8leYj)+2`W%s-~dX);SOnyTu-3Wj;fkS1ys`2S+`x!dJC=m{vP zGsjj*wG;dAMdPPcG6e7kJ}p2RQD^#ewZ?EjsRMY9-a&VwfptoeHGHS)6H|A5gV~duca~pH_$al~LhY%4|b~d6{98(&ylj73Bp+?$% z5_gbSv5|(((08*z{Xb4WAqktMMU(pDzKAi+z7$_tF!K~SO$XhRTi02)75|a>{()BV zENe}!`xr}SFaBx-T5xO4veh44MA_uFaU9i;e887kl`jK42j{+qUgA6t#s9z~V08AS zP4kE9|Eq}>^v+iR>No>0Hz6sILn$sVpi*c_A35di?hkUpQ##NK*OUFMhS60*aEHXYS!v5q0su4F+QU! zzUw{q(1*Co>A9s`+QPo#fHkRBn$fR5S$w zIe`jUV({~YPDfQO>ne9M_rIXM$8U?PW+xyXFi#!3%>Adq<4F*=tc)XdKYxPC`GO{1 zT*=LW$#08A4vFl>Qd zIWss&DhBFJ0=tIQ+5{4M>6R+tuw9T0etB|7n<@D#*%dTYL*$ZfvnlNWTO<`yYiznw!=`Pxpsa4Y`kw2*4NCqNIblgUT}Ml-K-P=zc~V+Y zqN=R5&bBud#I#>Kopi2TNcrK4zYOP+RcMzgb<2%3)O^B6Uh-y;R3*?a8=BF5q$j~r%pDw{Ll7yIopXT=ZnJRS zSyxL~tmc~izR8_-=$I28L)0pC*!J%HywbDRm?qV9nTPb1QaEPFkY|cd&zZ!(3g&7S zqKOYf#vip=LYFk63_ZH{SkUvfwjg3zQ_QhfwQzknAr{u|huYh1XbBh2)*N5-d4kU4 zoQEc!_!R876+P*B`+ ze}G@ZQA(637_H$!Q+aw%^Zugszul^R-+zLY7KxuoXTQG52~=67`z1Z#sV`j@Q{ybx zzAul3MjTSivpI#hH5}N7#bXorm4C1j z6(4HOGiAA(eP^C4^~q9GWxlZN!bgK4)lXN@vSaTIsTsiX!TZSiK;s@Qy;QB}F|`y> zr9eer2rVdyeJ@+txSkYD+~cUj87O)FIhX!f9*@byNM9>^@@~zGcZ9G1bf_gS#~6;D z80MX=r@k8=CIfyVH6CKWXXHr3AZKEb)>CITelw!t6ly!$G?{DMdj&eeFy7lwrBT`U z|CtJqrkNcYQi7JbS`9>tP!_Eyb2Jp+m};z}*de__3FjQvHWc)PMO-%ZLj(e<$$FTP zA7i0M95L|6Q8G{poHdScN>%!AOzQv1ZmE1DhwtkZvt+<>%F|nM_=z~ES^NLBbe}r5 zhuA;PY=-s52PhY_D%Hj{X{<8Ahm;k89C6qd?Psjn>I?q%6t<^hr$L z5Bqsa0xT0ZTgaUSx4Tmxd=yvz92h;nBuKfj|V|$ zG`c1t=qP)q*M?US-0&IF3df?z>mZ8j{lbRlu% zK#dkrjIKQ#G3w)f07gK$zj0eSIB^W}0<8V|vO(+$010{25ptiI99+5u@FGulnd#pP z$i^9f(MkND;r}&AN9wkHXF`H!}n#@wjcX1+bR)6E@0+^;57}c2RH9SN=-uV_8y+bwju%lDeMaiVd1{d82T1+#!3QF$4$|wxe z2%j+Yuzl2qMFApH)=}OgM7jTa*G8HXA`!)<8#QB9)V(j&5Oak(okIwh>Xc7hBLL@n zw{Ph;ChHNX%hi*1T3T3=_I1n^#|c-jn&SXvv^b=S1$+;#+6sBaV1rP+8a;{XUVa+~ z8YVe-B70;QS9&TT3iiA3P9P22Mr_0ZLntWeP(F=6Yg9U6iZP1jaSCHZyLj>ssH=)0 zC~x0YI}$t0Kz_ijsip}NABje4BmXukdW&}QCk)ZM`ab{Q<=`o&#V4|faU_$&l^!Oh z00BDaP>7b~Gx+Q$;N1OJX8CQ*>r02op2+S|*v)N~o>0*)B!tw&(PgM84 z78~yBrKf*ptpe8Lf&cMpjM{vbRn-C?ml?{HCnC)PSuskVLBDVyeF3rN*M6J`bmbbi zp%SJ)97niHSE9yK5Yk|-#iw6Y&|B2Y;4}(~>jMCAcIH-iq#4kJDQ{M40efbB8oule ztN=rn9w6LP^p^;vM(|DMk_<9UP*g**et|UVbv$m$Dm`48O;aCo&QmiCZW30oeUUK* zq?fi~d?;Lzq~8EdI39&Os%sQX#WVMQW9~9c%c$G{lxn!|@m*Z*+LaS=O+z@gI5*hOXaB7lLG^s!<&VH0E9BDwq3rtAau5; zOV9tzM-EL)Qsou+vypcxf}dn$aiw0O4y<8kUfn;HxE^hGAcUs*T8OtAx!LGvHE{WJ z82iybCTp;tli4?$0#Vtp-oO40*>^z3j8_@##g=ZiTb_4nNn-kFw?0QVAlV&VUssi& zZ+WNQbrMfZM{XjPEOhCUozjjM@p^Wy`UIkwc=HJYFIud?5+u8f;xsoj48&v@%*p$o zL1O<@^}%BmChV%Vq2)IQoxX*xa?!#_aW8B6A;p!)IGPYOuCOgJ#yG9v0y8M%ezcS0 zYOkFoi$Xox){v)bVQ!9 zx;kBI-%WmAh)26Ri0r{i8%WYPC{qfztpw}241MN}O)bZ`6(2E^KwX5j3RtZz>wC0x z1**J@>q=pU|&E1Lgfsk zhDH!2I7&012kDgfgW6a(QluF3CJNlGEI(&@lO#j@m^PPh#vKVyP59Sv|UuN+Br0Tdq91=@Pxme!F-sFD>@3k;PPPY7YBWDDNyB={p)L0(XSTP9udkGPvGGIPxA1@eRuW>-q_vu` z%tw@CgwZ*K;I7xA-LY3i@6gu*$vSl!@xyx=e)gSV*WV{-QTi&V-Qrr^ zZ-Yj(Ab`&R(v)f3E9MN8el2~yeNGyzQl#r4%XtMy0rBF)2y*o2A2OVhlaVa%KIsO- zzo%~6N_HNP3*In|jIOoDNi=MSIZK@Q9JeV*Y|u$kcXF(Un}`?D^X7c=AM#+ z^XP_OcS$cQ$>wy??I08%+zoUXRQccN;BNNKoXWR;FW}i)=D#lDgh~8KO7oZxP)0z- z7Ef$j;E+8Nafk3YmN#2` zsUOdIm{$QW+@4atJzVLCz|&+uTxTN$JZ|nskv$n!n((%dXP2pVGv(MS0Co5_nh)VP zxDyKj^k~B}1=3BWKYJ7j<25@`NwVJa*0LcZ1xPZ^N{?+eP}Y#1fj_iPWYO0OJ;7oE z-oH+Y&gqLP;+vi{svmK5lX_$bs?i~hr-S0lo}ycu6cbvX=*Xsp0SMov#kRGR(wSW% zH5XS-!6g1S6*krtE5L*ZpmElp|*- zkd942OirNtK0Tqhxy|KsoFH1SNw;`NLb+d;W(w@Det%2H_2_=4adDp~)^9PY>vIxa z9x2uf;(ZX+4}ObpIo;`>{Q}?VQufI!EGj6@)PUp?(nH^7z$xZ*I+jbq8h z!HC}pbzW}Wg5ri(7n-XmiSj7@W4Z(}7w29HBx-iC+@h7H1bc-jw%tfk8A>_v?w92g z+zl1U0LMUV?Lqfc^W3gD=$3*zEu!I_wEvIow@z6f>rdrF>lF0DKD%SGDDa0Dty@)Z z{c5^(vx|-L9dHH5V+2|6D}~Ye(|Q_=6;vkSVEt1)2^I~1^-e2y1pU12nDopnf+&7! zl6lG@-*E$9YEcrhH%4AswF?y3;(m}hU=GupR2~d#p2@{W`YpP+>RJ`WIC5gxB9DkV zCDK7&$0TPfk4dEX5}D~*YxoK>g3&wS(CsRT5+Imc)7cO}vC@})5i%)oCVRnWs7%?3 zJuJRe7eIlv&MKOWC!pwQxf>DFU#Xz84-LN{Q5tVsLi?&6BC9tC5a%oHIf5FGx}?3Y zvM(R4IuBm(-N}JTiFz}~mcNoq@0rtQp~}b_lAMSPWpn)K*XMtN`s65s(zNM|(YGbD z@53h2$5+B}kXEob0n9=%6aOAxO5OZarFlFZyRQo5Z(t;BVS1ruCXbnS7Z=NuNNNil!Xnb z<4t5FT8&$o%`m5YmioMVvT6HPeP!FL)+iy(q%v!>83>q@1_liz&aZ5pbawixgM)kM`NokNUw9O2^499vyxqFReOh z@iE>oQFT&|?2>ReSTBGBGuvj?>2e=!$>@=?pk#Zej(+8kllF0g!mLw2fEsI6=aV~E zG#@84(q&ti4Ovt^BRl3|@|6Kqhh;Y{S_8cH)XKy0&{$TZy z?K}G=3DG~V3-u5FruNLM^@IA=C!vj$y+LEU&^xHd!4(KIfUc5Xq6@ce7CFf?(z@d? zZ3W&iMEoK3Ra=NBP(zg8BcdI>0gL*47mLMuMR|k81HA=5`rNkblWf01UeR7`=_nRj zefmeXb68d?g!*sEVOBH}nA`u*R79qYCiORBjOccxmylI(SX7I4y&lIlD6iNcR~kma zwbtnYUzQGEHMpH0AZHl)(O}Coh1gpTywNw|a{jSh+rWl)98a@t(sF~hIPoW=!VZ41+pJ&@h`TEfV z^V16voA^?sf^c~2Q_2RhhFM&?nX#n^`Ti4nsNsY_;9{eTKJD6I=t+!8aU7U${7$%4sLnoC;fo)HirLvFiwWf zj7~&4QUY7soo^%HSO@{J_U@i>zECHO%NNcI^hqQLHDLbYaZr2bHegtwj^hQUek$X4 zst^;F8=Seh&uv{E#6~X2fj? z1Q**?2(pR)#r-x$n}y{8cU9q?&~S6R^Vk@TwL#Lqrs?^%97g0go1{w4`us#z?}v2! z?9Rn?e&vfJap6l}&&o#?L10VopC`rlXCcs6#Q?w?)!e6Gh5_!vP3Y50*;`XL>FY_U z8G;~JbhEiB_oQ!Q&gQVTR@kPz)!Oz#^D?Wma&!Y4Iey^~y=&HZ=*k}WTw{+?F_dUo ziNHXsRmPXX(^?_h(x|*vVR~G)F&g(|g;~K`jhI!;581vCmOH#I{Uo~a#^|m2@8u74 z2;@~979;wx7?t$2%_Mt?)6xMJd?C>P0eG(0bOk3`NQ0XK8e$Yo|E(vR?;n7J!pc$e zBGCpF&jA|`09#K+h^Zed;5_66M92l6wVk(&cX;v{@2=eK!h&BI%z$IaCyZwi@v}N- zh@>Cm4vpBezh!~<9gB-|Fx>L54bB6}nk!v-N6YvndCT^1(v5Vx$6KnB&$Cn|Bk>%$ z?0!?kJ>ozOUXw^36i4BkCuCw%4y>+|lWv5w71u_uk=aly824ci+_-%C{nGoUdOh9~c>+CUQ zvvcfu!wNi7gQTNNQn$l+Bb=9r&5$#`#l7c*0Oa{~tg{<2cYdl<8(kgCYnHPGLfL({ zJhSmKrjAl%w6>1X10v-teHL&KL|PqqXxeA58%MiRMk{VddXEB{11jCj9u!Z--{#Ng z+e90o(0UKy9{W{%;F6hFkM)Nm6UZL(dKgG@{QzqOIJdUacpjdgNL0Wn!yi!T6QWx( zA0fGhwPiT`i4p@uqY8BF4MR#Xi-s8OsM-RH%BEB>q8#>E2R(J&DUNUt!;0%@D)X&3 zd6*x9A&3{n-8W%rR*a)aZDrH$z*N9>fu0uV0FWPQEhiXBi2qy&Zg?hv)`<2tBPPQU z^FkM0P(Z94YsAVo4q4N==W~xFr2h`k2`x!ab*;Gu-KWdkxw--`7}#Oti3apb!IpDV ziYt=~2dR{kkTDhSPsi;EZx*_Z=T2n?<`wF~6!=*zQAHubFNSJKDV2ZQ0g^?pblOHKAe{a5=SvN0M{4#|e|hGvsQ#IAzIteV`^2kz zQlVeMe-&^vPoVA>j|Q0ETkvj}8`Dk!r8_ASV+8Y4eCi4`f6Sys=Sjbbr6imr*W6tuSdr zXhd5r;LXxvIIrL~U!5jcf}$Rw%ZJ|8_I&YLF(Rw6xsNgHH&pt;31HKSqkz;>jpMj^ zc!CqEH!K#~aDk1~fjUCq^5@ZCc|Itpsi+&wJj##>TvKe%52yOSs`i7OYoWx4pkbi_ zouQLv*sH|zhj#z69(+c~d}7UYL~XaVDx_L>DyjpN@IsWvPtSscg4kamC8^-xyQ4VO5m*y0bBQFBhT$u7eAi|qFQwgE90 zD*vr+oXF$+!esbPJ0$G`gN$pthlj`+sa2r1@DU7P6~2}@P`? z9ugT~VgK!^$&}g5O~v_q@)b8^{>`axzZxEk9-A91ddj;5kF8#+mQ4d|0wSB!Q+ici z(ez2nNn+;oqX=E(iCIN7nJX3hpC6pn;?Z2CNiMVjK|CCiOe2e@FPMw^CMOwPrLHzj zK=TXJfp=kvpC|?@6kTa@NSzxx{U*Pn{80g+2dio5wY0c;UYs%F?Y~Um_U9Nj~W5efn{KtbG42?Z0KKCLa*E&3p)N>=I-P78TmHF{?@z?&v}C) zX}HG{JOG3aS9W#9|x|lip zMwP&~N+UfwMb>~3E1ioO;8V!3wMq&*QZ3;+4db1TtWPRuhb zY(So)f%d}D#NHf+b8?vj$ReeYQc&v$)@bF}z59hm{=`h|!?T}DXgduQ?nSSj;++r^ zq0DmFe&L)h_r(RVJ0V7jZzp*kZXz|=>b@b*SH$DAe}!4Jm?Ep;=u0w(;7w@DSNDb2 zOfN~;;5aY0xgcH*mRYS@O)2Rf{TO{AnQ4XN#`dBSYFgB}=MQPoM*Et*>DQ*&tiL7# z01(dOk+6t2dh2fOA2+x1M?IM`j)wro{y=Agbm*GjaiM*5lNC&i*NlReP$jtBXf-7p z5v%z4X|T;5WOFr)0aKl`Wb}k?=6P;8#dndpQ($CKo?q>@Y|p0i z7)r(`@@QT3227;lDr@Lg9M(zwPcC3;p+H?b)QgpxfuSSIf*QFOmb>gkB6!;jn*X04 zG4IR@JHkOd8pK!3CHMPU&M^|&BUhI^3)%17$XxU3+4B^rjJmMWc;lWiBPlP<73m){ zZ+bnaQUj*{BerZ0KND48B->)wAuaWw(u;}BMM2)lC!wk4!wE&^!QK~40@FCuL5j3y zhz-yAG$-n^J9%L)*f2N;A}{@PYse3J`eryn#yjTOA)|g|wu}CIFfSJ;C8z*TQ4{o) ztzwUF7OUA;t~#INZG3VvNM$!pf^=l_ikQzgqK6jn3&o~wV&C#~EqzLJL)CHUeUgedj+#JA)E5Q=hw$QR ztd{sAYB6@yH_|Dc=cd;dSaX8$V{)m_iskTn;fl$b7DrH<*tgE*-5ulUjb3Wb$C|p! zt1zzx_f0cL2~RFnX!V`zn0bNUZmRPW{6P#UUz7mFax)$@y`OI75=bwOr=PSsTBboS zUR3Ozc&E%`0=7DhgBfcUE`?Hv8}&usSBb7_JoGN%S-Vll0#>gecl*7Ci-E_$L7 z7NJS52KUxw0DeVU$TzW0vf;Du$A+t2LwI9!?|uWqDVAkax8R;RXVndlTrHCs;z*tw zC?+S~z|_5@#?KqP)J^X$ZmWxFdiW7(#3fr7IDN*#8NBrXVH2UOPpL|aTWM8_d8wAW z2A6(O<|9L;WSu+x(x19OtVFjJ^MSu+i69dfWrX66yh8UQ;zVKp0X=WLYZvg0%38W8ecVW)+$l^qV z(L1P>ym~2XXmLn0Owl@l!JTB`Qoc4T`LWeqUeWEI<_N^vDBbDYtVBvlj5!}tCjCu1 zKO8{rco{CU)GS$ufHf21)U-0nHrr=kLNA)?sQ>ZkGOTW$H4`_tG)(CV0lu`H`*zjkYM7yn_yF%v_4kluH4On4q%)59= z`(KSicnKL{DS0hKSn6DzUG@=B=%GznlJb1jGjTX=Q?tYT?K+PksJFL(*5FA5SiLRf zH8EZYi1?x5*Z<~uvntV;+Nzc`>@~nIW1NXLO`*~zC3s)Tz^!qn36XQ9o~sv+6M@>W z+SwLznkirt0+~b!Ku`8^l~60yueP&8I)jFN?xV}uqE;vR*Yl<&yP1AyM4AwiDvEFVxNBWlMzCEw$*L>m8%4fU-L zxs9L3XZu%OE7{I-+Xd(f#S4o`R(o$Y-A@AIRvmyEBP+j+St~A!F8Q=LQJ^|J#?X+R zSy8$h025t(R_B3hWCH3E5cORmp*3(LRha-er{GL=@|ma!JjDshJ@`KLm^XSbT-lkD z4=fX31M)bFzbeTfh;-aRv-*l2am68&lu1So*+m)-+I&KL?3`{EQ3TWn5Qz4cMRn3^WPrLql1n(ZwV9vm4*#Z?mQ- z-ts3dU)*U$5lT`Pn+Fd6GQ%Nzgi^*cmK*$bJQT0`Q#`YkdlE4&R^ktNQ?7Ph^XhSk z4&7b_RHly}ax5N7e$J29EX1ZmP(wjQTGM5AFmr&8>{d(p$G6f4X> z8joza`fi#6E^#DCC|Xpg57I9bDYo&;#ciZxGP;(wu$?Z5;_Nd&i$wDd#5BCvFn#fzZ6j;vGKGqfmD^@I}@{HAOK$g*5t zMVS!wiBBtP0a=NB*Uv-a8G?a@s!38ih16Xixh&g`v*bvwCoCvUi+(at|p-%LtAu)VO6eCeMr4J&i|0SwzKx@SbmlGe{*ns1nhJ~ zVzmNG4tW{#80QMS^ABw~I#n_(9nW_9*`Z<1c>OEuJ&SJ!xVqWBG_vqni|{V-sI%`5 z$4exNOh=6tqF(h2V8{@0D+AaF0fE6%U{%EyTfT{H0^3`lGW;)#s$9T5b=n;(1Fcdv zM`#l@*NCWK*8vAbNqlO5nI~rrYn|*y!XR-G?K2rDjO1Q8a)ouH%GHVDfwDVavwy-! zU$+`*dc9OJw#bsJSie=@MRB?QT@h3_RFI>@OP2*XMbuMxw)cKD3+Hz(x$FM4HJ}ty z77ZJ|ITdoU!UZt`n;v!QVJ6NY?hr}$h~8+qJd)2xu;W!Sy!B!t^@r|()(pixF*p$7 zqPd+`j!ia1#_b3H^_O-bf-IU$J&*nrFgLLG3((s+rY`gu9s`9g_A!;0S{E}OO}YQ| zefkC9BAb zl8noNcrFSVQ2Hwiq{$;31LtT!-hnCXRQ%7P{iI1d+^LOB5&6>a4*;sYxvQ>L>RF1I zn_RxW&92+JAfCc^y3t*ZHMO;cnH!wE3YB2YoQZag#y);sbuMFuz7L6x@GqkVc+=M6 zF96vxafx%_aDJeLV$fzj`vAH|9dcU}ViuNS;ADh=Ue>LP^L_Jf**L%?owKewy|nd$ zlqQsqhDENS@T~!N^6pkE#~1yhhQ&2FW zAUI(hAGY6kr4!Ha1RElE-L(QHY3$5^CGAIs5UA1VZU9E-k-?L00+B3c!?rEQwt0^x zMh>~X(0_sV-qqmc|B{x&iwkJhQN$TId@ysjfa|Ca3%e0PZW}5eErFrK#Nd@Zf8Fz4 zPN0-z!w2Hk;^cn@ee$bj5yh(I-|>JMC$TSBbgW7iNHb|u8tngZska8(wFpwFpKuJo zjBZpiWK3}{D&e>H$ZHm2*$|Xt4xxLZHa1-F*NV)qAxV zu2=J5yWS@qpSi%<49=9+jsgN5NlZkzyN&WMrk)o@XqbxEuv5symA%#;^2gj3+A@ zOREpytXNi9hX0$l=;BUwT>XTsXKC{p{PSg4vRmt0b+RMmQc4Q7Y|5X>GU?^q14H}m zy6VmX%_Gy}E|J0x&It}^OzLR@r2-#tDWA4X){z8db;5b&6`o!Ky<;^Sp|9&* z(?6Mf!)(i?58~$}B}-hak!S}0kdz3t0MC9=_oh*P!K4hSYcgqorkcI}OjijD@dkNC z`r!eREx*-AgdbhLTG2I1VKe_gP9kpKcV;8ESH~B){R(!f;({$1)^H*>&qcr2Pg{^% z^s|IGt;_ti|4p6~<|C=&$aJ3}eexUu*u5eq>Cn$QCZL!BEs zFsZE050tPt8s3#Nz;+0rbG1*Yif{+$XQO&C>4Nldc^~G!?*KASZ(WW)H4LoZfuoY} z5w|--Ap0R%)HU?)FJ#OZ1I+5!*oHKS%Ha&KiHa2pX)jG~mKyffLlvQf*nf*tb);t~ zY26j3Fn8tRfp*bFuTDs8vGH6EETid3>mE?m8o4>Lop2qRKFG%a?yoA6EsJFaIyv)8 zEVjyxasxfvUt8J003(_D0;kPbI zC~kb()nne{9iK>zUM^o}fQCaiW#}2iGZH~QpKI`Y>2j6gQAwnUpxHvRi@_RN91gEQ zPbn(pQu1T-m4Fif6g8os{o-u8xJ1AWB`XGo<^G`CV+v9xKebrv0p(D&EWiuLrEPtf z^B%oRDYz?TnTe{@bc9m>PJh3Gp=6V$;KuT~S^%>1V9=i)I?qz;lV|6bzM@v>zXuYB zeNsR(JV?TLqz~xMac6NUbkZ_%WRP@lWY#+fuF8nf3Ru{_cA^E~OFIqTu`hu7h5U_S zW%OUCELvt1vpRrgj`R>g&NT3nVX^Iw-TV^$0J$K$+O?=cFvo#(7b*%@N|x`ZWqX)NZZmnM zAm;c4=v9r4o+mhChxYXO>P%4x?>P6YBtpKxNWe%leW^Nu3{jvi%(5DA^h7Nz%o}Uz zPt1N$5LYQtcs%{BW_xN79XeWwRl7Y6oCQhWo`<80WaU8I$(L#{Oq0jS3vkDM9oKcnFD-5E6`{(-vbe$@8uP}2_#Mh3sVuP{3L zy3xkgSuWHvX?68(2$FCqjkgVP)k5#dAmNvOXbPa;k>;t~@T6Krhj=s|{mi~>aW}ie z-j&1Q3uHP9H+)`xftg;BD(7%w0EJ;aTxj3QpHs_t!Et_J(AgKVi-zr;;nYR0A*&Aj z-sRzT;QdEsgWko>NW*hWKboQXFj0^UcTFjnF-yC}re_bL&()GeDC^+Ho;+eq|44R9 z4K=meHb`*>^NU5yj0QxZjpiEqnf8Uq@NqAl;wJwxp@cCI&?qyf*Z~}Qf&nd=bgY+g z9uQm5e-WT!5wIqOqZlQG2`V14X!Ye%dVY6`RzZP*@VslYRpiSQqgxK7MMBFi-DGu9 z0LQPpU7$8n-WK+gTam+%Dv=foIhK1-=2TA&V1WtcdUuLT|L zx^Z&4Iakobz49a99S06|%gM|8iyWXIN0>U}2&pVVDwSlyQ%PO__^$(sYfpcAq-x>o zURM7x3v?(BHO8SG^P)J)!XHK_@i0in_hr_bgp}6g`~UqsC^X8$Bb}s(o*pFUB-3E! z^+r8}r$uP*iqu5~Ta?Caf`6MzbM-Nyr((QF?ZPub>W*?e)7wIDv0)k0(Xb@4J{04^ z1Q5du8Ka6j(d#iz^Z>wKXWFBxg~YGNzsr*rK4Aknn?$FgLDYCAh_Jm15s&M5lg_S) zV^VBetFE2edL*g`yz@m8z9doo;i6dj;pXlIj|2E24mX{>?c${dTB;f?+Hl;tONDy3 z`*z4st6mOKC&5A`UtdP{w!7~5LbetRmTfyEb4A+qy~&Eo!0N!l8Bw` z2V`lcqZih4lB>1!Rv8zFO=xCYaKQ7ukxEWC@HFs2?A$@!1Qx&*6L2fY z@fJw{<_{S6JUc^Ume=?n0zgp&vLGzrInxKOk@(iSKCi^YZtkZ6CS1Z8HGOvfzJ=nnrj5=_Vc?Y}=&zHS(nBRt!C_$%DMDuq z)X+XQoFw(btHH#c z1xnNNEOr@997ZHKrn4}k+_fuSC6dY?dgjD|&GJiME5)AcYTEgkC60qm?SZBdJ@gdhph% z&#`I1g*OJv3Y7-@UM^*^Qw+R;zZCZxsF3aY+#qOE)dsswwx$RlJCZTLrA1dHQCp;LxQ7w)0sE7Iz?!h)XQLevATqRNqFP31kg63 z;Rch5r?zZJs1~uCYxH3sv?O~4)lr)D zJT5*}cDv2Xe%?Mbuixo;s!e|CkVtOBM9?o|Dq_0iVYNH86pegZ5RpLhV7!7@*Kd;cT!CeEOL9WA0i&dH-1R zw~LJIK0vrg9zzMElEa%VH0!8*Q}4z5thcs{K6hro*-XhhN&SsfnIW>N>}MsnM~wTU zQ9g&3RMEKpBj1>rB-RFy)&LCE>EK#OAP3)udq?V-7OCwCT_E6 zr-eL?Ahkqr(%5$o{9}CV$Cw9d5nio^Z$@B~L92<$h&SsWCXt$8KE5a2fr@+4(+99i zWv91v&vCriM{8zUtq7KJA3i`BgiZE=L}p7!O3;T@TzO~qJ3T$<9!nqq*0qP{YE>43*`pfeZg6w!Vg!3&tN zLG^Gax#}LI)WjFAnZtK}i3+OWCbx}UjFBXk-s%)gWNi8|ut;ipBl5-jgpKIAT9;jJ zhzT_1tVp)m;A+acHPu{zW2`d#^L&@r&ACrkj%I_%;U*o~F8Gng(?>q%`G>Y*mp^lF zY>==cd!3+0C#)@e5p&vHW(NoBW(WQRoRl3QY1a&Wv4PC1^p8XCY!Yi+f=XwMf*jlT z)L0bbdV_A{BrQ~U;D}?Vc}Xhvd`O_7TV{lDupDcc`lh|){bK|LIk`biq#fJ|r`G@c zwG96R1xqf3V+SW?>cW`MMEKDXc4O#m&JCg&i#{n3v%s}GOwI?II6-&WkmEWpt1-=7 zVuKC%&=L5qIIfg0>3^XeF40fGqiDM@{k8K|Kw5~{KvZ%S{-=lb4%TvI?u)<0w!LeF zKPsgdEXyH@(dKEeK?D<%mSwA!JALqU&5t7Q+L&OPse~G+6vmlqfUIxKlA(l{e{Dsk z-R&$VtVSr9Q^PnKsX_1wSp$I{#5B}`wGLiQh$&BqPjA~?MO5t40A9J-i(0XyD5@dn)$h54ksKC zrs0FKu3wwCjyoGjGgK(l?bYm!!hhLF87zL9rO|lbE0OGM#hWq_-P0%syo)q84$pWR z^{m%cik#y7FlHmZA2@74$K;rtP029}Q;bGFPq-%u4KB_d$(Uq7lmtOi>m*%7<3Ju@ z0};}-40BB~PgKrPslKP{i4;?nod%@VwXne)?Bd@OYS+uxI{Z0qlg3K-7knFgQ@nQhLhjVjbC&NT0 zg5Dp>i3FN@nz(wnhSgJwdQxb-mWH3`E#+V! z6Je|gu5gzDhnOdXUf8b1Wz|!&45X36neX9e*V?DEBndzHjfiE=;zrQ7Cj0Y|4H=E( z`&G5$D0r*Q&l@1{CSFU(W}^HupUo%r>O(N*`Y=k-^(qkBq=mb6|F+XYh1L;80X6U| z%ORcUYI*-@=DA>a{^r^rBEIJyqJZbdWJzWA)O@^2&n9jym?)Shy@?QTeoskhzVNI0 z2Ko<-)pISizr6l1{>3XC6(xr;kQRDgK6vLSOJ|u9FNeuY20VW0v+@$N0TKEW^CV1ak#P`qs_vR=3(3h z?5g*yo?=0l<6FbXc8Q2}SPV<8FlURv+-gfARoC83}6HJa1=^2|b4V1@r zfQ12|a7pIS8YS+DLNj#>O(Z1L66(l>mqO0$W$I${A)S&xNH!c4=2n@eJWDro{dU=} zo5f2v*c7k<4dYkVF;ga~I)=221Th_r2XAW|OsW|u##OhFE{&5mXmk~6zOn-t%A;B?7Qu^c<%=6U${D} zH=~~Bv#Cvwiv_+b%ujcdF)%Jajd1p}!iL!}T67CDLe)q1Yp_HjLb~H{oq#ekxwbBa z;$DAdQBy&!X81TG%09@o!}a5HJ@$0J7^3piQzc8kg2RVjNRJmweqwz)2*CjPCaqK@ zamG%w>RQjkbbWWhY*>odp1jBz+!e-)T|#=b+P>HoPjLck7wPo?z)&!zSt~&f%8bLW z&!KpF_I-c;+mC7m+l_$dQy^xjfywPC_1EiHs>#+;mza#zM^)gR1K=^BGBrxtriftd ze)mX*l3iwT_vD~Q$lU#L^Kqlz3Vdxz;ZlyF5N8AYF@wdg!z3P&>7?>FVq;Gg&>k?>fMB@@r&%9P zD!P2bBHE9sw#CL1d={zMy9B9p$`;apNzZm=5_*YD_3AHHdo~%J*P$1O9jaT3M3fb& zH);?{T;*H}`=WRs5b0mUU*Q-k#aO)HF@tGsq;-xpjmE^81h!?QDi>Z=Kmp7L({Qo~ zD)I94dnLy*`BMtp!~9Ef^`FC^6>=byABBp z-Mlz$wY366JnT?IkI|q^Num6zrpNbZ3@^u#2tB_!7ptS;bO1G0Z)p>j10?&ds^yLo zl~xT~A%E&D6J=xWTLH_|DUb~Wzt^e|Z|ZU1Oy(aqqmpFx)n6E;B$p0Bdp3pO!YP%+ zGPR-w{%EY-ng_Si0vmw+c%X0-vLF07(a^t7XLamnR?7s^@D0Q%w%P#?Oo2u?&VA31 ztDXx=X3KxXHPtXVUtj4yR)8g)! z2V?SZRSj-O^2EmvReIq8xkZ<~Hu52Ft4sr20Pi?4*C7JS zx`H#AoQGTHJ-52EHon3_UbOOxBv0?MCOM@ne>%1{bPvZ{**hi!UaW>)w}MF7&v5@l zjM#&rC4VXTb%I+K>pyf{!Zr3`_UE&~k-tKk`Hgwq*CjL?w~jof$wyVUiw5-A+DSI?C&LN;)u2CVc5D*ec!Xswhz_oobiw5gxW)KEQdkOaGXOzW!o4$mj*Lp!&k_ z;z>`qsda2)WnRZF zv`eG**#cjjQCAB`qmXV5+B*HBnQzfOPBE7Q?yf`3A3%abdZ}QFH#&;ON8>y)TAUvu zxr|e3NWVtc%uw!sL zU<<0XWj2f-Z@xReFYSO3HsQ$J-AZrz(Z0MKf}hl?^fgN`(lwL*4HB2Nqs0m+z^pGh zs+0&Rm|vG|&eWD0y#n6hQI8w4)+P^sD3PiPBEIp(0}g&1j+tIXc~GXNH+J2>{y&Ib zezagbqJ>*rwB?bl#<5>IMaRivbH$Hu6$;CSBUv1nK4oFp*JM*3w9i@=dzQs2x@{V7 zf@OI_VS&L8GAC_hAF0p6c5Ys(U+Kb15EIeOo?-9%8=EGdUI#e$8+|VJEAFegY$hTP zXS}Ex39@3U8Dlhw_QewW88gJSRmrL3sP6x{7B}u))x2up;L2$qWk&5mRIxb0kWi0n z)uX;|a6F0>L6N2@4x3N|!qs0H$a~JNkJcm!NggPJ7cQ-V5*T#e#3Y{s6y9~Y*s!ZI zb$(!sP|pWs4l*YL?jA;5F=hWM34>%-Bx)Ax`bV+fwEH-Ks$i-Vvywu>mY4>0aLZLC zZ^46?De(@Y^u!>N%c@H1?LE<;XQ;W7S-L^fu;(^nWh{zlzQ;*pGu_g$UaGlMH^ghRTPhBeN zmt1Ib!8Y$S#Y*S%T$REqIU_f3b%5+vgr=eG1QRS#yxoOFThb%Jg{cSJ>RG;1-Ek_I zzzbi-px6!*9Z{}eA`MAdtOGh~6_6Ru&0qcHmcv&NR(9L7Cak8vw`R(U^D3hwwkd-LA%s|8=ZDR?>yS@HIcz`kba~ng%Tq(@o1@o$DFrswW z#z9^DDcx9V*7MNJ38zv{Ufivi(@|)P8NrINFx*J{1N5$RA@Atxzl|+$0R!Ef3T{| z4&qjWJK7i-Lu6<5N6gRc#0*CN8Q6yWFK;^3(k0`dWm0c(C>u+rj0-zAjx^c|iql(g zA!m-mp>RFjZ&QTZnYBIhbKGneCN6{&$w!BZ3=NOvQO4H~`ms^l^^0(olD<6we<5|V z`=#`b&?Qmr4FVg4+n{To0s8XLd7y5K-0JGY=x?>xT>@BHQ|<`&wW9Em1ow8W`11iP+N{l1(m{ zR~g{(6fsKo2a>rBqmdEf)vB7Dlnva}!3El--}41o z#)qD*kv+*F1|Jox*Hn9? zs#y~!7lMa$@WwP*!7~Vj6#Y`!W?Jr*^ePJ6hCg^i$iP*A+Ku#)YM}2y-q+ z`?+jCa?3}k(^GEC|J(i6WR>8LK#@Z0w>Ky^hsP;=A*k<~O>UX3B3JnBpGS38Kzl?k z6@z$N(Ff$yRKQDAi%nvOo`p%#7%GM-->&gKlbgD_}@FHhJ8N&VX znJ7@sNZ2a0(_*%)dxQ9;UEy(W_e~f63gEzJSna5TM3Gb^1V8k zC}p8Ff)!x@B6;4=YrW2&q1|%UB0t64qkznofFAmr)l0+AK?iYEAmzsKpiV(6YGo4- zrgHO%kv0|gK}xh~_tyiN4lC50TD3x`>~Jw@)1wXao?Tsqd~9&cYJH(Vew%o_Kq!Ck zmisn%dX&u^*`~#LN zjc`vqftuxamGAdn*|LyTZu`K^WSQvu@Z?aT6-ReQ1 zZCbWm5+el&vnCfNIuf078^d!k69I=jG~ZqEUq(`t)0o}q383tB#xTUph#+JVW1gmh zc`~Xex{kq@VdNc|N%$3^QT3>uMx+67I_7)IJL~oXtpkv)&m}L(EmT4SN{fx;dp20~ z2tAQ-fipP!mp@x5qu5w?HDK1=X4T)%eUHUNLlLE0NqMSGPPKO^Mr{nO@WbwBJhMR{ z;(#N0?w9}ES+j_(Y`63S8(1L*xKJMASUS6JEE4IVW4#zhG5QYmD&g}Vg%hrXonaVT zVD3p79e;^-=LR#4aLBI*(wW==do%lu4*o1}7hH5oah^Bsx0$066UH~}`3f1jp85Lq z_;6r2JaJHOQu7=nU-**hfz>Oje*w!2wdHn#FFQn4SeeMQBrBHDSFkg#ls^nB^n>_{ z;1Mcz*7#A{nB$vXDesqC60?i8yJMxek;QuLT`*!SQot%LGYsY|G|UIB@!ZFq+6if| zjzGz#_QPXx>_z4nK_hSo zwDTK`lPCHXCDfsv)Vc!}@msreB;&|cifjf)+zgBu$L9G2^7XQ)4l&!-pr`=AeHX14 zs_1((h(PPOX+re7?%e;-@$OB*H?uo~>}urWtrS>@f4F>BhkCqV>vlVn8{K0ySYQWx zw;=7*oHobSemjKap^j%IFdX$6X0*cSPndW|Du~O!4OBiP3cz5+4XKKVh=pqR(igOnC{mKZk0#e%Bw{)NVB4AYL-<1gxt z4aPvmb>48y2n%@I_Zi}{a(PBx5jc##@KgO8p!^UQ;l$#Dk43y5Z+QMo0`HD#LsxIR zoni!SH-beWh;+X!H<%-4qdcY8WTngHe1z07cn;(Zb#)dFrsb zI*$5I6Pnvv1pB6X5gZY4q&gACwP$*p81#9M<~IAQfMDC=*YK<4$Wi{NKe;ub2GqbS zy}o6#y;=q|ut<%VR~o7Z0FbjPtIvo$G=fJr8@>)-qA9doHKuM^jt|V6vDspmRjcZy z()@e$!_&sB>&z5wgY2oj8Z-q+j)9u3zB)?-2g0}@rPDsT@K;)f51E*kr7MMcb`fw5 zi+N~{a8D&Ly)6MJgB%-Ciyv^LU5qR#!@Xe^XC$`aJh6(1CtrbjP}pB>n!U3& z06{9zNpX{VcBcYHE-H%eZliuHrn(?mnD?;3hE|GY>eX~q|5Gf$Y!sN8c8Xlia)2&i zJNYv)XuhTQOdVHw#`ZAkkHCF$PPP*+Hl)_>4Y@!@8XxKpKh59Rp_Z-}HFwC@8lneu z& zK45>}Bvz>z(wePyT9ZpTY_bY!lN5WQa7#fX&vqJ&mWr_o7uyyo|A|_I?G!j%nna&U z00p3fyWlLyQ@44p1aQ>r7~F1rc|oVKd#}P_1Tjl#B3b{UpAVi*xIKu7uSLu4RHSS@ zV*Z8S4eojlm;8;&g@ifgLU{*u9s$U)4p1ugI>^Ji_xbtYJsxLWNbw&~<$slskAt{l z%eotB7zi>g{OjB;x{!qyD0G%w$<3(9-}{dql7ZFHm;0py^u*VKAEQpwKf*%ntL#vi zY$ac%rps?nafXe1sDVo(QT3k=AFW%0ZQ86V5=xn}9)qk~-pFQZvNjkGCf^J-@5TIG z1D;L6>^d*wQF=_>dOIlOWIMnE*!qpgp|?uCEvZvzk_^$7XR)mcFjyVwbrgj+(YYoR2I=WyH|Jhvv z^J%=r$4!_PIX(+KA>fqD^!RuTZ zjD`;v3k5q4O5z%EUf)!2DT~738r7)uL;_pbmBk>zse4~2BTfk-vnv|0)@Z#A%+-ua zoM&&HL$ti%^wo;(<$YPPa6Qg&@4qx2Lx;gYfTfEaMSgw3MmkjdLE7j%5w~mt?8(TT zhMH7Oo%_J51`}kd>TLP|Xr`*=C4-mP48S&eghF@7Af7~d^Eb=RT9N3x70rs(x#~s9 zjLpGO!hUmX)`sqSB!pWudu^iVK6EQ$TxB~{>F?v~da^}u?JQOCYog-HD0;}CTEN2Y zAdxrv-4AtWk%Wp1HVFg6M`C@W#}c{n#Yzb3l{tr?{wgv&+UY32yhJ7MAk6%|&;c0G zC2@;2_}Y{zwG+_~3n^kV0cXU#K{xob>7q41Zf4jZYAL(Vu!Pq_v1>dv z^jhGNB?TJ;$uzY8s)=Qi&&<`$w%RT>fn(L0qkF5fE8n-IIAt-lRRQ-9e$^iu%rHRV z46&R=(@65)H@8_j%yY(S{UjS7lx9vbl0J{hg#;Ln)H-JZtIuU@_>Sj6a#jsO{Km;? zdRc<0U*a+Q+3mO^zJ1pDd_T>~72SFwtuw^&)bF9}hGc*mE*NXU6bXqbIeUddmFWKm zUX*i!t?gHULMMwruyl3)9@}gfw*VFft0FrKgWy<#Pzg+QO6z+iZPHA*O(A@pEHII^ zUW!FqegTC=yZ2hw4f(SyJ?JET%tA?8+G62bcD5g$Z9y_-io}4NeK2fMdtdU{D3L%Tq6Xn{I?rHoPr92(oxyv@5MX0B)d{1P^2j`{BG2Gu9;+cmW!Wcz|q>c0ugdXI6S);_|B45LZN?e z;y0w`Boh}oiaVN9NVkt!$?dSHqRZ!f?@wN=m}+Y30Q4ieok4aG{k+~&RBlG$iVHmQ zx%x{5Tye;r5LmgOcRX&Fez&8oGMK@6E4@`O?zO4fVa*-RK6-(hW}{`%R>?QZ>Ws%R zvxu^9nH8JQSqXgew0x3;>$p27G64N5)am2;a?=w=y7;Dbti%QlIUvDJ@xA8mIRp0= zbrl@%hZ~iWO~Oh_K*U~w$!)h) ziw6$2%-87%3Yn|{Gj}00I@Du+WZLFo^{0|-_K_hvhxt*>q5g?`f^Q+4Eu5$Ea=X6Q z3igF|ocxW=SuK26vDaQ~4MO|0S;=o?J{VECArh%7b>>SI?KQt*2icgXZw>4!$R4Yn zx3^~lxdi7WHlxq@=pj|=&VpmHpmllVqMc;qG~ySxtiGb2i7n2RO1q&rIP{zKCd-C| z`)9$-k!U<L(rIwffkhBAkjtclHZT)k;0G|k5huYVcpXI0SIGOtE4$v z;VU#o)_d7^v_?M`sR)!ZU-fhmmOLgqAHZKKJmS)CJg7S@u8e! zsd?xd5Y^zSxo=|;ft`7Ta4)d?A$LiSI8FjS(ojMj?To_C21LhSl{Mj{HR=$C979*e z(8G&TFd?!M91cpDAe3OY()o;p_g%~hSIol5uwJ{oK0Fnr`yHm0G=pEAi7h!t2LdL5 z*rZBu029f&K=$9oQb7B8U5a9=xfBKd}2MVmREI`+TXA2 z|5X!ewu7`2aCxZf9Uk9$epL?j)!W&#P?lZ;9G8N!J)5n34NcUP-PUNnc zVdcW>3tU8|J-P=>Ty;n9H0xPT2+X}K0BsHsk|nWpoM zR)DMMKZgAe3v>~JE6@#ib9#}YEu!CI_dU#Po}l+PLP3~ri?RR>zg6@q^fs(ro5GEM zz@ETg679w~W}+~F8JvH~$HmtgTXJa3Nv_{7^7OKv#pbK8`9s_aR4-hiiMi9LSsZq5a+7599eu@{ox_ze2uv3F2f)0_PfH zNnGbz(d=~@IKZMXurrVw(MPOl^Kl=o9>XqlD-AU4X`%)@EYL)ZMS}J)mlCcbv1;`p z%KHZ(%`(Txi)lx`l-enk3d9`wjeY7h*K0~@N-$ptZulT779(rLEZE?3c-<579n{+E z^ilbgL$@)Y&e4%3H&-D%$NYD8;FP<^Vh`+-}vt9;iSwG?DH90fJC z;LVo*GVO7ZKCn7Lq*I$ZltMu=2&BZiIY&U3Yt3B&+_ z+$IrEd545-q9uE>LS2_dVLSAcuP5sLK`>mW5UsSN@(}YH+kt|={J4sk_`zxOwPJiS z`uStzhHWCkLZrEidDBG-T?@}X_nt>hCeBQlg4@czKGdHXt=biDE)h7q%#Z)3`q4Yb!7n20(;-T4sjz8Z>45+g2NVEj z>#rmCr#<%FSYF9#Ou3w+YT$%twGi=~S+bst%EbNclu_66Dp?}q^1rq9YI*Y-PPm#e zUW5EYrqHGFr#sg2lN@n~d`(J?vty_JX?Tdq0{Lx@e*DE`Z#Rwxk#K$Ym#%Ob7XKWJ z!@THhqkK<6+yhTfKKc<#$z7j$Kq{8^B6BgtLv@=@4q(X&34CE@{+Q?Y^2RiEU6fbB zg2o&3_K>*{*le5k@oERLmR;YPAP$}ayzzlP99pY#5K`OR8QB`z#VXGga5~uj`Kg#D z#jzfbRdWxee5Z6zLCdu6382@xHA>Xo`)+PG=Q>cSI#(8c`k!&1AbB=fj(o`!@FjA4 z!{)YiT@~iRZbYV5|LJ37FEo0q#z{pXKE$4C4pUMA1__nC!kWpH^&WrRts#NVr0eZ7 z)`P{LEz6=1dxc1bkgrdP0?@)d*-M%=T5D^Y`dDeyE#P)fIvhNgI+Sl))MD)c)hVx# zz8@(LOvfF&+QNdMs_Ih*;3A02a~PWV`7#iwt$)Efzl_OzKhK*iKJ`XJG{Wt{$*s47 z#adxb(X(FukwIV3ejKNJPXC|mWMs7*Js=6$y+5W?*|QnwfVeylzLQ4}c|2CT&ZkYH zySF5ca`j6NTT|JX(T5%RAorB&x2iV5f_Z8le-pkuaiWEEoKro}l~Kv^_OU!iDl!#_ zOdg}UG^mz%ve8)6EhU5P+brJo2S+qYox^xyvTmERIZDhvD6mqg0n_3z3x}YvNzb+! zB0eT)HD1lx{0x)&YN}~X`+ei$1pKcHEEVvXt>-J}x|9|Gx~;_&8GZ#~O<1e=TyGMR$T9GjOWcic+7id;;Twj=;X#GXM zfXivG-5LjyKT##XrUIg2WB!_V+yyu@A3lt5yp459D$4u>8V>a|6IJp6{%F}l7zU9t z5sw_ZDpP+%gJ3~`Q0v=mRuYM=^QtoBe#$RG#?xq($sTpG%GIf<{)%ALlSOcTn6xeX z+jzf6y8+2~9G`N7YCq!8;Hh-ujpib(NYlmW5d}D<%~t-so;PZ6F_^zY4)sPRVE{SW zO!yQV0jf3$a;RFmP0q~ktU1jnt))8GE>CE(J2O~;b!Zns6Fs0^NWttQHpfOo=IOd> zvMam#fzCku0SF|!FC#RHQ?OLS8<51z2yMCn%Vzsr5#kTM#!sY1=tDy?3e{Em1J7dn zkFQ(zbCq<*Z=0i+r|=f@@j0GnF1|+^_}%VsfH^z45|K1zTZNK^jKf|OO{PPe;LACj z9QcdlyPX)zJ~sT5TQ}2&$MA43mJ3lgJeP(oP_CHFfaU|YD`QuMB9bAZl&X@bzf`4E zE(!{%cNhTPigN%MX&nvd_$WQY>{lzQGehx6G)fp4m`B?R@?pDe)-DdtuY0VMBNm7@KXc%|ek4}J( zmII)$f4!jFp2Ar+XgAP7r5xsxuKQa$tj+)Xvwdk0I4wh!;M#`cG z)!E7MN`WeQb3%8%HXBx)aAb{|_WlYo0|k=HlI56P(!K@|b)N#h75wqPZ$z2p|G`bCkk1GDtsJr`%cT$hQkhkS7zDZEiVWUm~; z-kXysz}aju(X0y_$C~a5dyiWcL=p=KAO`9#_vevq@6&!8FH*yxcNgf>DoKUNHqp04 zHj>r-k6h9rLFfwnpE@X7I91n6F*z}m4MJ1wRnVH3p`N61&b(kX^YX#xhMgBh{?H=T z#tI`YQh%UAd`y%b7^T6h!h*Ygwra#E7%+6}7th+Q(oCpFgNh4v+WkBie?w4xg9l^4 zOuu`xGKK4n5aJR~SC@TTuq=#x^RMYcJ7NkC`#eh@UxS;##8 zZnKlU=dB@4BPJ8QYk*N7y5Fxnju$-bk-_{cY;9#1yzfGXMyIa>o|>L9?5ZQ8{tk$1 zhfOjd8c(=Qs5TM^AeQuR0qGE1EmCh`Rs`IGfPj!_UnnfkCT$nq?R%HVQM)CS_hP)W zr8s*kS*Kzh4oSbsQmXX+u5+}kBE(EBJEMb|+RzZs0K3;8&513l77gp$NKjXjp-{;s z;s6!8Q1)+jf!gscjkpA8ZmN8%wXQ!3{UhwXuKn?8@D=mzD{37C49kZcdy|86b58@BGXHv5bd8s|#r(GafL z@QOME-8DE@x)@Bjy4js3EiWB-!6Z9q`A%BGg==5C3#k~rs(l7li3-^JEPFnd?+P4z zjs&v9=bYlIm>xBNucl9`2H_ucANWrdbhDn>V9VBSs2@J5Z|khtJEu|uHWhOQ+kj-IcabRcVu(V#G#lHv+%~Dzsd*}0D)2Kf zWh4Yx{a6*nGOr*#P4O{EeQUWFVccmUyyyW)!wd>WXrth?$~sXlS7`>ZZ_S^-Udwg+ zjjl5SP393f9s#h0J<~Cn81$UpVD1o?IR!0s7_`cK&dNi6gJ1D@P#JeZ1}p+76U*EV++1cE)Y3Ea!rgBsG@A&?MC#le5hUv| zKF%{l;44&ia;-@6%)tDZ-#clY$+Uf(co*V&h#eQ;i)*T^n6794@R9X15rm}4$X6l8 zZT5*hQeu-A*C4g-?&P5#5}w8*m=@`jXhEC$_-{`q0NwG)8iL)jrl3skUeV|BO8x*; z|8}PAsW(_5KKkxkM2L!ylT?9Zki}&ZM6~ zIyNZ1e-EdqhvmZTQ=p+iPj=o-H?&VQ(^QHaFHwQH;2z8>jujvly0)jHFOveZvkjF- zOveJC?a8*U!V*K5P;0EszlCXA$^!p|AY&awh9kZqJ+?}L<9wp%0T1QnDyi8Edz6P8 zf(gXXA0wqUUdmqG({AfkEDWCu^OIL+xzyans$ zA{GOGqBxb*@8%!C1X7`YF{GhE(xz)~7Fesem>%+7(n!F&_Hbm2J{3Nzz@D>$mueDk zVwe^0eHHF?bU2S}n_>5R1974=lvRk|Yn-aN6`?o_)C1>gkDwZ#Nj0YS68oqcjO5vHlYyR` zm>^Z09c*#nNgBrKb7QS+Qn(CIFs98P3*HT`PswKn;wV#q@?DnVt@9=&DBgT2$5(fd#)PNpKp12*;90k2`Yz(G7nhRY^oPEC;L**@w=YtKo`-G!v0zPQ%DgQHJx+waw18+= ztgbGDT?f>!A5!{-#4ET;EcPOooDm^m44hvzK-e%MdvftS4WaB;WwUkKghNQ-0-N;*5)ZU=ykH!*eRrifjyp5RkS6 zYy@&A3z>=z*5tsn2hqkxEs>`p+8~n`ou&z6Zp>#(;zR1@K@HXJ?=;6(X z1v&dPChvf8o%wjy0NB{67RP~;6A?Cv2FbkocghSTN6u^$Sj`q`FvO;WYXS9B=KOPo zEmZ;jy>=mn^H0PUf^M*wtCX8nz7B!vJUtwOjz-=-48L=dNs8ANvuqrx9OyNlbX-y7 zm|-P9cWiL?`OV+Gs-^nG@ayV5-w^Fn7*G)uN-0hXVZd@*rT&P?M;j-S{_#VMv+1~-&mSt z?o2+_9-_Xu`I9mWV-b*72tm#7iK6f#|YlT=Of; zk2z}4VWQz8J`SX<7jChp_TL;pYsqzk;o=O6C*ceAjjR{J!&i3g)2SlPkJNhT;e$ox zYJkiLafN7aKnj)pUlU9ewdoPt&T%uQ&&0bbmU%9$c>5(lIi-u-ThH)OtTd{g59MF& z)Ms)-^Q0QZ#{WpNBwIS?aiwdBMA6@cCQ87`d*NKv_Tj%0@t0~)x>1{PGjG`g za)24=H3_H&j5_aj;`-u+%+7Ome@^GBd4@njGX_W5^|fQt+bB?poEo%$0mg_~?70fh znEaqJ0mveoehZdwtr+*6JSQLynu1&D21mve)`CPes%2W6*?m2xG^UBRrU626brgoT zLP+n6wlwEHGW{Cko~N%(i~g;OKxFTQeKv)1wx>dI{JQa&jbw9EJ~1k*H|dS^gnUcx8|?^|K_xzix>~v@Gx@x%xua$pw%m z_Q~R>g0K&yTafw$0gWa`aS1E~;l=tlf3gVuS%NxguMwV<3Rd1-M3*L7U zY#+${pp-MXD+tW&VG-w-&lh6tqaL_u)Zy(QTX} zya<8Man>)b)?(k4gHMd3O_+3S&$}U09X1EI#Gojlwjq!4YM`DFzi*f~^Hq=-=+xh- zWx<*c6PMCllw>F!__((P0qn(le#ai<_$`vt!t57mp0Q#6M1a#cQcIDLpRJfc3teIR zsMV6^f1-tfI^X8m`MNKWEiG23gGmW}-aA2X^+Z)+2X{aXm9Jp=4ml-hsJ>83Yi^rd=we^t%$@wJ$Q&+(UDC?)8G*{I@$HLttmwsWl}h&Hpv z3Uzz|j4q}$8pH4-CgZdUl~XxCorniKsoyrbpQU=oPZg==X^O97(DS*oqZ|h}Cq$); z#jOZP!rI(KT)+3JhhmuGjm)dX`{AMPVd=*)I0l_87#tkQ!I#r1?+eg>HFrj(q*~z-Yrtxe3m{ffN$3b>{ve>}AY$#5v(X!h(FDu5i z8Qvr21WfZw{WzA>x17`2jW*a@5f{;>AX-TvEGYi2g1!1ZtuqWvM^px&tN|;0ad*T! zEABc%so}ICw)=5h@v5%AcRWEQO{t&EY#QgOk+8=zC!Fy28>*IC#pA{V=xW2h`CGrV{p`bpVlqa>cigk za%kfKfoan5x^0SFsDZop(0cfSZedVTTx_TM&*zs>-+h?c-qz&v7NKl#Ilv?CMwGyt(a`#;@~BV^Qt1==#5W+!_TeAd@e)8gU@Me5 zA7^;CC{^e}x0w^!)1#<%pc2o-+p2SEG;~HXok`y(1!P^4)&^%Yf@I^+Z6i?*3T1|6 zqr1L(CGQ$m?@En`I~+t+hHx$rBG1C@gw?58>0eVw0kIh{r8>CFgLJse2A4z5it zQb;A(N&firy-ExZ=tDgldF(d3P55i;9NBKZ@qc01?K_;!PI~EgN2XJwbwK9i3=t)8 zA0P0fJHH5NbTR=!AMI;yVp!{&())&A3}H5;_^d?mK9S1FM6IfT+_hFr_*#W+#wsP> zT6G35KQ%Xcn}mR^|4RLA8O-K zQPRFfnu2m<&BY*U-M%KA{BR<_LCz}8N$#CplDUC))k;sYcOUl&&DAKaKqgq4$ zp5Qr5E!p`n{H7WnC@sBgs>-rD0j-L{9MZ|<&UNQk1B`4=B**m-n1;hD(k#@0s;37Z zG(}-XpuAD$k+%n<-C<&PYEu0eziYn=`nj1c1s+bNWhAtpJjK(mRBYoxmL3Azi;_K; zYstC!{}xHZk{Pym&~9}Vgkf_zNtcXz(&8my(UHkKFxl|d_&>Kd5WCM0GJ_flKkm3i zyp9mDD#VDON(_mf#I%0BqAg@Ob&t55R-rdB6*K`}9-+3Q-dS~Zx62^%W4T1LI7^9^ z#BYzvA{)teK?o8eo!EC+8^z%&Kh-9VsG6i6Q1!Mx4Sf!Rbwp%5kvPo zc4@UyuWMnWjPxYOyXS7+J)P8)VH7Qp3merxvG&OV(m*Ra8CRd1Yepsgp*%FShC-*9 zG)Sl^GPfy$p%OtNTc~}>xqAe}2W%jdnguO1;-I@(cTG(Af;fRSmCqBO0sHLg`$I*C zJ@Kt#cJkI*tSL8xKFA*iK&i$hm+1^Lan*SXP+Solo&OdK*sDjsZnQ0?$z=3~L7}%@goPg!O71Yf0 z+}u|T1Eia6hC5&i0<>7DM9SkguAa`b;%5CGHYclK^~oZQRE=mq0a``$0STQ=>VO$Z zN+>?OdBY~AGo~#&aNYkoXpG!$;m;#yhnZ@t<~V_hUAt>m-9V>fFLJ4 z6Qik*o#R@=(Qq@rqmrw*w2RBZ4>9`0MjKc7DP^$+z_^sj&c$6VMJX2z_&D8`DTbjw zZ<7}K_?U(r%bt~#7z4nd-w2;b@B(ABwUZ>+cx1H>Q|wSi-D9A^2~vGR5F?bf}=}>Dc;WL zf+)z@n`;LSYrXP&CLxvtUKD&O&by1HhjZj%qjOQ|%oEw|qDcS_yhVx5`v{1kY2Y8V z4S=Dg8l#a{`qiQNlrGG64h`?Q#B-CKi*8NP?+fhXu(FR;WG3zq-vqzWIWEA5kK%Gr ze#Tv`+htDjBBmF>$a%wQN*Q>I0mR|5Bz}(O85{$zKwLmggsctU6%QzGU)LDKP4tl& zu|9vUcQt5Zce3{tz#|p2!Hrc<5OC?=hcwWgQPX>1_93Ihe*B%B&VbIm{x$^X?54mr z6dYBj#o2lE{*)rb(5~I!H6}TFHA^}T+-DSDZtJ57As&~kG6+gK?QU%qMCg}~-#gWX ztdlxIEzO#QVaPU^)}mom&3t;kTHyvK$nbP~Y^=93RrkuL$#~^5j zoxBwSkL&_r<3_aBBkK$qoSuGgjqgCQt!Se4yk0u_hkc1VZHwAbkC$dUI7&q8n1~A} zOp&*Nju^|Oo(((NF4-ao(Z?|6A%$)OlnOhx70H?Hc(kE-sa>i z-^w5FK}7(IKjTqTw8@>jF9O{sSeg_Lq0c4^d1Yng$^DRy2<(-6k&5z?4x-Pj-Ha4W zpWwJ(khz-@G&p^RRRIG;@gtJBW~fCFSe)nYasO!^EkDd=-!!^mn$4e)b30 zHK~=CA^uAR3PZ&at1jm9aT82OR@Cez>&TD{eV7WQLqW-GXebR+t8yZQQJi>+&xe!y z%p3&vJz3avbeWIwlmF2ab7cL)E9oH?2^?}pwv$%QbB)U=m3tET#&+ z7l*8FP{Fy*Lct8*pF(J-4!9IIY*YCg(!!&**5AE28gapCmKXqds?^|3c^4rjR9Q%9 zT>{;FR@R)|m3r%n@JRe>_9J+5Gf0EkB-ppbng!J0mGsi_9e$C5IZtezWs@}y&>osx zrGaxdb@IwrjrLe@VyUP$H=+2{MzilfigHL-v7rzptm^NfRPAuOeY)j>Zg=8J;5dJG ze|9XJkPgW$c%@@mnO~nYNFi5O2oG_qR+#!}O6c|G!whv>2iqI3#)&VKY;sikV6j)? zdcOjL9{nYDUzDp9t-a6hY^BPR-j1(29QBpT}Fc5hO1t;SUk)VW_?qo_qwx&uPHU0WdYn$}t_FPUoU#FjPG#d8c zJtn&muwxm1i#$_quHd4NA^=wZmO7{q5{&Rpb6orC1)hO7HkuJBR?Y>IlcL0n9x5j? zd+j?o{};&#iFL%+l%C>+O(v1173D1?SpY;pyT6H{dNH)+ zWuQY`E`{FaB1hf5lzE&0GJ6RO$hduk(x9IrqQZFAbz7U zQKkFeAfr$l8(6L~g+74VpXB%`w}EI5z~+7mnxT(KU{eSv(}Ofdjq|VV`N=iQi{iPJ z8|f{>X|r?d&7rd+#MTt?zf4ve{|5sai`&b>yx_n6;zt_-tCiH(^*Ci(JOyCVBKFmt7Z+>XA-TCnC>~U0GPrv3ah_ z#d)T>AEb!%vP>st2`pOD!l#%COw1!X+6s$Cok}76MZeB+U3&*g;S&q(F||^e}Vw203M=_H?L!PJJXOiu!{}$yz|vna`)^?j{}d5w^R>Hux}tnEV<>Gw1QW| zt=bA|AWI%vRinME)eY7#VjMV*{9LJb+VM0vUsndZ8bpxdJ> z?=)M(l}78~P*y<I_)k5n#gmaQtOCz6uq@^XdqpFDIofT%3bq@bGCgaLeX=TpME9JU@WB=_h!hLTEle z25hB45){&p9vwV$$jJg7@QqRkbq76|(~eHtjIjlG3oe9u$53qd*miN}oa>-^2(T`GH?_Le4G zrbR&UfBeo|r+3~)E^Kf2I~0L5O|E}M1<;YbzF*nXY{Pcn&GP_tIO#n)VM>9guuycc zIW;57H=d=R@h)iB5HN$jRz9a+^aA!>X~1!?f^ej4G7dR{&-A>R-A4~|8p)|EF@sfdrAa-ognt7L;sZbjOV z%H5{*sz)$BYxZuX;V@uPC^Q_))Gnn>*&RS;ps=mgaDwZKfWvHuy~D!1ieab_y1xShW4nKOJIMlH{>e#AJe0X$pO@rAw3VI^c=#(J9MASAC%d& z5_Y-_@y4{-+Q67Tn<>4dPaap$znN)2k~oV-O>YWl1nhguGgx znTePq{pg}3MKxEfx9qFzqB@4aZlW^jKu>`n-$bVWI|NzBW|0^rf~&2BBBMb-p~(x; z5n%YSyceIOItY<7z<9e)e0pF5yrgFZ&MdTI3Bl3MA<25Z-XZpswlTSSrUv+FGExXp z>h<)K7OK%OPgxI+6-D5xwsleTi6doFb+E7LyhlmLU~)YJx}{Q^sAe6J(2W%FqvSs7 z<1NICDY}e~Ytf*?u0_M08L-)L#DbD1 z!lpxusTMDo?#MsvIG@+;mXpHI&NxR}}yhbX7$ypKUX06H0*cyo>Oga#5Uep@B!+QOh$R!y_Rh|Z+%B_ z09J(PTRiF66u;PZ`p%Qyc{E!Y)OupM7Soor%G$F(yK|9!)U@w3?;~J8^5)jnNMn+@ z^aaXq^IURyx~6UsJ)=CGv~%nNV*>*(eX5S!!)A4KYd2}BtuVa3g6wCbEi<6W_Fv!=kY#Cqme&a_~-=yzLbd=WOVH2_1DJ2Y;5p6HLrN&#G zo~cx|W||(p82wr~RW?^;lQg%BgVpj9yE_F`hXO5)H?{>YswMkDFm0CRYP!^Zdb8(5ZN72BuJ65MP2I0`MIsbem)}XPFz9Gd-u<2T%wk zeJf$R?Qt?XkcEqIb~GAoSJWg-UMv6jOPlp$8bv*gCyJ~vNK?87ZvDVeIw-B_U;cbz zu6fHz%wOA8s-9Y}z$;N5w9owW=JHpaCb0cLX0EB~elMd+4f|REBAOAzQ)AmM(Q9qx zFM9+A;gTBfGGLHE{&)evlPN%c!&ihiFOd^*X*R&Qm8_X(hij z+8(raX)mr==bC>paB8L6wi)kQd7ALkt`-v0-d|5noR)=hQ97FL0kj!n_iYVty-XZq zjiN&D61nPVZa**))Es}r6qPM<+9hNS02`~4|Cd`Ej4`%B>2GUdY83>l_s!I`P z&ER<>LHc!u@PL8k58dee*ML;GMP(Q*?9l1^FO?!k;xLWL>>o&(5j#cXiCHhok^j*E zY~_~9Bx|LQVWrhJsDfZ~_6C;Cyp0U_cp@e8nMK&3No~3pEpmukAfBlMP4d=t^VH>g$6W>0d9Upk{$X4%o}VDwRzN8=4BBs{{!a^hzsVCTabC@; z1f{GJ9kZ}7Tssl|L(pfgBWd!K(1Z9w?6DaPMF{c2?*T~GFj8tdo{09}sDiaE#wz0= zw*>L4P^vvm#rVn0bv9JSPoCS0AcU-gV*EO6*UbVuV+){R)MB}-T`7=qBoh(4-Gb>` zsPMAv)kHJt6p?V*3mEp#ND@zMlP$&}!A=jw_n}4Rko}0a#2@SbAwbqU!*<~bII;Yw zK}B)Kjh^Tp42aSN09hTrx=Ze<8yfc`D~}?-_Lwyk@vur*l@1$VSy7|eihS1M0IEw{ zRMbWzX&GEFMi$SZOPxh8IbRwb0NAB4)_i7|qs_bFM#gz~#Ll}z7D8+cG=3+XY1}<< z0M;Jb)6*@M^M4O!OWl|16dq=;ZC@mlZmeEFo~A`AzdT#f3*h!XN|OK6cWz>y`!6;! zq?HdGUOXJss_AQX#A_F(qnT$b7lq5hi6h!!FVA6i$A%77aZK8-$Wl+`Vt6Z8P*q^W z%?KH{9rD6sqZ7m)tN<}diku8qsgW0Bs0+x=<8B+Lux6#2R#u~daWSSChT}5*bpqjM z!Qu^Kwj_6r2*-x#TOTTo+BYYES#q7(Q#rQq!==J0BCSRE{K{q-5A%sL#R&WIk-$mg z>y3$y3!MQaE#JpYo+SCn{&AHMgJN*7kp6k_01C}x*$O7-2MM4~@e=seMwd*X8liSu z?530(l%sKR3}e)*JBM*)bEU$$0!bdyHRT2W`WV9;_^4Bsj3@aPM2-S}r`086+bit6 z3gVNMYTPxl*fyCIUiMomVVoLH9QpaTe;3?-pR4cm{fYT;RJ8 zl{oLVek_Hxeph0_BfcYy>h_hr^Xm$5$uW?BKi9-%EAGL&k=2Ieo>Le)I*rv zyLQsql6i%dMwHQ|a#(UVRaDGlx07OYNGpe~p55Q5Fl+ul->>7gZ!&Z#N8vY}{5DxT zJZ1UQZx~bDuCG(b6*Jq#oMFQ;j5ZVoU0_TK%%+O3?a)@#J3_c9s~%t8Pc`I4Lgk&i znUOVTxH3%^a=KsBm7K9`Z=?#_>@SvmGABVDB*)jqXB;fd2es!%)x#*{CFd#Q%%RXR z?+q2^jLEMPUE+?U_z=(AEO@3|VxGE0KO{f2uOug_^MmyX&-h-SWOb#osp(Vta~6cK27qXZ?@qtStQ~q zoMMZ0shLPOx~&nAF0McI*J%c|y(;V_*fY>=rP%`UGiU;Ik1e&ldzG%z9ub{^v&vPN zRqNr3eNS-Wj}S!^fVmodMd%kAfQIS89#~oJH3y(@G0MjDR^9dc_Jb;8ONl9jCwOR2 zf@|3{y|qhlB81y>zv7EVc4w_p)ngu2jGsY2#@$fWf#X8rIz8~yxXycV^YR;-MNzj+ zT2d*p4pDQT6|;PxLofgS%iwd9)&TM4BK=*W@PkEYUjeS9y4oQ2f}66S;QB2gsJo5o zd8y-o@1b0O9|4JFB>VpA?#?0`wpcyg-lE0$&1Cz5z?|D?RFWa^dA=kHd~}w;7DcBC zPyqGkHn6smz~Upk-2*&NMZ@0DxpnwtNAgW07lqsYKcw+UPdqx9rR1C`*qV*=+){pb zkY66U6mlNl{uL>Fo-2OCzuGdfCV#j9A|)z3N!5_O1eTcPnlEnk##E~Wzeqb_u_qY7 z1g~mi&TRvg=KwF8i}1V6rup88>IHPraRMmI;(I=V<5H;jm!IbEWZAeDz83X{wmzNy zMt}zc5XD(*&`t$3ac(8o4M$>H2hGDgyW91pTfZFnx4#}25SZA`zFy{a@JQS~C60Sf(M zt?HvU(2Be9Io=t)HrB-X^I+4{XAl-yZy$va{yAk-oz9Sm)7nXmc!x?QGQ+>?z(MCB zQ3mQZ)(5?2KbiReO+>W;asS;?f9-CbJlpP=`;brZm7gAr95P!Wn~#wG8l3^-ISAV% z@G{I2y82Ipnpr2YyKVp5!AS|nQU^aS>Mk^pc^>xb-C2sa8$B!T*&YEwm_fmD_bd2$ z2}J8(9>9ro1mk}F8F(qKRS!qbdGXDXm_&|(u+{3suQ+=GCFQ^7o(W_Cr8b@hYWbR8 z)H$UV{oRskU>+9rL(P8gWf2IQT!~KEECe3&?JX@q{e?E!2-~ z=Aq>+LYL<4wboBYnq*J=SW!Uo07q=cSjMhtz$*ue3IMuei z=cd*T{sYVTkT49!#c71@hT*|AadwbbN#oR7?+mWn)DlIjTX`j=L0?R10V@DAf4lCmri9XX4nwQuqX&oa_1DMRADR;JN%M1vAQ4Jy+TG{+ z)zetbo9Vf(GFmd$_zrpTKaq&I(LVD|DWha#mtcDD!1S`qK+R$5;_3!hq6N%AqnkC8 zOyQ*mM=k-tx>-YvsAB-mE~;Wm)th{<9OA5ACu{9To;>ood3s8P?l9nkZ!|F zD-741=m@^9y*xDr!z5HCB#kH2%{UHx_@9W40Og z-9YY!JNw?V)nWU{eo-ggYcJ+T5kSS=t$1``vcGKu>1T902ag$!(=(REpuRHVioo_o zZj`AgOg^tJ4dU8^o={CUC0s>ZiNhC&ekDIp&i-OYYCbj+bD3epKKdXha7 zC~;uAmoB*FPRY`$&_SGmXAEVl2>u2YZ+U!%GqBstRwD!bNj+LxjAk&Kw!Mz80pN6S zqsnczt9-8C7}huqq&{~Ihw8;Zv$~_VOUkOa>w~9H&=J#C5YZ)Jo%_ifF0+w);XVxo z%E|3IYmP-q&}@e}UdWCzR3;tZp3}re@(#78YBPq&3RQre1N97s#UbO2iyK3Y>6lXkGZCdWM=M1HhA@n)1lCV;!x8v z;GnSt=8jE<%E-^0UFZGZKkPJ;h4qyD@bW8Re&8`KFDIG52vl@KKBTQvj!xmsZ*3NI z%x2L{x2?z`pPeYK)i~D_!l)`jG3SITy9p=UM@>*mx){~vHIiO_WbDaqEvIJLw(Bnq zcVOC54)>v0f(?mMf2WEyygxuMSE$N&^%HlB=jiRR-Z@|x&3<6t(KiK2D6X@qQ4r9$ zm`Dsn#}9&ED(JVoynryIYnz$3lubcAF^2R|lVDwhIy)yg53dFiY~m*+`&?|NC4GGU zbl;~6($|N+c5!wMT~F9If?uJ1{K4krw{gmUTurGYNZFKpw2^^1DDzR_TXotQK-nrb zLxa>UPVe)iI1e6xd3ki(vS*shRERL@;*px`z65EFY>)T_gFrEZ|6x9!o&Y!J

LKoTzZ2J}LyrD*@g;}zBcFbIWJ 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

$*m&t<~XPhX}A3F6}o9AK+Zi9 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 r+Tn^rRqrIo@({3QbO2|a3X3!8g!TRo^!GN( literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/X121/14030217/Experts/x-saherelm.xea.mq5 b/MQLTestWorkspace/X121/14030217/Experts/x-saherelm.xea.mq5 new file mode 100644 index 0000000..68fe87e --- /dev/null +++ b/MQLTestWorkspace/X121/14030217/Experts/x-saherelm.xea.mq5 @@ -0,0 +1,366 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Expert Advisor +// ---------------------------------------- +// Name: X121EA +// Description: this is an expert controller +// advisors which provides a mechanism for use them ... +// +// NOTE: about provider instancing in multi asset state: +// you can provide configurations using this: +// +// EURUSDb,GBPUSDb,USDJPYb,USDCHFb,XAUUSDb|M5,M15|0.01|X786|true +// EURUSDb,GBPUSDb,USDJPYb,USDCHFb,XAUUSDb|M5,M15|0.01|X786|true +// +// or make the instance use this: +// +// XPV(EURUSDb|M15|0.01|X92|true)XPV(GBPUSDb|M5|0.02|X786|false) +// +// if leave Configuration string blank this will used default config +// and One asset mode enabled ... +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm X121EA" +#property strict + +// +// START Definitions ... +// + +// +#define ShortName "X121EA" + +// +// END Definitions ... +// + +// +// START Inputs ... +// + +// +// EA ... +input group "Common"; +input bool xEAEnable = true; // Enable EA +input int xEASlippage = 10; // Slippgae +input ulong xEAMagicNumber = 1604056; // Magic Number + +// +// Providers ... +input group "Providers"; +input string xEAProvidersConfiguration = ""; // Providers Configuration +input string xEADefaultSignalProviders = "X786"; // Default Allowed Signal Providers + +// +// Signals ... +input group "Signals"; +input bool xEAEnableLongs = true; // Enable Long Trades +input bool xEAEnableShorts = true; // Enable Short Trades + +// +// Risk Management ... +input group "Risk Management"; +input int xEAMaxOpenPositions = 15; // Max Allowed Open Trades +input double xEAMinRiskAmountPerTrade = 0.001; // Min Risk Amount Per Trade +input double xEAMaxAllowedDrawDownFactor = 0.01; // Max Allowed Drawdown Factor +input double xEAMinProfitPerTrade = 0.1; // Min Acceptable Profit Per Trade +input double xEAMinProfitPerVolumeFactor = 0.01; // Min Acceptable Profit Volume Factor Per Trade +input bool xEAUseRiskAmountAsStaticVolume = true; // Use Provided Risk Amount as Static Volume + +// +// Alerts ... +input group "Alerts"; +input bool xEAEnableAlerts = true; // Enable Events Alert +input bool xEAEnableHourlyAlerts = false; // Send Alert on each new Hour +input bool xEAEnableDailyAlerts = false; // Send Alert on each new Day +input bool xEAEnableWeeklyAlerts = false; // Send Alert on each new Week +input bool xEAEnableMonthlyAlerts = false; // Send Alert on each new Month + +// +// END Inputs ... +// + +// +// START Including Providers ... +// + +// +// Logger Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Classes/x-saherelm.x121.xea.class.mq5" +#include "../Libraries/x-saherelm.seriallizer.lib.mq5" + +// +// END Including Providers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +XSCX121EA *mX121EA; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + logTag = ShortName; + drawPrefix = logTag; + alertPrefix = logTag; + + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + bool isInit = InitEAInstance(); + if (!isInit) + { + return INIT_FAILED; + } + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // De Initialize XEA Providers ... + delete mX121EA; +} + +// +// On Tick Handler ... +void OnTick() +{ + // + // Prevent Going Forward if user Disable it ... + if (xEAEnable) + { + mX121EA.OnTick(); + } +} + +// +// Handle Trade Events ... +void OnTrade() +{ + mX121EA.OnTrade(); +} + +// +// Handle Signal Event ... +void OnSignalConditionsRecieved(X121MarketConditions &info) +{ +} + +// +// Handle StopLoss Event ... +void OnStopLossTriggered(const XDeal &deal) +{ +} + +// +// Handle TakeProfit Event ... +void OnTakeProfitTriggered(const XDeal &deal) +{ +} + +// +// Handle Deals Changed Event ... +void OnDealsChangedHandler(int count) +{ +} + +// +// Handle Order Changed Event ... +void OnOrdersChangedHandler(int count) +{ +} + +// +// Handle Position Changed Event ... +void OnPositionsChangedHandler(int count) +{ +} + +// +// Handle Trade State Changed ... +void OnTradeStateChangedHandler(const XOnTradeHandlerState &state) +{ +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = true; + + // + // Validate Args ... + result = + // + xEASlippage > 0 && + xEAMagicNumber > 0 && + xEAMinRiskAmountPerTrade > 0 && + StringLen(xEADefaultSignalProviders) > 0 + // + // TODO: add new validations here ... + // + ; + + // + // Validate Providers ... + if (result) + { + // + string providers[]; + SplitContent( + providers, + xEADefaultSignalProviders); + + // + int providersCount = ArraySize(providers); + if (providersCount <= 0) + { + // + result = false; + return result; + } + + // + string allProviders[]; + GetAllProviders(allProviders); + + // + bool hasError = false; + for (int i = 0; i < providersCount; i++) + { + // + string iProvider = providers[i]; + if (!Contains(iProvider, allProviders)) + { + // + hasError = true; + break; + } + } + + // + if (hasError) + { + // + result = false; + return result; + } + } + + // + // Logging State ... + string message = "Validation of (" + logTag + ") Inputs " + (result ? "Succeeded" : "Failed") + " ..."; + LogMessage(message); + + // + return result; +} + +// +// Initialize X121EA Class Instances ... +bool InitEAInstance() +{ + // + bool result = false; + + // + X121SignalProvider providers[]; + + // + // Try to Extract Configs ... + int configsCount = ExtractProviderConfigurations( + providers, + xEAProvidersConfiguration, + xEADefaultSignalProviders, + xEAMinRiskAmountPerTrade, + xEAUseRiskAmountAsStaticVolume); + + // + mX121EA = new XSCX121EA( + _Symbol, + _Period, + xEAMagicNumber, + xEASlippage, + xEAMinProfitPerTrade, + xEAMinProfitPerVolumeFactor, + OnStopLossTriggered, + OnTakeProfitTriggered, + OnDealsChangedHandler, + OnOrdersChangedHandler, + OnPositionsChangedHandler, + OnTradeStateChangedHandler, + OnSignalConditionsRecieved); + + // + mX121EA.EnableLongs(xEAEnableLongs); + mX121EA.EnableShorts(xEAEnableShorts); + mX121EA.MaxAllowedPositions(xEAMaxOpenPositions); + mX121EA.MaxAllowedDrawDownFactor(xEAMaxAllowedDrawDownFactor); + + // + // Attach Providers to EA Instance ... + int providersCount = ArraySize(providers); + int addedProviders = mX121EA.AddProviders(providers); + result = addedProviders == providersCount; + + // + return result; +} +// +// END Functions ... +// diff --git a/MQLTestWorkspace/X121/14030217/Helpers/x-saherelm.x121.xman.helper.class.ex5 b/MQLTestWorkspace/X121/14030217/Helpers/x-saherelm.x121.xman.helper.class.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..c92bebaf62fd366e27060550f5882c278ceff4f6 GIT binary patch literal 10470 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 Mp(acv{d4v_k`Vc+ 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 1 ? mPeriod : 1); + mHalfPeriod = (int)(mFullPeriod > 1 ? mFullPeriod / (mDivisor > 1 ? mDivisor : 1) : 1); + mSqrtPeriod = (int)MathSqrt(mFullPeriod); + + // + mArraySize = -1; + mWeight1 = mWeight2 = mWeight3 = 1; + + // + result = true; + + // + return result; + } + + // + // CalCulate Specific Value ... + double Calculate( + double value, + int i, + int bars) + { + // + double result = 0; + + // + if (mArraySize < bars) + { + // + mArraySize = ArrayResize(mData, bars + 500); + if (mArraySize < bars) + return result; + } + + // + mData[i].value = value; + if (i > mFullPeriod) + { + // + mData[i].wsum1 = mData[i - 1].wsum1 + value * mHalfPeriod - mData[i - 1].lsum1; + mData[i].lsum1 = mData[i - 1].lsum1 + value - mData[i - mHalfPeriod].value; + mData[i].wsum2 = mData[i - 1].wsum2 + value * mFullPeriod - mData[i - 1].lsum2; + mData[i].lsum2 = mData[i - 1].lsum2 + value - mData[i - mFullPeriod].value; + } + else + { + // + mData[i].wsum1 = mData[i].wsum2 = + mData[i].lsum1 = mData[i].lsum2 = mWeight1 = mWeight2 = 0; + for (int k = 0, w1 = mHalfPeriod, w2 = mFullPeriod; w2 > 0 && i >= k; k++, w1--, w2--) + { + // + if (w1 > 0) + { + // + mData[i].wsum1 += mData[i - k].value * w1; + mData[i].lsum1 += mData[i - k].value; + mWeight1 += w1; + } + + // + mData[i].wsum2 += mData[i - k].value * w2; + mData[i].lsum2 += mData[i - k].value; + mWeight2 += w2; + } + } + + // + mData[i].value3 = 2.0 * mData[i].wsum1 / mWeight1 - mData[i].wsum2 / mWeight2; + + // + if (i > mSqrtPeriod) + { + // + mData[i].wsum3 = mData[i - 1].wsum3 + mData[i].value3 * mSqrtPeriod - mData[i - 1].lsum3; + mData[i].lsum3 = mData[i - 1].lsum3 + mData[i].value3 - mData[i - mSqrtPeriod].value3; + } + else + { + // + mData[i].wsum3 = + mData[i].lsum3 = mWeight3 = 0; + + // + for (int k = 0, w3 = mSqrtPeriod; w3 > 0 && i >= k; k++, w3--) + { + // + mData[i].wsum3 += mData[i - k].value3 * w3; + mData[i].lsum3 += mData[i - k].value3; + mWeight3 += w3; + } + } + + // + result = mData[i].wsum3 / mWeight3; + + // + return result; + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + int mFullPeriod; + int mHalfPeriod; + int mSqrtPeriod; + int mArraySize; + double mWeight1; + double mWeight2; + double mWeight3; + + // + XHullData mData[]; +}; + +// +#include +#include "../Libraries/x-saherelm.xman.parser.lib.mq5" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Candle Timer"; +input string cTimerConfig = "candleTimerColor(clrGold)candleTimerCorner(2)"; // Config + +// +input group "Chart Style"; +input string cStyleConfig = "upColor(clrLime) downColor(clrRed) lineColor(clrLime) bearishColor(clrRed) bullishColor(clrLime) volumesColor(clrGreen) chartMode(1)"; // Config + +// +input group "Makret Cycles"; +input group "Short"; +input string scConfig = "l1Method(1)l1Period(NULL)"; // Config +input group "Medium"; +input string mcConfig = "l2Method(1)l2Period(NULL)"; // Config +input group "Long"; +input string lcConfig = "l3Method(1)l3Period(NULL)"; // Config +input group "Hind"; +input string hcConfig = "l4Method(1)l4Period(NULL)"; // Config + +// +input group "Fibonacci"; +input string fibConfig = "fiboLevel1(0.236)fiboLevel2(0.382)fiboLevel3(0.5)fiboLevel4(0.618)fiboLevel5(0.764)"; // Config + +// +input group "Boundary Detection Modes"; +input string bdConfig = "hhMode(2)llMode(1)"; // Config + +// +input group "Trend Detection"; +input string tdConfig = "trendMultiplier(3)trendPriceAppliedTo(4)"; // Config + +// +input group "Ribbon Detection"; +input string rbConfig = "ribbonMode(5)"; // Config + +// +input group "Hull Trend Detection"; +input string hullConfig = "hullDivisor(2.0)hullUpAppliedTo(3)hullDownAppliedTo(4)"; // Config + +// +input group "SSL Channel"; +input string sslcConfig = "sslcMode(1)sslcUpAppliedTo(3)sslcDownAppliedTo(4)"; // Config + +// +input group "Presentation"; +input string stylePRSConfig = "showCandleTimer(true)showCandles(true)showHKCandles(false)showSMHKCandles(false)"; // Styles +input string pvPRSConfig = "showPeaksAndVales(true)showLevels(false)showConsolidations(false)"; // Peaks and Vales +input string trendPRSConfig = "showHull(false)showTrends(false)fillTrends(false)showRibbons(false)showSSLChannel(false)"; // Trend +input string fiboPRSConfig = "showFibo1Levels(false)showFibo2Levels(false)showFibo3Levels(false)showFibo4Levels(false)showFibo5Levels(false)"; // Fibonacci + +// +// END Inputs ... +// + +// +// START Configs ... +// + +// +// Candles Timer ... +color candleTimerColor = clrGold; // Text Color +ENUM_BASE_CORNER candleTimerCorner = CORNER_RIGHT_UPPER; // Text Position + +// +// Chart Style +color upColor = clrLime; // Up Color +color downColor = clrRed; // Down Color +color lineColor = clrLime; // Line mode and Doji candlestick Color +color bearishColor = clrRed; // Bullish Color +color bullishColor = clrLime; // Bearish Color +color volumesColor = clrGreen; // Volumes Color +ENUM_CHART_MODE chartMode = CHART_CANDLES; // Chart Mode + +// +// Makret Cycles + +// +// Level 1 ... +ENUM_X_PERIOD_METHOD l1Method = X_PERIOD_AUTO; // How to Find Period +ENUM_TIMEFRAMES l1Period = NULL; // Time Period + +// +// Level 2 ... +ENUM_X_PERIOD_METHOD l2Method = X_PERIOD_AUTO; // How to Find Period +ENUM_TIMEFRAMES l2Period = NULL; // Time Period + +// +// Level 3 ... +ENUM_X_PERIOD_METHOD l3Method = X_PERIOD_AUTO; // How to Find Period +ENUM_TIMEFRAMES l3Period = NULL; // Time Period + +// +// Level 4 ... +ENUM_X_PERIOD_METHOD l4Method = X_PERIOD_AUTO; // How to Find Period +ENUM_TIMEFRAMES l4Period = NULL; // Time Period + +// +// Fibonacci ... +double fiboLevel1 = 0.236; // Fibio 1st Level +double fiboLevel2 = 0.382; // Fibio 2st Level +double fiboLevel3 = 0.5; // Fibio 3rd Level +double fiboLevel4 = 0.618; // Fibio 4th Level +double fiboLevel5 = 0.764; // Fibio 5th Level + +// +// Boundary Detection Modes ... +ENUM_SERIESMODE hhMode = MODE_HIGH; // Highest High Calculation Method +ENUM_SERIESMODE llMode = MODE_LOW; // Lowest Low Calculation Method + +// +// Trend Detection ... +double trendMultiplier = 3; // Multiplier +ENUM_APPLIED_PRICE trendPriceAppliedTo = PRICE_MEDIAN; // Applied To + +// +// Ribbon Detection ... +ENUM_X_MA_METHOD ribbonMode = X_MA_AMA; // How to Calculate + +// +// Hull Trend Detection ... +double hullDivisor = 2.0; // Divisor (Speed) +ENUM_APPLIED_PRICE hullUpAppliedTo = PRICE_HIGH; // Up Zone Applied to +ENUM_APPLIED_PRICE hullDownAppliedTo = PRICE_LOW; // Down Zone Applied to + +// +// SSL Channel Detection ... +ENUM_X_MA_METHOD sslcMode = X_MA_SMA; // How to Calculate +ENUM_APPLIED_PRICE sslcUpAppliedTo = PRICE_HIGH; // Up Applied To +ENUM_APPLIED_PRICE sslcDownAppliedTo = PRICE_LOW; // Down Applied To + +// +// Presentation ... +bool showCandleTimer = true; // Show Candle Time +bool showCandles = true; // Show Candles +bool showHKCandles = false; // Draw Hiken Ashi Candle +bool showSMHKCandles = false; // Draw Smoothed Hiken Ashi Candle +bool showPeaksAndVales = true; // Show Peaks and Vales +bool showTrends = true; // Show Trends +bool fillTrends = false; // Fill Trends +bool showLevels = false; // Show Levels +bool showConsolidations = false; // Show Consolidations +bool showRibbons = false; // Show Ribbons +bool showHull = false; // Show Hull +bool showSSLChannel = false; // Show SSL Channel +bool showFibo1Levels = false; // Show Fibo 1st Level +bool showFibo2Levels = false; // Show Fibo 2nd Level +bool showFibo3Levels = false; // Show Fibo 3rd Level +bool showFibo4Levels = false; // Show Fibo 4th Level +bool showFibo5Levels = false; // Show Fibo 5th Level + +// +// END Configs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Draw Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 94 +#property indicator_plots 50 + +// +// PEKSANDVALES ... + +// +// PEAKS ... + +// +#define peaksBufferIndex 0 +double peaksBuffer[]; + +// +#property indicator_label1 "X121_XMAN PEAKS" +#property indicator_type1 DRAW_ARROW +#property indicator_color1 clrAqua +#property indicator_width1 1 + +// +// VALES ... + +// +#define valesBufferIndex 1 +double valesBuffer[]; + +// +#property indicator_label2 "X121_XMAN VALES" +#property indicator_type2 DRAW_ARROW +#property indicator_color2 clrMagenta +#property indicator_width2 1 + +// +#define rBufferIndex 2 +double rBuffer[]; + +// +#define rColorBufferIndex 3 +double rColorBuffer[]; + +// +#property indicator_label3 "X121_XMAN R" +#property indicator_type3 DRAW_COLOR_LINE +#property indicator_color3 CLR_NONE, clrAqua +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +#define sBufferIndex 4 +#define sBufferPlotIndex 3 +double sBuffer[]; + +// +#define sColorBufferIndex 5 +double sColorBuffer[]; + +// +#property indicator_label4 "X121_XMAN S" +#property indicator_type4 DRAW_COLOR_LINE +#property indicator_color4 CLR_NONE, clrMagenta +#property indicator_style4 STYLE_DOT +#property indicator_width4 1 + +// +// FIBBO Level 1 ... + +// +#define fl1BufferIndex 6 +#define fl1BufferPlotIndex 4 +double fl1Buffer[]; + +// +#define fl1ColorBufferIndex 7 +double fl1ColorBuffer[]; + +// +#property indicator_label5 "X121_XMAN FL1" +#property indicator_type5 DRAW_COLOR_LINE +#property indicator_color5 CLR_NONE, clrGold +#property indicator_style5 STYLE_DASHDOTDOT +#property indicator_width5 1 + +// +// FIBBO Level 2 ... + +// +#define fl2BufferIndex 8 +#define fl2BufferPlotIndex 5 +double fl2Buffer[]; + +// +#define fl2ColorBufferIndex 9 +double fl2ColorBuffer[]; + +// +#property indicator_label6 "X121_XMAN FL2" +#property indicator_type6 DRAW_COLOR_LINE +#property indicator_color6 CLR_NONE, clrGold +#property indicator_style6 STYLE_DASHDOTDOT +#property indicator_width6 1 + +// +// FIBBO Level 3 ... + +// +#define fl3BufferIndex 10 +#define fl3BufferPlotIndex 6 +double fl3Buffer[]; + +// +#define fl3ColorBufferIndex 11 +double fl3ColorBuffer[]; + +// +#property indicator_label7 "X121_XMAN FL3" +#property indicator_type7 DRAW_COLOR_LINE +#property indicator_color7 CLR_NONE, clrGold +#property indicator_style7 STYLE_DASHDOTDOT +#property indicator_width7 1 + +// +// FIBBO Level 4 ... + +// +#define fl4BufferIndex 12 +#define fl4BufferPlotIndex 7 +double fl4Buffer[]; + +// +#define fl4ColorBufferIndex 13 +double fl4ColorBuffer[]; + +// +#property indicator_label8 "X121_XMAN FL4" +#property indicator_type8 DRAW_COLOR_LINE +#property indicator_color8 CLR_NONE, clrGold +#property indicator_style8 STYLE_DASHDOTDOT +#property indicator_width8 1 + +// +// FIBBO Level 5 ... + +// +#define fl5BufferIndex 14 +#define fl5BufferPlotIndex 8 +double fl5Buffer[]; + +// +#define fl5ColorBufferIndex 15 +double fl5ColorBuffer[]; + +// +#property indicator_label9 "X121_XMAN FL5" +#property indicator_type9 DRAW_COLOR_LINE +#property indicator_color9 CLR_NONE, clrGold +#property indicator_style9 STYLE_DASHDOTDOT +#property indicator_width9 1 + +// +// LEVELS ... + +// +#define sHHBufferIndex 16 +#define sHHBufferPlotIndex 9 +double sHHBuffer[]; + +// +#define sHHColorBufferIndex 17 +double sHHColorBuffer[]; + +// +#property indicator_label10 "X121_XMAN SHH" +#property indicator_type10 DRAW_COLOR_LINE +#property indicator_color10 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style10 STYLE_DOT +#property indicator_width10 1 + +#define sLLBufferIndex 18 +#define sLLBufferPlotIndex 10 +double sLLBuffer[]; + +// +#define sLLColorBufferIndex 19 +double sLLColorBuffer[]; + +// +#property indicator_label11 "X121_XMAN SLL" +#property indicator_type11 DRAW_COLOR_LINE +#property indicator_color11 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style11 STYLE_DOT +#property indicator_width11 1 + +// +#define mHHBufferIndex 20 +#define mHHBufferPlotIndex 11 +double mHHBuffer[]; + +// +#define mHHColorBufferIndex 21 +double mHHColorBuffer[]; + +// +#property indicator_label12 "X121_XMAN MHH" +#property indicator_type12 DRAW_COLOR_LINE +#property indicator_color12 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style12 STYLE_DOT +#property indicator_width12 1 + +// +#define mLLBufferIndex 22 +#define mLLBufferPlotIndex 12 +double mLLBuffer[]; + +// +#define mLLColorBufferIndex 23 +double mLLColorBuffer[]; + +// +#property indicator_label13 "X121_XMAN MLL" +#property indicator_type13 DRAW_COLOR_LINE +#property indicator_color13 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style13 STYLE_DOT +#property indicator_width13 1 + +// +#define lHHBufferIndex 24 +#define lHHBufferPlotIndex 13 +double lHHBuffer[]; + +// +#define lHHColorBufferIndex 25 +double lHHColorBuffer[]; + +// +#property indicator_label14 "X121_XMAN LHH" +#property indicator_type14 DRAW_COLOR_LINE +#property indicator_color14 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style14 STYLE_DOT +#property indicator_width14 1 + +// +#define lLLBufferIndex 26 +#define lLLBufferPlotIndex 14 +double lLLBuffer[]; + +// +#define lLLColorBufferIndex 27 +double lLLColorBuffer[]; + +// +#property indicator_label15 "X121_XMAN LLL" +#property indicator_type15 DRAW_COLOR_LINE +#property indicator_color15 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style15 STYLE_DOT +#property indicator_width15 1 + +// +#define hHHBufferIndex 28 +#define hHHBufferPlotIndex 15 +double hHHBuffer[]; + +// +#define hHHColorBufferIndex 29 +double hHHColorBuffer[]; + +// +#property indicator_label16 "X121_XMAN HHH" +#property indicator_type16 DRAW_COLOR_LINE +#property indicator_color16 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style16 STYLE_DOT +#property indicator_width16 1 + +// +#define hLLBufferIndex 30 +#define hLLBufferPlotIndex 16 +double hLLBuffer[]; + +// +#define hLLColorBufferIndex 31 +double hLLColorBuffer[]; + +// +#property indicator_label17 "X121_XMAN HLL" +#property indicator_type17 DRAW_COLOR_LINE +#property indicator_color17 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style17 STYLE_DOT +#property indicator_width17 1 + +// +// XSTR Buffers ... + +// +#define fillUpBufferIndex 32 +double fillUpBuffer[]; + +#define fillDownBufferIndex 33 +double fillDownBuffer[]; + +// +#define fillingBufferPlotIndex 17 + +// +#property indicator_label18 "X121_XMAN TRND Filling" +#property indicator_type18 DRAW_FILLING +#property indicator_color18 clrBisque, clrPaleGreen + +// +#define trendBufferIndex 34 +#define trendBufferPlotIndex 18 +double trendBuffer[]; + +// +#define trendColorBufferIndex 35 +double trendColorBuffer[]; + +// +#property indicator_label19 "X121_XMAN TRND" +#property indicator_type19 DRAW_COLOR_LINE +#property indicator_color19 CLR_NONE, clrGreen, clrDarkRed +#property indicator_style19 STYLE_DOT +#property indicator_width19 1 + +// +// XMRB ... + +// +// RIBBON 1 ... +// High ... + +// +#define ribbon1BufferIndex 36 +#define ribbon1BufferPlotIndex 19 +double ribbon1Buffer[]; + +// +#define ribbon1ColorBufferIndex 37 +double ribbon1ColorBuffer[]; + +// +#property indicator_label20 "X121_XMAN RB 1" +#property indicator_type20 DRAW_COLOR_LINE +#property indicator_color20 CLR_NONE, clrGray, clrGreen, clrDarkRed +#property indicator_style20 STYLE_DASH +#property indicator_width20 1 + +// +// RIBBON 2 ... +// Open ... + +// +#define ribbon2BufferIndex 38 +#define ribbon2BufferPlotIndex 20 +double ribbon2Buffer[]; + +// +#define ribbon2ColorBufferIndex 39 +double ribbon2ColorBuffer[]; + +// +#property indicator_label21 "X121_XMAN RB 2" +#property indicator_type21 DRAW_COLOR_LINE +#property indicator_color21 CLR_NONE, clrGray, clrGreen, clrDarkRed +#property indicator_style21 STYLE_DASH +#property indicator_width21 1 + +// +// RIBBON 3 ... +// Close ... + +// +#define ribbon3BufferIndex 40 +#define ribbon3BufferPlotIndex 21 +double ribbon3Buffer[]; + +// +#define ribbon3ColorBufferIndex 41 +double ribbon3ColorBuffer[]; + +// +#property indicator_label22 "X121_XMAN RB 3" +#property indicator_type22 DRAW_COLOR_LINE +#property indicator_color22 CLR_NONE, clrGray, clrGreen, clrDarkRed +#property indicator_style22 STYLE_DASH +#property indicator_width22 1 + +// +// RIBBON 4 ... +// Median ... + +// +#define ribbon4BufferIndex 42 +#define ribbon4BufferPlotIndex 22 +double ribbon4Buffer[]; + +// +#define ribbon4ColorBufferIndex 43 +double ribbon4ColorBuffer[]; + +// +#property indicator_label23 "X121_XMAN RB 4" +#property indicator_type23 DRAW_COLOR_LINE +#property indicator_color23 CLR_NONE, clrGray, clrGreen, clrDarkRed +#property indicator_style23 STYLE_DASH +#property indicator_width23 1 + +// +// RIBBON 5 ... +// Typical ... + +// +#define ribbon5BufferIndex 44 +#define ribbon5BufferPlotIndex 23 +double ribbon5Buffer[]; + +// +#define ribbon5ColorBufferIndex 45 +double ribbon5ColorBuffer[]; + +// +#property indicator_label24 "X121_XMAN RB 5" +#property indicator_type24 DRAW_COLOR_LINE +#property indicator_color24 CLR_NONE, clrGray, clrGreen, clrDarkRed +#property indicator_style24 STYLE_DASH +#property indicator_width24 1 + +// +// RIBBON 6 ... +// Low ... + +// +#define ribbon6BufferIndex 46 +#define ribbon6BufferPlotIndex 24 +double ribbon6Buffer[]; + +// +#define ribbon6ColorBufferIndex 47 +double ribbon6ColorBuffer[]; + +// +#property indicator_label25 "X121_XMAN RB 6" +#property indicator_type25 DRAW_COLOR_LINE +#property indicator_color25 CLR_NONE, clrGray, clrGreen, clrDarkRed +#property indicator_style25 STYLE_DASH +#property indicator_width25 1 + +// +// XSSLC ... + +// +#define sslcUpBufferIndex 48 +#define sslcUpBufferPlotIndex 25 +double sslcUpBuffer[]; + +// +#define sslcUpColorBufferIndex 49 +double sslcUpColorBuffer[]; + +// +#property indicator_label26 "X121_XMAN SSLC Up" +#property indicator_type26 DRAW_COLOR_LINE +#property indicator_color26 CLR_NONE, clrLime +#property indicator_style26 STYLE_SOLID +#property indicator_width26 1 + +// +#define sslcDownBufferIndex 50 +#define sslcDownBufferPlotIndex 26 +double sslcDownBuffer[]; + +// +#define sslcDownColorBufferIndex 51 +double sslcDownColorBuffer[]; + +// +#property indicator_label27 "X121_XMAN SSLC Down" +#property indicator_type27 DRAW_COLOR_LINE +#property indicator_color27 CLR_NONE, clrRed +#property indicator_style27 STYLE_SOLID +#property indicator_width27 1 + +// +// XHULL ... + +// +// UP Zone ... + +// +#define hullUpZoneBufferIndex 52 +#define hullUpZoneBufferPlotIndex 27 +#define hullUpZoneColorBufferIndex 53 + +// +double hullUpZoneBuffer[]; +double hullUpZoneColorBuffer[]; + +// +#property indicator_label28 "X121_XMAN HULL Up" +#property indicator_type28 DRAW_COLOR_LINE +#property indicator_color28 CLR_NONE, clrGray, clrAqua, clrMagenta +#property indicator_width28 1 + +// +// DOWN Zone ... + +// +#define hullDownZoneBufferIndex 54 +#define hullDownZoneBufferPlotIndex 28 +#define hullDownZoneColorBufferIndex 55 + +// +double hullDownZoneBuffer[]; +double hullDownZoneColorBuffer[]; + +// +#property indicator_label29 "X121_XMAN HULL Down" +#property indicator_type29 DRAW_COLOR_LINE +#property indicator_color29 CLR_NONE, clrGray, clrAqua, clrMagenta +#property indicator_width29 1 + +// +// Open ... +#define hkOpenBufferIndex 56 +double hkOpenBuffer[]; + +// +// High ... +#define hkHighBufferIndex 57 +double hkHighBuffer[]; + +// +// Low ... +#define hkLowBufferIndex 58 +double hkLowBuffer[]; + +// +// Close ... +#define hkCloseBufferIndex 59 +double hkCloseBuffer[]; + +// +// Candle Color ... +#define hkCandleColorBufferIndex 60 +double hkCandleColorBuffer[]; + +// +#define hkCandlesBufferIndex 29 + +// +#property indicator_label30 "X121_XMAN HK Open;X121_XMAN HK High;X121_XMAN HK Low;X121_XMAN HK Close" +#property indicator_type30 DRAW_COLOR_CANDLES +#property indicator_color30 CLR_NONE, clrAqua, clrMagenta + +// +// Open ... +#define smhkOpenBufferIndex 61 +double smhkOpenBuffer[]; + +// +// High ... +#define smhkHighBufferIndex 62 +double smhkHighBuffer[]; + +// +// Low ... +#define smhkLowBufferIndex 63 +double smhkLowBuffer[]; + +// +// Close ... +#define smhkCloseBufferIndex 64 +double smhkCloseBuffer[]; + +// +// Candle Color ... +#define smhkCandleColorBufferIndex 65 +double smhkCandleColorBuffer[]; + +// +#define smhkCandlesBufferIndex 30 + +// +#property indicator_label31 "X121_XMAN SMHK Open;X121_XMAN SMHK High;X121_XMAN SMHK Low;X121_XMAN SMHK Close" +#property indicator_type31 DRAW_COLOR_CANDLES +#property indicator_color31 CLR_NONE, clrOliveDrab, clrSaddleBrown + +// +// DATA Buffers ... + +#define lastBufferIndex 65 + +// +// 66 +#define atrBufferIndex lastBufferIndex + 1 +double atrBuffer[]; + +// +// 67 +#define trendStateBufferIndex lastBufferIndex + 2 +double trendStateBuffer[]; + +// +// 68 +#define upBufferIndex lastBufferIndex + 3 +double upBuffer[]; + +// +// 69 +#define downBufferIndex lastBufferIndex + 4 +double downBuffer[]; + +// +// 70 +#define priceBufferIndex lastBufferIndex + 5 +double priceBuffer[]; + +// +// 71 +#define sslcUpMaBufferIndex lastBufferIndex + 6 +double sslcUpMaBuffer[]; + +// +// 72 +#define sslcDownMaBufferIndex lastBufferIndex + 7 +double sslcDownMaBuffer[]; + +// +// 73 +#define sslcKpiBufferIndex lastBufferIndex + 8 +double sslcKpiBuffer[]; + +// +// STATE Buffers ... + +// +// 74 +// When new Peaks Happens it's Valued otherwise EMPTY_VALUE ... +#define peaksStateBufferIndex lastBufferIndex + 9 +double peaksStateBuffer[]; + +// +// 75 +// When new Vales Happens it's Valued otherwise EMPTY_VALUE ... +#define valesStateBufferIndex lastBufferIndex + 10 +double valesStateBuffer[]; + +// +// SHORT Cycle ... + +// +// 76 +#define sHHStateBufferIndex lastBufferIndex + 11 +double sHHStateBuffer[]; + +// +// 77 +#define sLLStateBufferIndex lastBufferIndex + 12 +double sLLStateBuffer[]; + +// +// MEDIUM Cycle ... + +// +// 78 +#define mHHStateBufferIndex lastBufferIndex + 13 +double mHHStateBuffer[]; + +// +// 79 +#define mLLStateBufferIndex lastBufferIndex + 14 +double mLLStateBuffer[]; + +// +// LONG Cycle ... + +// +// 80 +#define lHHStateBufferIndex lastBufferIndex + 15 +double lHHStateBuffer[]; + +// +// 81 +#define lLLStateBufferIndex lastBufferIndex + 16 +double lLLStateBuffer[]; + +// +// HIND Cycle ... + +// +// 82 +#define hHHStateBufferIndex lastBufferIndex + 17 +double hHHStateBuffer[]; + +// +// 83 +#define hLLStateBufferIndex lastBufferIndex + 18 +double hLLStateBuffer[]; + +// +// XSTR ... +// 84 +#define strTrendStateBufferIndex lastBufferIndex + 19 +double strTrendStateBuffer[]; + +// +// XMRB ... + +// +// RIBBON 1 (High) ... +// 85 +#define rb1StateBufferIndex lastBufferIndex + 20 +double rb1StateBuffer[]; + +// +// RIBBON 2 (Open) ... +// 86 +#define rb2StateBufferIndex lastBufferIndex + 21 +double rb2StateBuffer[]; + +// +// RIBBON 3 (Close) ... +// 87 +#define rb3StateBufferIndex lastBufferIndex + 22 +double rb3StateBuffer[]; + +// +// RIBBON 4 (Median) ... +// 88 +#define rb4StateBufferIndex lastBufferIndex + 23 +double rb4StateBuffer[]; + +// +// RIBBON 5 (Typical) ... +// 89 +#define rb5StateBufferIndex lastBufferIndex + 24 +double rb5StateBuffer[]; + +// +// RIBBON 6 (Low) ... +// 90 +#define rb6StateBufferIndex lastBufferIndex + 25 +double rb6StateBuffer[]; + +// +// XHULL ... + +// +// 91 +#define hullUpStateBufferIndex lastBufferIndex + 26 +double hullUpStateBuffer[]; + +// +// 92 +#define hullDownStateBufferIndex lastBufferIndex + 27 +double hullDownStateBuffer[]; + +// +// XHK ... +// 93 +#define hkStateBufferIndex lastBufferIndex + 28 +double hkStateBuffer[]; + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +double lastPeak; +double lastVale; + +// +double mLastSHH = 0; +double mLastSLL = 0; + +// +double mLastMHH = 0; +double mLastMLL = 0; + +// +double mLastLHH = 0; +double mLastLLL = 0; + +// +double mLastHHH = 0; +double mLastHLL = 0; + +// +double mHideColorIDX = 0; + +// +int currentPeriodSecconds = 0; + +// +// CYCLE 1 ... +int mL1Candles; +int mL1PeriodSecconds = 0; +int mLastL1StartBarIndex = 0; +datetime mLastL1StartTime = NULL; +ENUM_TIMEFRAMES mL1Period = NULL; + +// +// CYCLE 2 ... +int mL2Candles; +int mL2PeriodSecconds = 0; +int mLastL2StartBarIndex = 0; +datetime mLastL2StartTime = NULL; +ENUM_TIMEFRAMES mL2Period = NULL; + +// +// CYCLE 3 ... +int mL3Candles; +int mL3PeriodSecconds = 0; +int mLastL3StartBarIndex = 0; +datetime mLastL3StartTime = NULL; +ENUM_TIMEFRAMES mL3Period = NULL; + +// +// CYCLE 4 ... +int mL4Candles; +int mL4PeriodSecconds = 0; +int mLastL4StartBarIndex = 0; +datetime mLastL4StartTime = NULL; +ENUM_TIMEFRAMES mL4Period = NULL; + +// +// XSTR ... + +// +int atrHandler = INVALID_HANDLE; + +// +int changeOfTrend; +int startBearishTrend; +int startBullishTrend; + +// +int mStrLength; + +// +// XMRB ... + +int mMRBLength; +int mMRBAMAFast = 2; +int mMRBAMASlow = 30; + +// +int rb1Handler = INVALID_HANDLE; +int rb2Handler = INVALID_HANDLE; +int rb3Handler = INVALID_HANDLE; +int rb4Handler = INVALID_HANDLE; +int rb5Handler = INVALID_HANDLE; +int rb6Handler = INVALID_HANDLE; + +// +// XSSLC ... + +// +int mSSLCLength; + +// +int sslcUpHandler = INVALID_HANDLE; +int sslcDownHandler = INVALID_HANDLE; + +// +// XHULL ... + +// +int mHULLLength; + +// +XSCHull *mUpZHull; +XSCHull *mDownZHull; + +// +double mLastHullUpValue; +double mLastHullUpColorValue = 1; +double mLastHullDownValue; +double mLastHullDownColorValue = 1; + +// +// XCC ... + +// +XChartStyle chartStyle; +XChartStyle clearStyle; + +// +int mHKSmoothingLength; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Parse Configs ... + if (!ParseConfigs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + InitCandleTimer(); + + // + // Initial Periods ... + InitialCycles(); + + // + drawPrefix = ShortName; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // We Can Choose ATR Length based on Other Cycles ... + mStrLength = mL4Candles; + atrHandler = iATR( + _Symbol, + _Period, + mStrLength); + if (atrHandler == INVALID_HANDLE) + { + return INIT_FAILED; + } + + // + mMRBLength = mL4Candles; + if (!InitRibbons()) + { + return INIT_FAILED; + } + + // + mSSLCLength = mL4Candles; + if (!InitSSLChannel()) + { + return INIT_FAILED; + } + + // + mHULLLength = mL4Candles; + if (!InitHullTrend()) + { + return INIT_FAILED; + } + + // + mHKSmoothingLength = mL4Candles; + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Apply Chart Style ... + ApplyCustomChartStyle(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + IndicatorRelease(atrHandler); + + // + // XMRB ... + IndicatorRelease(rb1Handler); + IndicatorRelease(rb2Handler); + IndicatorRelease(rb3Handler); + IndicatorRelease(rb4Handler); + IndicatorRelease(rb5Handler); + IndicatorRelease(rb6Handler); + + // + // XSSLC ... + IndicatorRelease(sslcUpHandler); + IndicatorRelease(sslcDownHandler); + + // + // XHULL ... + delete mUpZHull; + delete mDownZHull; + + // + ObjectDelete(0, ShortName); + + // + Comment(""); +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Calculate Candle Remain Time ... + CalculateCandleTimer(); + + // + // this counts Available Bars ... + int limit; + + // + limit = prev_calculated - 1; + if (limit < 0) + { + limit = 0; + } + + // + // Main Loop ... + for (int i = limit; i < rates_total && !IsStopped(); i++) + { + // + double upPrice = GetAppliedPrice( + hullUpAppliedTo, + open, high, low, close, i); + + // + double downPrice = GetAppliedPrice( + hullDownAppliedTo, + open, high, low, close, i); + + // + CalculateHull(i, rates_total, upPrice, downPrice); + } + + // + bool isXSTRCalculated = CalculateXSTR( + rates_total, + prev_calculated, + open, + high, + low, + close); + if (!isXSTRCalculated) + { + return prev_calculated; + } + + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + + // + // Checking Handlers Calculated Bars ... + + // + // XMRB ... + int rb1CalculatedBars = BarsCalculated(rb1Handler); + int rb2CalculatedBars = BarsCalculated(rb2Handler); + int rb3CalculatedBars = BarsCalculated(rb3Handler); + int rb4CalculatedBars = BarsCalculated(rb4Handler); + int rb5CalculatedBars = BarsCalculated(rb5Handler); + int rb6CalculatedBars = BarsCalculated(rb6Handler); + + // + // XSSLC ... + int sslcUpCalculatedBars = BarsCalculated(sslcUpHandler); + int sslcDownCalculatedBars = BarsCalculated(sslcDownHandler); + + // + bool isCalculatedBarsNotPassed = + // + // XMRB ... + rb1CalculatedBars < maxLength || + rb2CalculatedBars < maxLength || + rb3CalculatedBars < maxLength || + rb4CalculatedBars < maxLength || + rb5CalculatedBars < maxLength || + rb6CalculatedBars < maxLength || + // + // XSSLC ... + sslcUpCalculatedBars < maxLength || + sslcDownCalculatedBars < maxLength + // + ; + + // + if (isCalculatedBarsNotPassed) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Check Handlers Copied Bars ... + + // + // XMRB ... + int rb1CopiedBars = CopyBuffer(rb1Handler, 0, 0, limit, ribbon1Buffer); + int rb2CopiedBars = CopyBuffer(rb2Handler, 0, 0, limit, ribbon2Buffer); + int rb3CopiedBars = CopyBuffer(rb3Handler, 0, 0, limit, ribbon3Buffer); + int rb4CopiedBars = CopyBuffer(rb4Handler, 0, 0, limit, ribbon4Buffer); + int rb5CopiedBars = CopyBuffer(rb5Handler, 0, 0, limit, ribbon5Buffer); + int rb6CopiedBars = CopyBuffer(rb6Handler, 0, 0, limit, ribbon6Buffer); + + // + // XSSLC ... + int sslcUpCopiedBars = CopyBuffer(sslcUpHandler, 0, 0, limit, sslcUpMaBuffer); + int sslcDownCopiedBars = CopyBuffer(sslcDownHandler, 0, 0, limit, sslcDownMaBuffer); + + // + bool isCopiedBarsNotPassed = + // + // XMRB ... + rb1CopiedBars < 0 || + rb2CopiedBars < 0 || + rb3CopiedBars < 0 || + rb4CopiedBars < 0 || + rb5CopiedBars < 0 || + rb6CopiedBars < 0 || + // + // XSSLC ... + sslcUpCopiedBars < 0 || + sslcDownCopiedBars < 0 + // + ; + + // + if (isCopiedBarsNotPassed) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + // + CalculateBuffers(i); + + // + CalculateRibbonsColors(i, low, high); + + // + CalculateHikenAshi(i, prev_calculated, rates_total, open, high, close, low); + + // + CalculateSSLC(i, limit, rates_total, prev_calculated, close); + } + + // + CalculateSMHK(rates_total, prev_calculated); + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Parse Configs ... +bool ParseConfigs() +{ + // + bool result = false; + + // + // Since we Use Default Values ... + // Apply Changes Only When it's Provided ... + + // + bool hasCTConfig = StringLen(cTimerConfig) > 0; + if (hasCTConfig) + { + // + XCTimerConfig cfg = ParseCTimerConfig(cTimerConfig); + + // + candleTimerColor = cfg.candleTimerColor; + candleTimerCorner = cfg.candleTimerCorner; + } + + // + bool hasChartConfig = StringLen(cStyleConfig) > 0; + if (hasChartConfig) + { + // + XChartStyleConfig cfg = ParseChartStyleConfig(cStyleConfig); + + // + upColor = cfg.upColor; + downColor = cfg.downColor; + lineColor = cfg.lineColor; + bearishColor = cfg.bearishColor; + bullishColor = cfg.bullishColor; + volumesColor = cfg.volumesColor; + chartMode = cfg.chartMode; + } + + // + bool hasSCConfig = StringLen(scConfig) > 0; + if (hasSCConfig) + { + // + XSCConfig cfg = PrseSCConfig(scConfig); + + // + l1Method = cfg.l1Method; + l1Period = cfg.l1Period; + } + + // + bool hasMCConfig = StringLen(mcConfig) > 0; + if (hasMCConfig) + { + // + XMCConfig cfg = PrseMCConfig(mcConfig); + + // + l2Method = cfg.l2Method; + l2Period = cfg.l2Period; + } + + // + bool hasLCConfig = StringLen(lcConfig) > 0; + if (hasLCConfig) + { + // + XLCConfig cfg = PrseLCConfig(lcConfig); + + // + l3Method = cfg.l3Method; + l3Period = cfg.l3Period; + } + + // + bool hasHCConfig = StringLen(hcConfig) > 0; + if (hasHCConfig) + { + // + XHCConfig cfg = PrseHCConfig(hcConfig); + + // + l4Method = cfg.l4Method; + l4Period = cfg.l4Period; + } + + // + bool hasFibConfig = StringLen(fibConfig) > 0; + if (hasFibConfig) + { + // + XFiboConfig cfg = PrseFiboConfig(fibConfig); + + // + fiboLevel1 = cfg.fiboLevel1; + fiboLevel2 = cfg.fiboLevel2; + fiboLevel3 = cfg.fiboLevel3; + fiboLevel4 = cfg.fiboLevel4; + fiboLevel5 = cfg.fiboLevel5; + } + + // + bool hasBDConfig = StringLen(bdConfig) > 0; + if (hasBDConfig) + { + // + XBDConfig cfg = ParseBDConfig(bdConfig); + + // + hhMode = cfg.hhMode; + llMode = cfg.llMode; + } + + // + bool hasTDConfig = StringLen(tdConfig) > 0; + if (hasTDConfig) + { + // + XTDConfig cfg = ParseTDConfig(tdConfig); + + // + trendMultiplier = cfg.trendMultiplier; + trendPriceAppliedTo = cfg.trendPriceAppliedTo; + } + + // + bool hasRBConfig = StringLen(rbConfig) > 0; + if (hasRBConfig) + { + // + XRBConfig cfg = ParseRBConfig(rbConfig); + + // + ribbonMode = cfg.ribbonMode; + } + + // + bool hasHullConfig = StringLen(hullConfig) > 0; + if (hasHullConfig) + { + // + XHullConfig cfg = ParseHullConfig(hullConfig); + + // + hullDivisor = cfg.hullDivisor; + hullUpAppliedTo = cfg.hullUpAppliedTo; + hullDownAppliedTo = cfg.hullDownAppliedTo; + } + + // + bool hasSSLCConfig = StringLen(sslcConfig) > 0; + if (hasSSLCConfig) + { + // + XSSLCConfig cfg = ParseSSLCConfig(sslcConfig); + + // + sslcMode = cfg.sslcMode; + sslcUpAppliedTo = cfg.sslcUpAppliedTo; + sslcDownAppliedTo = cfg.sslcDownAppliedTo; + } + + // + bool hasStylePresentationConfig = StringLen(stylePRSConfig) > 0; + if (hasStylePresentationConfig) + { + // + XStylePresentationConfig cfg = ParseStylePresentationConfig(stylePRSConfig); + + // + showCandleTimer = cfg.showCandleTimer; + showCandles = cfg.showCandles; + showHKCandles = cfg.showHKCandles; + showSMHKCandles = cfg.showSMHKCandles; + } + + // + bool hasPVPresentationConfig = StringLen(pvPRSConfig) > 0; + if (hasPVPresentationConfig) + { + // + XPVPresentationConfig cfg = ParsePVPresentationConfig(pvPRSConfig); + + // + showPeaksAndVales = cfg.showPeaksAndVales; + showLevels = cfg.showLevels; + showConsolidations = cfg.showConsolidations; + } + + // + bool hasSTrendPresentationConfig = StringLen(trendPRSConfig) > 0; + if (hasSTrendPresentationConfig) + { + // + XTrendPresentationConfig cfg = ParseTrendPresentationConfig(trendPRSConfig); + + // + showHull = cfg.showHull; + showTrends = cfg.showTrends; + fillTrends = cfg.fillTrends; + showRibbons = cfg.showRibbons; + showSSLChannel = cfg.showSSLChannel; + } + + // + bool hasFiboPresentationConfig = StringLen(fiboPRSConfig) > 0; + if (hasFiboPresentationConfig) + { + // + XFiboPresentationConfig cfg = ParePresentationConfig(fiboPRSConfig); + + // + showFibo1Levels = cfg.showFibo1Levels; + showFibo2Levels = cfg.showFibo2Levels; + showFibo3Levels = cfg.showFibo3Levels; + showFibo4Levels = cfg.showFibo4Levels; + showFibo5Levels = cfg.showFibo5Levels; + } + + // + result = true; + + // + return result; +} + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = true; + + // + // Validate User Inputs ... + result = + // + // L1 ... + // Short Cycle ... + ( + // + l1Method == X_PERIOD_AUTO + ? l1Period == NULL + : l1Period != NULL && l1Method != X_PERIOD_NOTHING + // + ) + // + && + // + // L2 ... + // Medium Cycle ... + ( + // + l2Method == X_PERIOD_AUTO + ? l2Period == NULL + : l2Period != NULL && l2Method != X_PERIOD_NOTHING + // + ) + // + && + // + // L3 ... + // Long Cycle ... + ( + // + l3Method == X_PERIOD_AUTO + ? l3Period == NULL + : l3Period != NULL && l3Method != X_PERIOD_NOTHING + // + ) + // + && + // + // L4 ... + // Hind Cycle ... + ( + // + l4Method == X_PERIOD_AUTO + ? l4Period == NULL + : l4Period != NULL && l4Method != X_PERIOD_NOTHING + // + ) + // + && + // + // Validate Ribbon ... + ( + // + ribbonMode != X_MA_NOTHING + // + ) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 1; + + // + result = MathMax(result, mL1Candles); + result = MathMax(result, mL2Candles); + result = MathMax(result, mL3Candles); + result = MathMax(result, mL4Candles); + + // + return result; +} + +// +// Init Candle Timer ... +void InitCandleTimer() +{ + // + // Validate Inputs ... + if (showCandleTimer) + { + CreateIndicatorObject(); + } + else + { + ObjectDelete(0, ShortName); + } +} + +// +// Initial Multi Time Frame Cycles Periods ... +void InitialCycles() +{ + // + // Calculate Current Period Secconds ... + currentPeriodSecconds = PeriodSeconds(_Period); + + // + // Nearest ... + // Calculate Cycle 1 Requirements ... + if (mL1Period == NULL) + { + // + if (l1Method == X_PERIOD_AUTO) + { + mL1Period = GetNearestTimeFrame(_Period); + } + else + { + mL1Period = l1Period; + } + + // + mL1PeriodSecconds = PeriodSeconds(mL1Period); + + // + mL1Candles = mL1PeriodSecconds / currentPeriodSecconds; + } + + // + // Mediest ... + // Calculate Cycle 2 Requirements ... + if (mL2Period == NULL) + { + // + if (l2Method == X_PERIOD_AUTO) + { + mL2Period = GetMediestTimeFrame(_Period); + } + else + { + mL2Period = l2Period; + } + + // + mL2PeriodSecconds = PeriodSeconds(mL2Period); + + // + mL2Candles = mL2PeriodSecconds / currentPeriodSecconds; + } + + // + // Farest ... + // Calculate Cycle 3 Requirements ... + if (mL3Period == NULL) + { + // + if (l3Method == X_PERIOD_AUTO) + { + mL3Period = GetFarestTimeFrame(_Period); + } + else + { + mL3Period = l3Period; + } + + // + mL3PeriodSecconds = PeriodSeconds(mL3Period); + + // + mL3Candles = mL3PeriodSecconds / currentPeriodSecconds; + } + + // + // HindMost ... + // Calculate Cycle 4 Requirements ... + if (mL4Period == NULL) + { + // + if (l4Method == X_PERIOD_AUTO) + { + mL4Period = GetHindmostTimeFrame(_Period); + } + else + { + mL4Period = l4Period; + } + + // + mL4PeriodSecconds = PeriodSeconds(mL4Period); + + // + mL4Candles = mL4PeriodSecconds / currentPeriodSecconds; + } + + // + string comment = GenerateCyclesRepresentation(); + Comment(comment); +} + +// +bool InitRibbons() +{ + // + bool result = false; + + // + if (mMRBLength <= 0) + { + return result; + } + + // + // RIBBON 1 ... + // High ... + result = InitMaHandler( + rb1Handler, + mMRBLength, + ribbonMode, + PRICE_HIGH); + if (!result) + { + return result; + } + + // + // RIBBON 2 ... + // Open ... + result = InitMaHandler( + rb2Handler, + mMRBLength, + ribbonMode, + PRICE_OPEN); + if (!result) + { + return result; + } + + // + // RIBBON 3 ... + // Close ... + result = InitMaHandler( + rb3Handler, + mMRBLength, + ribbonMode, + PRICE_CLOSE); + if (!result) + { + return result; + } + + // + // RIBBON 4 ... + // Median ... + result = InitMaHandler( + rb4Handler, + mMRBLength, + ribbonMode, + PRICE_MEDIAN); + if (!result) + { + return result; + } + + // + // RIBBON 5 ... + // Typical ... + result = InitMaHandler( + rb5Handler, + mMRBLength, + ribbonMode, + PRICE_TYPICAL); + if (!result) + { + return result; + } + + // + // RIBBON 6 ... + // Low ... + result = InitMaHandler( + rb6Handler, + mMRBLength, + ribbonMode, + PRICE_LOW); + + // + return result; +} + +// +bool InitSSLChannel() +{ + // + bool result = false; + + // + if (mSSLCLength <= 0) + { + return result; + } + + // + // SSLUP ... + result = InitMaHandler( + sslcUpHandler, + mSSLCLength, + sslcMode, + sslcUpAppliedTo); + if (!result) + { + return result; + } + + // + // SSLDOWN ... + result = InitMaHandler( + sslcDownHandler, + mSSLCLength, + sslcMode, + sslcDownAppliedTo); + + // + return result; +} + +// +bool InitHullTrend() +{ + // + bool result = false; + + // + if (mHULLLength <= 0) + { + return result; + } + + // + mUpZHull = new XSCHull(); + mUpZHull.Init( + mHULLLength, + hullDivisor); + + // + mDownZHull = new XSCHull(); + mDownZHull.Init( + mHULLLength, + hullDivisor); + + // + result = true; + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // RANGE ... + + // + // PEAKS and VALES ... + ENUM_DRAW_TYPE pvDrawType = showPeaksAndVales ? DRAW_ARROW : DRAW_NONE; + + // + // PEAKS ... + ArraySetAsSeries(peaksBuffer, true); + SetIndexBuffer(peaksBufferIndex, peaksBuffer, INDICATOR_DATA); + PlotIndexSetInteger(peaksBufferIndex, PLOT_ARROW, 225); + PlotIndexSetDouble(peaksBufferIndex, PLOT_EMPTY_VALUE, 0); + + // + PlotIndexSetInteger(peaksBufferIndex, PLOT_SHOW_DATA, showPeaksAndVales); + PlotIndexSetInteger(peaksBufferIndex, PLOT_DRAW_TYPE, pvDrawType); + + // + // VALES ... + ArraySetAsSeries(valesBuffer, true); + SetIndexBuffer(valesBufferIndex, valesBuffer, INDICATOR_DATA); + PlotIndexSetInteger(valesBufferIndex, PLOT_ARROW, 225); + PlotIndexSetDouble(valesBufferIndex, PLOT_EMPTY_VALUE, 0); + + // + PlotIndexSetInteger(valesBufferIndex, PLOT_SHOW_DATA, showPeaksAndVales); + PlotIndexSetInteger(valesBufferIndex, PLOT_DRAW_TYPE, pvDrawType); + + // + // SUPPORT and RESISTANCE ... + // + + // + // RESISTANCE ... + ArraySetAsSeries(rBuffer, true); + SetIndexBuffer(rBufferIndex, rBuffer, INDICATOR_DATA); + PlotIndexSetInteger(rBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(rBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // RESISTANCE Color ... + ArraySetAsSeries(rColorBuffer, true); + SetIndexBuffer(rColorBufferIndex, rColorBuffer, INDICATOR_COLOR_INDEX); + + // + // SUPPORT ... + ArraySetAsSeries(sBuffer, true); + SetIndexBuffer(sBufferIndex, sBuffer, INDICATOR_DATA); + PlotIndexSetInteger(sBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(sBufferPlotIndex, PLOT_SHOW_DATA, false); + + // + // SUPPORT Color ... + ArraySetAsSeries(sColorBuffer, true); + SetIndexBuffer(sColorBufferIndex, sColorBuffer, INDICATOR_COLOR_INDEX); + + // + // FIBBO Levels ... + + // + // LEVEL 1 ... + + // + // Buffer ... + ArraySetAsSeries(fl1Buffer, true); + SetIndexBuffer(fl1BufferIndex, fl1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl1BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl1BufferPlotIndex, PLOT_SHOW_DATA, showFibo1Levels); + + // + // Color ... + ArraySetAsSeries(fl1ColorBuffer, true); + SetIndexBuffer(fl1ColorBufferIndex, fl1ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LEVEL 2 ... + + // + // Buffer ... + ArraySetAsSeries(fl2Buffer, true); + SetIndexBuffer(fl2BufferIndex, fl2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl2BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl2BufferPlotIndex, PLOT_SHOW_DATA, showFibo2Levels); + + // + // Color ... + ArraySetAsSeries(fl2ColorBuffer, true); + SetIndexBuffer(fl2ColorBufferIndex, fl2ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LEVEL 3 ... + + // + // Buffer ... + ArraySetAsSeries(fl3Buffer, true); + SetIndexBuffer(fl3BufferIndex, fl3Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl3BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl3BufferPlotIndex, PLOT_SHOW_DATA, showFibo3Levels); + + // + // Color ... + ArraySetAsSeries(fl3ColorBuffer, true); + SetIndexBuffer(fl3ColorBufferIndex, fl3ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LEVEL 4 ... + + // + // Buffer ... + ArraySetAsSeries(fl4Buffer, true); + SetIndexBuffer(fl4BufferIndex, fl4Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl4BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl4BufferPlotIndex, PLOT_SHOW_DATA, showFibo4Levels); + + // + // Color ... + ArraySetAsSeries(fl4ColorBuffer, true); + SetIndexBuffer(fl4ColorBufferIndex, fl4ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LEVEL 5 ... + + // + // Buffer ... + ArraySetAsSeries(fl5Buffer, true); + SetIndexBuffer(fl5BufferIndex, fl5Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl5BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl5BufferPlotIndex, PLOT_SHOW_DATA, showFibo5Levels); + + // + // Color ... + ArraySetAsSeries(fl5ColorBuffer, true); + SetIndexBuffer(fl5ColorBufferIndex, fl5ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // SHORT Buffers ... + + // + // HIGH ... + ArraySetAsSeries(sHHBuffer, true); + SetIndexBuffer(sHHBufferIndex, sHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(sHHBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(sHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(sHHColorBuffer, true); + SetIndexBuffer(sHHColorBufferIndex, sHHColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LOW ... + ArraySetAsSeries(sLLBuffer, true); + SetIndexBuffer(sLLBufferIndex, sLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(sLLBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(sLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(sLLColorBuffer, true); + SetIndexBuffer(sLLColorBufferIndex, sLLColorBuffer, INDICATOR_COLOR_INDEX); + + // + // MEDIUM Buffer ... + + // + // HIGH ... + ArraySetAsSeries(mHHBuffer, true); + SetIndexBuffer(mHHBufferIndex, mHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(mHHBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(mHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(mHHColorBuffer, true); + SetIndexBuffer(mHHColorBufferIndex, mHHColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LOW ... + ArraySetAsSeries(mLLBuffer, true); + SetIndexBuffer(mLLBufferIndex, mLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(mLLBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(mLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(mLLColorBuffer, true); + SetIndexBuffer(mLLColorBufferIndex, mLLColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LONG Buffer ... + + // + // HIGH ... + ArraySetAsSeries(lHHBuffer, true); + SetIndexBuffer(lHHBufferIndex, lHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(lHHBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(lHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(lHHColorBuffer, true); + SetIndexBuffer(lHHColorBufferIndex, lHHColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LOW ... + ArraySetAsSeries(lLLBuffer, true); + SetIndexBuffer(lLLBufferIndex, lLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(lLLBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(lLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(lLLColorBuffer, true); + SetIndexBuffer(lLLColorBufferIndex, lLLColorBuffer, INDICATOR_COLOR_INDEX); + + // + // HIND Buffer ... + + // + // HIGH ... + ArraySetAsSeries(hHHBuffer, true); + SetIndexBuffer(hHHBufferIndex, hHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(hHHBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(hHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(hHHColorBuffer, true); + SetIndexBuffer(hHHColorBufferIndex, hHHColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LOW ... + ArraySetAsSeries(hLLBuffer, true); + SetIndexBuffer(hLLBufferIndex, hLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(hLLBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(hLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(hLLColorBuffer, true); + SetIndexBuffer(hLLColorBufferIndex, hLLColorBuffer, INDICATOR_COLOR_INDEX); + + // + // XSTR ... + + // + // FILLINGS ... + SetIndexBuffer(fillUpBufferIndex, fillUpBuffer, INDICATOR_DATA); + SetIndexBuffer(fillDownBufferIndex, fillDownBuffer, INDICATOR_DATA); + PlotIndexSetInteger(fillingBufferPlotIndex, PLOT_SHOW_DATA, false); + + // + // MAIN ... + SetIndexBuffer(trendBufferIndex, trendBuffer, INDICATOR_DATA); + PlotIndexSetInteger(trendBufferPlotIndex, PLOT_SHOW_DATA, showTrends); + SetIndexBuffer(trendColorBufferIndex, trendColorBuffer, INDICATOR_COLOR_INDEX); + + // + // RIBBON 1 ... + + // + ArraySetAsSeries(ribbon1Buffer, true); + SetIndexBuffer(ribbon1BufferIndex, ribbon1Buffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(ribbon1BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(ribbon1BufferPlotIndex, PLOT_SHOW_DATA, showRibbons); + + // + ArraySetAsSeries(ribbon1ColorBuffer, true); + SetIndexBuffer(ribbon1ColorBufferIndex, ribbon1ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // RIBBON 2 ... + + // + ArraySetAsSeries(ribbon2Buffer, true); + SetIndexBuffer(ribbon2BufferIndex, ribbon2Buffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(ribbon2BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(ribbon2BufferPlotIndex, PLOT_SHOW_DATA, showRibbons); + + // + ArraySetAsSeries(ribbon2ColorBuffer, true); + SetIndexBuffer(ribbon2ColorBufferIndex, ribbon2ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // RIBBON 3 ... + + // + ArraySetAsSeries(ribbon3Buffer, true); + SetIndexBuffer(ribbon3BufferIndex, ribbon3Buffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(ribbon3BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(ribbon3BufferPlotIndex, PLOT_SHOW_DATA, showRibbons); + + // + ArraySetAsSeries(ribbon3ColorBuffer, true); + SetIndexBuffer(ribbon3ColorBufferIndex, ribbon3ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // RIBBON 4 ... + + // + ArraySetAsSeries(ribbon4Buffer, true); + SetIndexBuffer(ribbon4BufferIndex, ribbon4Buffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(ribbon4BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(ribbon4BufferPlotIndex, PLOT_SHOW_DATA, showRibbons); + + // + ArraySetAsSeries(ribbon4ColorBuffer, true); + SetIndexBuffer(ribbon4ColorBufferIndex, ribbon4ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // RIBBON 5 ... + + // + ArraySetAsSeries(ribbon5Buffer, true); + SetIndexBuffer(ribbon5BufferIndex, ribbon5Buffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(ribbon5BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(ribbon5BufferPlotIndex, PLOT_SHOW_DATA, showRibbons); + + // + ArraySetAsSeries(ribbon5ColorBuffer, true); + SetIndexBuffer(ribbon5ColorBufferIndex, ribbon5ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // RIBBON 6 ... + + // + ArraySetAsSeries(ribbon6Buffer, true); + SetIndexBuffer(ribbon6BufferIndex, ribbon6Buffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(ribbon6BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(ribbon6BufferPlotIndex, PLOT_SHOW_DATA, showRibbons); + + // + ArraySetAsSeries(ribbon6ColorBuffer, true); + SetIndexBuffer(ribbon6ColorBufferIndex, ribbon6ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // XSSLC ... + + // + // UP ... + + // + ArraySetAsSeries(sslcUpBuffer, true); + SetIndexBuffer(sslcUpBufferIndex, sslcUpBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(sslcUpBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(sslcUpBufferPlotIndex, PLOT_SHOW_DATA, showSSLChannel); + + // + ArraySetAsSeries(sslcUpColorBuffer, true); + SetIndexBuffer(sslcUpColorBufferIndex, sslcUpColorBuffer, INDICATOR_COLOR_INDEX); + + // + // DOWN ... + + // + ArraySetAsSeries(sslcDownBuffer, true); + SetIndexBuffer(sslcDownBufferIndex, sslcDownBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(sslcDownBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(sslcDownBufferPlotIndex, PLOT_SHOW_DATA, showSSLChannel); + + // + ArraySetAsSeries(sslcDownColorBuffer, true); + SetIndexBuffer(sslcDownColorBufferIndex, sslcDownColorBuffer, INDICATOR_COLOR_INDEX); + + // + // XHULL ... + + // + // UP ... + + // + SetIndexBuffer(hullUpZoneBufferIndex, hullUpZoneBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(hullUpZoneBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(hullUpZoneBufferPlotIndex, PLOT_SHOW_DATA, showHull); + + // + SetIndexBuffer(hullUpZoneColorBufferIndex, hullUpZoneColorBuffer, INDICATOR_COLOR_INDEX); + + // + // DOWN ... + + // + SetIndexBuffer(hullDownZoneBufferIndex, hullDownZoneBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(hullDownZoneBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(hullDownZoneBufferPlotIndex, PLOT_SHOW_DATA, showHull); + + // + SetIndexBuffer(hullDownZoneColorBufferIndex, hullDownZoneColorBuffer, INDICATOR_COLOR_INDEX); + + // + // XHK ... + + // + // Candles Color ... + ArraySetAsSeries(hkCandleColorBuffer, true); + SetIndexBuffer(hkCandleColorBufferIndex, hkCandleColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Set EMPTY_VALUE on Candles Buffer ... + PlotIndexSetDouble(hkCandlesBufferIndex, PLOT_EMPTY_VALUE, 0.0); + + // + PlotIndexSetInteger(hkCandlesBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(hkCandleColorBufferIndex, PLOT_SHOW_DATA, false); + + // + // Open ... + ArraySetAsSeries(hkOpenBuffer, true); + PlotIndexSetInteger(hkOpenBufferIndex, PLOT_SHOW_DATA, false); + SetIndexBuffer(hkOpenBufferIndex, hkOpenBuffer, INDICATOR_DATA); + + // + // High ... + ArraySetAsSeries(hkHighBuffer, true); + SetIndexBuffer(hkHighBufferIndex, hkHighBuffer, INDICATOR_DATA); + PlotIndexSetInteger(hkHighBufferIndex, PLOT_SHOW_DATA, false); + + // + // Close ... + ArraySetAsSeries(hkCloseBuffer, true); + SetIndexBuffer(hkCloseBufferIndex, hkCloseBuffer, INDICATOR_DATA); + PlotIndexSetInteger(hkCloseBufferIndex, PLOT_SHOW_DATA, false); + + // + // Low ... + ArraySetAsSeries(hkLowBuffer, true); + SetIndexBuffer(hkLowBufferIndex, hkLowBuffer, INDICATOR_DATA); + PlotIndexSetInteger(hkLowBufferIndex, PLOT_SHOW_DATA, false); + + // + // XSMHK ... + + // + // Candles Color ... + ArraySetAsSeries(smhkCandleColorBuffer, true); + SetIndexBuffer(smhkCandleColorBufferIndex, smhkCandleColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Set EMPTY_VALUE on Candles Buffer ... + PlotIndexSetDouble(smhkCandlesBufferIndex, PLOT_EMPTY_VALUE, 0.0); + + // + PlotIndexSetInteger(smhkCandlesBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(smhkCandleColorBufferIndex, PLOT_SHOW_DATA, false); + + // + // Open ... + ArraySetAsSeries(smhkOpenBuffer, true); + PlotIndexSetInteger(smhkOpenBufferIndex, PLOT_SHOW_DATA, false); + SetIndexBuffer(smhkOpenBufferIndex, smhkOpenBuffer, INDICATOR_DATA); + + // + // High ... + ArraySetAsSeries(smhkHighBuffer, true); + SetIndexBuffer(smhkHighBufferIndex, smhkHighBuffer, INDICATOR_DATA); + PlotIndexSetInteger(smhkHighBufferIndex, PLOT_SHOW_DATA, false); + + // + // Close ... + ArraySetAsSeries(smhkCloseBuffer, true); + SetIndexBuffer(smhkCloseBufferIndex, smhkCloseBuffer, INDICATOR_DATA); + PlotIndexSetInteger(smhkCloseBufferIndex, PLOT_SHOW_DATA, false); + + // + // Low ... + ArraySetAsSeries(smhkLowBuffer, true); + SetIndexBuffer(smhkLowBufferIndex, smhkLowBuffer, INDICATOR_DATA); + PlotIndexSetInteger(smhkLowBufferIndex, PLOT_SHOW_DATA, false); + + // + // DATA Buffers ... + + // + // ATR ... + SetIndexBuffer(atrBufferIndex, atrBuffer, INDICATOR_CALCULATIONS); + + // + // TREND ... + SetIndexBuffer(trendStateBufferIndex, trendStateBuffer, INDICATOR_CALCULATIONS); + + // + // UP ... + SetIndexBuffer(upBufferIndex, upBuffer, INDICATOR_CALCULATIONS); + + // + // DOWN ... + SetIndexBuffer(downBufferIndex, downBuffer, INDICATOR_CALCULATIONS); + + // + // PRICE ... + SetIndexBuffer(priceBufferIndex, priceBuffer, INDICATOR_CALCULATIONS); + + // + // SSLCDOWNMA ... + ArraySetAsSeries(sslcUpMaBuffer, true); + SetIndexBuffer(sslcUpMaBufferIndex, sslcUpMaBuffer, INDICATOR_CALCULATIONS); + + // + // SSLCUPMA ... + ArraySetAsSeries(sslcDownMaBuffer, true); + SetIndexBuffer(sslcDownMaBufferIndex, sslcDownMaBuffer, INDICATOR_CALCULATIONS); + + // + // SSLCKPI ... + ArraySetAsSeries(sslcKpiBuffer, true); + SetIndexBuffer(sslcKpiBufferIndex, sslcKpiBuffer, INDICATOR_CALCULATIONS); + + // + // STATE Buffers ... + + // + // PEAKS ... + ArraySetAsSeries(peaksStateBuffer, true); + SetIndexBuffer(peaksStateBufferIndex, peaksStateBuffer, INDICATOR_CALCULATIONS); + + // + // VALES ... + ArraySetAsSeries(valesStateBuffer, true); + SetIndexBuffer(valesStateBufferIndex, valesStateBuffer, INDICATOR_CALCULATIONS); + + // + // CYCLES ... + + // + // SHORT ... + + // + ArraySetAsSeries(sHHStateBuffer, true); + SetIndexBuffer(sHHStateBufferIndex, sHHStateBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(sLLStateBuffer, true); + SetIndexBuffer(sLLStateBufferIndex, sLLStateBuffer, INDICATOR_CALCULATIONS); + + // + // MEDIUM ... + + // + ArraySetAsSeries(mHHStateBuffer, true); + SetIndexBuffer(mHHStateBufferIndex, mHHStateBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(mLLStateBuffer, true); + SetIndexBuffer(mLLStateBufferIndex, mLLStateBuffer, INDICATOR_CALCULATIONS); + + // + // LONG ... + + // + ArraySetAsSeries(lHHStateBuffer, true); + SetIndexBuffer(lHHStateBufferIndex, lHHStateBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(lLLStateBuffer, true); + SetIndexBuffer(lLLStateBufferIndex, lLLStateBuffer, INDICATOR_CALCULATIONS); + + // + // HIND ... + + // + ArraySetAsSeries(hHHStateBuffer, true); + SetIndexBuffer(hHHStateBufferIndex, hHHStateBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(hLLStateBuffer, true); + SetIndexBuffer(hLLStateBufferIndex, hLLStateBuffer, INDICATOR_CALCULATIONS); + + // + // XSTR ... + SetIndexBuffer(strTrendStateBufferIndex, strTrendStateBuffer, INDICATOR_CALCULATIONS); + + // + // XMBR ... + + // + // RIBBON 1 _ (High) ... + ArraySetAsSeries(rb1StateBuffer, true); + SetIndexBuffer(rb1StateBufferIndex, rb1StateBuffer, INDICATOR_CALCULATIONS); + + // + // RIBBON 2 _ (Open) ... + ArraySetAsSeries(rb2StateBuffer, true); + SetIndexBuffer(rb2StateBufferIndex, rb2StateBuffer, INDICATOR_CALCULATIONS); + + // + // RIBBON 3 _ (Close) ... + ArraySetAsSeries(rb3StateBuffer, true); + SetIndexBuffer(rb3StateBufferIndex, rb3StateBuffer, INDICATOR_CALCULATIONS); + + // + // RIBBON 4 _ (Median) ... + ArraySetAsSeries(rb4StateBuffer, true); + SetIndexBuffer(rb4StateBufferIndex, rb4StateBuffer, INDICATOR_CALCULATIONS); + + // + // RIBBON 5 _ (Typical) ... + ArraySetAsSeries(rb5StateBuffer, true); + SetIndexBuffer(rb5StateBufferIndex, rb5StateBuffer, INDICATOR_CALCULATIONS); + + // + // RIBBON 6 _ (Low) ... + ArraySetAsSeries(rb6StateBuffer, true); + SetIndexBuffer(rb6StateBufferIndex, rb6StateBuffer, INDICATOR_CALCULATIONS); + + // + // XHULL ... + + // + // UP Zone ... + SetIndexBuffer(hullUpStateBufferIndex, hullUpStateBuffer, INDICATOR_CALCULATIONS); + + // + // DOWN Zone ... + SetIndexBuffer(hullDownStateBufferIndex, hullDownStateBuffer, INDICATOR_CALCULATIONS); + + // + // XHK ... + + // + ArraySetAsSeries(hkStateBuffer, true); + SetIndexBuffer(hkStateBufferIndex, hkStateBuffer, INDICATOR_CALCULATIONS); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ + // + // Calculate ... + + // + // Calculate Short Cycle ... + CalculateShortCycle(bar_index); + + // + // Calculate Medium Cycle ... + CalculateMediumCycle(bar_index); + + // + // Calculate Long Cycle ... + CalculateLongCycle(bar_index); + + // + // Calculate Hind Cycle ... + CalculateHindCycle(bar_index); + + // + // Calculate Peaks and Vales ... + CalculatePeaksAndVales(bar_index); + + // + // Calculate Fibonnaci ... + CalculateFibonacci(bar_index); +} + +// +// START Calculation Parts ... +// + +// +// SHORT Cycle ... +void CalculateShortCycle( + int bar_index // Selected Bar Index +) +{ + // + ENUM_TIMEFRAMES mPeriod = mL1Period; + + // + double hhValue = GetCycleHHC( + bar_index, + mPeriod); + + // + double llValue = GetCycleLLC( + bar_index, + mPeriod); + + // + double lastHH = mLastSHH; + double lastLL = mLastSLL; + + // + double mHHState = EMPTY_VALUE; + double mhhColorIDX = mHideColorIDX; + if (showLevels) + { + // + if (hhValue == lastHH) + { + mhhColorIDX = showConsolidations ? 1 : mHideColorIDX; + } + else if (hhValue > lastHH) + { + mhhColorIDX = 2; + } + else if (hhValue < lastHH) + { + mhhColorIDX = 3; + } + + // + mHHState = mhhColorIDX; + } + else + { + mhhColorIDX = mHideColorIDX; + } + + // + double mLLState = EMPTY_VALUE; + double mllColorIDX = mHideColorIDX; + if (showLevels) + { + // + if (llValue == lastLL) + { + mllColorIDX = showConsolidations ? 1 : mHideColorIDX; + } + else if (llValue > lastLL) + { + mllColorIDX = 2; + } + else if (llValue < lastLL) + { + mllColorIDX = 3; + } + + // + mLLState = mllColorIDX; + } + else + { + mllColorIDX = mHideColorIDX; + } + + // + mLastSHH = hhValue; + mLastSLL = llValue; + + // + sHHBuffer[bar_index] = hhValue; + sLLBuffer[bar_index] = llValue; + sHHStateBuffer[bar_index] = mHHState; + sLLStateBuffer[bar_index] = mLLState; + sHHColorBuffer[bar_index] = mhhColorIDX; + sLLColorBuffer[bar_index] = mllColorIDX; +} + +// +// MEDIUM Cycle ... +void CalculateMediumCycle( + int bar_index // Selected Bar Index +) +{ + // + ENUM_TIMEFRAMES mPeriod = mL2Period; + + // + double hhValue = GetCycleHHC( + bar_index, + mPeriod); + + // + double llValue = GetCycleLLC( + bar_index, + mPeriod); + + // + double lastHH = mLastMHH; + double lastLL = mLastMLL; + + // + double mHHState = EMPTY_VALUE; + double mhhColorIDX = mHideColorIDX; + if (showLevels) + { + // + if (hhValue == lastHH) + { + mhhColorIDX = showConsolidations ? 1 : mHideColorIDX; + } + else if (hhValue > lastHH) + { + mhhColorIDX = 2; + } + else if (hhValue < lastHH) + { + mhhColorIDX = 3; + } + + // + mHHState = mhhColorIDX; + } + else + { + mhhColorIDX = mHideColorIDX; + } + + // + double mLLState = EMPTY_VALUE; + double mllColorIDX = mHideColorIDX; + if (showLevels) + { + // + if (llValue == lastLL) + { + mllColorIDX = showConsolidations ? 1 : mHideColorIDX; + } + else if (llValue > lastLL) + { + mllColorIDX = 2; + } + else if (llValue < lastLL) + { + mllColorIDX = 3; + } + + // + mLLState = mllColorIDX; + } + else + { + mllColorIDX = mHideColorIDX; + } + + // + mLastMHH = hhValue; + mLastMLL = llValue; + + // + mHHBuffer[bar_index] = hhValue; + mLLBuffer[bar_index] = llValue; + mHHStateBuffer[bar_index] = mHHState; + mLLStateBuffer[bar_index] = mLLState; + mHHColorBuffer[bar_index] = mhhColorIDX; + mLLColorBuffer[bar_index] = mllColorIDX; +} + +// +// LONG Cycle ... +void CalculateLongCycle( + int bar_index // Selected Bar Index +) +{ + // + ENUM_TIMEFRAMES mPeriod = mL3Period; + + // + double hhValue = GetCycleHHC( + bar_index, + mPeriod); + + // + double llValue = GetCycleLLC( + bar_index, + mPeriod); + + // + double lastHH = mLastLHH; + double lastLL = mLastLLL; + + // + double mHHState = EMPTY_VALUE; + double mhhColorIDX = mHideColorIDX; + if (showLevels) + { + // + if (hhValue == lastHH) + { + mhhColorIDX = showConsolidations ? 1 : mHideColorIDX; + } + else if (hhValue > lastHH) + { + mhhColorIDX = 2; + } + else if (hhValue < lastHH) + { + mhhColorIDX = 3; + } + + // + mHHState = mhhColorIDX; + } + else + { + mhhColorIDX = mHideColorIDX; + } + + // + double mLLState = EMPTY_VALUE; + double mllColorIDX = mHideColorIDX; + if (showLevels) + { + // + if (llValue == lastLL) + { + mllColorIDX = showConsolidations ? 1 : mHideColorIDX; + } + else if (llValue > lastLL) + { + mllColorIDX = 2; + } + else if (llValue < lastLL) + { + mllColorIDX = 3; + } + + // + mLLState = mllColorIDX; + } + else + { + mllColorIDX = mHideColorIDX; + } + + // + mLastLHH = hhValue; + mLastLLL = llValue; + + // + lHHBuffer[bar_index] = hhValue; + lLLBuffer[bar_index] = llValue; + lHHStateBuffer[bar_index] = mHHState; + lLLStateBuffer[bar_index] = mLLState; + lHHColorBuffer[bar_index] = mhhColorIDX; + lLLColorBuffer[bar_index] = mllColorIDX; +} + +// +// HIND Cycle ... +void CalculateHindCycle( + int bar_index // Selected Bar Index +) +{ + // + ENUM_TIMEFRAMES mPeriod = mL4Period; + + // + double hhValue = GetCycleHHC( + bar_index, + mPeriod); + + // + double llValue = GetCycleLLC( + bar_index, + mPeriod); + + // + double lastHH = mLastHHH; + double lastLL = mLastHLL; + + // + double mHHState = EMPTY_VALUE; + double mhhColorIDX = mHideColorIDX; + if (showLevels) + { + // + if (hhValue == lastHH) + { + mhhColorIDX = showConsolidations ? 1 : mHideColorIDX; + } + else if (hhValue > lastHH) + { + mhhColorIDX = 2; + } + else if (hhValue < lastHH) + { + mhhColorIDX = 3; + } + + // + mHHState = mhhColorIDX; + } + else + { + mhhColorIDX = mHideColorIDX; + } + + // + double mLLState = EMPTY_VALUE; + double mllColorIDX = mHideColorIDX; + if (showLevels) + { + // + if (llValue == lastLL) + { + mllColorIDX = showConsolidations ? 1 : mHideColorIDX; + } + else if (llValue > lastLL) + { + mllColorIDX = 2; + } + else if (llValue < lastLL) + { + mllColorIDX = 3; + } + + // + mLLState = mllColorIDX; + } + else + { + mllColorIDX = mHideColorIDX; + } + + // + mLastHHH = hhValue; + mLastHLL = llValue; + + // + hHHBuffer[bar_index] = hhValue; + hLLBuffer[bar_index] = llValue; + hHHStateBuffer[bar_index] = mHHState; + hLLStateBuffer[bar_index] = mLLState; + hHHColorBuffer[bar_index] = mhhColorIDX; + hLLColorBuffer[bar_index] = mllColorIDX; +} + +// +// Calculate Peaks and Values ... +void CalculatePeaksAndVales( + int bar_index // Bar Index +) +{ + // + // Retrieve Requirements ... + + // + // Short ... + double sHHValue = sHHBuffer[bar_index]; + double sLLValue = sLLBuffer[bar_index]; + + // + // Medium ... + double mHHValue = mHHBuffer[bar_index]; + double mLLValue = mLLBuffer[bar_index]; + + // + // Long ... + double lHHValue = lHHBuffer[bar_index]; + double lLLValue = lLLBuffer[bar_index]; + + // + // Hind ... + double hHHValue = hHHBuffer[bar_index]; + double hLLValue = hLLBuffer[bar_index]; + + // + double rColorIDX = mHideColorIDX; + double sColorIDX = mHideColorIDX; + + // + // RESISTANCE ... + double rValue = (sHHValue + mHHValue + lHHValue + hHHValue) / 4; + + // + // PEAKS ... + bool isPeak = rValue == hHHValue && + hHHValue == lHHValue && + lHHValue == mHHValue && + mHHValue == sHHValue; + + // + if (isPeak && lastPeak != rValue) + { + // + rColorIDX = 1; + lastPeak = rValue; + peaksStateBuffer[bar_index] = rColorIDX; + } + else + { + peaksStateBuffer[bar_index] = EMPTY_VALUE; + } + + // + // SUPPORT ... + double sValue = (sLLValue + mLLValue + lLLValue + hLLValue) / 4; + + // + // VALES ... + bool isVale = sValue == hLLValue && + hLLValue == lLLValue && + lLLValue == mLLValue && + mLLValue == sLLValue; + + // + if (isVale && lastVale != sValue) + { + // + sColorIDX = 1; + lastVale = sValue; + valesStateBuffer[bar_index] = sColorIDX; + } + else + { + valesStateBuffer[bar_index] = EMPTY_VALUE; + } + + // + rBuffer[bar_index] = rValue; + sBuffer[bar_index] = sValue; + peaksBuffer[bar_index] = lastPeak; + valesBuffer[bar_index] = lastVale; + + // + if (showPeaksAndVales) + { + // + rColorBuffer[bar_index] = rColorIDX; + sColorBuffer[bar_index] = sColorIDX; + } + else + { + // + rColorBuffer[bar_index] = mHideColorIDX; + sColorBuffer[bar_index] = mHideColorIDX; + } +} + +// +// Calculate Fibonacci Level 1 ... +void CalculateFibonacci( + int bar_index // Bar Index +) +{ + // + // Select Requirements ... + double upPrice = peaksBuffer[bar_index]; + double downPrice = valesBuffer[bar_index]; + + // + // Level 1 ... + double fibLevel1Value = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel1, + 1); + // + // Level 2 ... + double fibLevel2Value = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel2, + 1); + + // + // Level 3 ... + double fibLevel3Value = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel3, + 1); + + // + // Level 4 ... + double fibLevel4Value = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel4, + 1); + + // + // Level 5 ... + double fibLevel5Value = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel5, + 1); + + // + fl1Buffer[bar_index] = fibLevel1Value; + fl2Buffer[bar_index] = fibLevel2Value; + fl3Buffer[bar_index] = fibLevel3Value; + fl4Buffer[bar_index] = fibLevel4Value; + fl5Buffer[bar_index] = fibLevel5Value; + + // + double fl1ColorIdx = showFibo1Levels ? 1 : mHideColorIDX; + double fl2ColorIdx = showFibo2Levels ? 1 : mHideColorIDX; + double fl3ColorIdx = showFibo3Levels ? 1 : mHideColorIDX; + double fl4ColorIdx = showFibo4Levels ? 1 : mHideColorIDX; + double fl5ColorIdx = showFibo5Levels ? 1 : mHideColorIDX; + + // + fl1ColorBuffer[bar_index] = fl1ColorIdx; + fl2ColorBuffer[bar_index] = fl2ColorIdx; + fl3ColorBuffer[bar_index] = fl3ColorIdx; + fl4ColorBuffer[bar_index] = fl4ColorIdx; + fl5ColorBuffer[bar_index] = fl5ColorIdx; +} + +// +// XSTR ... +bool CalculateXSTR( + const int rates_total, + const int prev_calculated, + const double &open[], + const double &high[], + const double &low[], + const double &close[] // +) +{ + // + bool result = false; + + // + int numOfRequiredAtrs; + if (prev_calculated > rates_total || prev_calculated < 0) + { + numOfRequiredAtrs = rates_total; + } + else + { + // + numOfRequiredAtrs = rates_total - prev_calculated; + if (prev_calculated > 0) + { + numOfRequiredAtrs++; + } + } + + // + // Checking for stop ... + if (IsStopped()) + { + return result; + } + + // + // Check Number of items Copy or not ... + int copiedATRs = CopyBuffer(atrHandler, 0, 0, numOfRequiredAtrs, atrBuffer); + if (copiedATRs <= 0) + { + return result; + } + + // + // + int limit; + + // + // checking for the limit start of calculation of an indicator ... + if (prev_calculated > rates_total || prev_calculated <= 0) + { + // + // starting index for calculation of all bars ... + limit = maxLength; + } + else + { + // + // starting number for calculation of new bars + limit = prev_calculated - 1; + } + + // + // Main Loop ... + for (int i = limit; i < rates_total && !IsStopped(); i++) + { + // + // Calculated Price ... + double price = GetAppliedPrice( + trendPriceAppliedTo, + open, + high, + low, + close, + i); + // price = (high[i] + low[i]) / 2; + priceBuffer[i] = price; + + // + double atr = atrBuffer[i]; + + // + // Up ... + upBuffer[i] = price + (trendMultiplier * atr); + + // + // Down ... + downBuffer[i] = price - (trendMultiplier * atr); + + // + if (close[i] > upBuffer[i - 1]) + { + // + trendStateBuffer[i] = 1; + if (trendStateBuffer[i - 1] == -1) + { + changeOfTrend = 1; + } + } + else if (close[i] < downBuffer[i - 1]) + { + // + trendStateBuffer[i] = -1; + if (trendStateBuffer[i - 1] == 1) + { + changeOfTrend = 1; + } + } + else if (trendStateBuffer[i - 1] == 1) + { + // + trendStateBuffer[i] = 1; + changeOfTrend = 0; + } + else if (trendStateBuffer[i - 1] == -1) + { + // + trendStateBuffer[i] = -1; + changeOfTrend = 0; + } + + // + // Down Trend Starting ... + if (trendStateBuffer[i] < 0 && trendStateBuffer[i - 1] > 0) + { + startBearishTrend = 1; + } + else + { + startBearishTrend = 0; + } + + // + // Up Trend Starting ... + if (trendStateBuffer[i] > 0 && trendStateBuffer[i - 1] < 0) + { + startBullishTrend = 1; + } + else + { + startBullishTrend = 0; + } + + // + if (trendStateBuffer[i] > 0 && downBuffer[i] < downBuffer[i - 1]) + { + downBuffer[i] = downBuffer[i - 1]; + } + + // + if (trendStateBuffer[i] < 0 && upBuffer[i] > upBuffer[i - 1]) + { + upBuffer[i] = upBuffer[i - 1]; + } + + // + if (startBearishTrend == 1) + { + upBuffer[i] = priceBuffer[i] + (trendMultiplier * atr); + } + + // + if (startBullishTrend == 1) + { + downBuffer[i] = priceBuffer[i] - (trendMultiplier * atr); + } + + // + // Draw the indicator ... + + // + double colorIDX = 0; + double state = EMPTY_VALUE; + trendColorBuffer[i] = colorIDX; + + // + if (trendStateBuffer[i] == 1) + { + // + trendBuffer[i] = downBuffer[i]; + if (changeOfTrend == 1) + { + // + trendBuffer[i - 1] = trendBuffer[i - 2]; + changeOfTrend = 0; + + // + state = 2; + } + + // + colorIDX = 1; + } + else if (trendStateBuffer[i] == -1) + { + // + trendBuffer[i] = upBuffer[i]; + if (changeOfTrend == 1) + { + // + trendBuffer[i - 1] = trendBuffer[i - 2]; + changeOfTrend = 0; + + // + state = 3; + } + + // + colorIDX = 2; + } + + // + if (showTrends) + { + trendColorBuffer[i] = colorIDX; + } + strTrendStateBuffer[i] = state; + + // + // Filling ... + if (fillTrends) + { + // + fillUpBuffer[i] = trendBuffer[i]; + fillDownBuffer[i] = close[i]; + } + else + { + // + fillUpBuffer[i] = EMPTY_VALUE; + fillDownBuffer[i] = EMPTY_VALUE; + } + } + + // + result = true; + + // + return true; +} + +// +XMRBColorInfo GetRibbonColorIndex( + double value, + const double h, + const double l // +) +{ + // + XMRBColorInfo result; + + // + result.state = EMPTY_VALUE; + result.clr = mHideColorIDX; + + // + // Color Indexes ... + // 0 => HIDE + // 1 => NEUTURAL + // 2 => BULLISH + // 3 => BEARISH + + // + result.clr = 1; + + // + if (value < l && value < h) + { + result.clr = 2; + } + else if (value > h && value > l) + { + result.clr = 3; + } + else if (value < h && value > l) + { + result.clr = 1; + } + + // + result.state = result.clr; + + // + if (!showRibbons) + { + result.clr = mHideColorIDX; + } + + // + return result; +} + +// +// Calculate Ribbons Color ... +void CalculateRibbonsColors( + int bar_index, // Bar Index + const double &high[], + const double &low[] // +) +{ + // + double tmpVal; + XMRBColorInfo tmpColorIDX; + + // + double h = high[bar_index]; + double l = low[bar_index]; + + // + // RIBBON 1 ... + tmpVal = ribbon1Buffer[bar_index]; + tmpColorIDX = GetRibbonColorIndex( + tmpVal, + h, + l); + rb1StateBuffer[bar_index] = tmpColorIDX.state; + ribbon1ColorBuffer[bar_index] = tmpColorIDX.clr; + + // + // RIBBON 2 ... + tmpVal = ribbon2Buffer[bar_index]; + tmpColorIDX = GetRibbonColorIndex( + tmpVal, + h, + l); + rb2StateBuffer[bar_index] = tmpColorIDX.state; + ribbon2ColorBuffer[bar_index] = tmpColorIDX.clr; + + // + // RIBBON 3 ... + tmpVal = ribbon3Buffer[bar_index]; + tmpColorIDX = GetRibbonColorIndex( + tmpVal, + h, + l); + rb3StateBuffer[bar_index] = tmpColorIDX.state; + ribbon3ColorBuffer[bar_index] = tmpColorIDX.clr; + + // + // RIBBON 4 ... + tmpVal = ribbon4Buffer[bar_index]; + tmpColorIDX = GetRibbonColorIndex( + tmpVal, + h, + l); + rb4StateBuffer[bar_index] = tmpColorIDX.state; + ribbon4ColorBuffer[bar_index] = tmpColorIDX.clr; + + // + // RIBBON 5 ... + tmpVal = ribbon5Buffer[bar_index]; + tmpColorIDX = GetRibbonColorIndex( + tmpVal, + h, + l); + rb5StateBuffer[bar_index] = tmpColorIDX.state; + ribbon5ColorBuffer[bar_index] = tmpColorIDX.clr; + + // + // RIBBON 6 ... + tmpVal = ribbon6Buffer[bar_index]; + tmpColorIDX = GetRibbonColorIndex( + tmpVal, + h, + l); + rb6StateBuffer[bar_index] = tmpColorIDX.state; + ribbon6ColorBuffer[bar_index] = tmpColorIDX.clr; +} + +// +// Calculate SSL Channel ... +void CalculateSSLC( + int bar_index, // Selected Bar Index + int limit, + int ratesTotal, + int prevCalculated, + const double &close[]) +{ + // + double upMaValue = sslcUpMaBuffer[bar_index]; + double downMaValue = sslcDownMaBuffer[bar_index]; + + // + double closeValue = close[bar_index]; + + // + double kpiValue; + if (closeValue > upMaValue) + { + kpiValue = 1; + } + else if (closeValue < downMaValue) + { + kpiValue = -1; + } + else + { + kpiValue = sslcKpiBuffer[bar_index + 1]; + } + + // + sslcKpiBuffer[bar_index] = kpiValue; + + // + double upValue = kpiValue < 0 ? downMaValue : upMaValue; + sslcUpBuffer[bar_index] = upValue; + + // + double downValue = kpiValue < 0 ? upMaValue : downMaValue; + sslcDownBuffer[bar_index] = downValue; + + // + if (showSSLChannel) + { + // + sslcUpColorBuffer[bar_index] = 1; + sslcDownColorBuffer[bar_index] = 1; + } + else + { + // + sslcUpColorBuffer[bar_index] = mHideColorIDX; + sslcDownColorBuffer[bar_index] = mHideColorIDX; + } +} + +// +// Calculate XHULL ... +void CalculateHull( + int bar_index, // Selected Bar Index + int ratesTotal, // Total Rates + double upPrice, // Up Price ... + double downPrice // Down Price ... +) +{ + // + double upValue = mUpZHull.Calculate( + upPrice, + bar_index, + ratesTotal); + hullUpZoneBuffer[bar_index] = upValue; + double upColorIDX = (bar_index > 0) + ? (hullUpZoneBuffer[bar_index] > hullUpZoneBuffer[bar_index - 1]) + ? 2 + : (hullUpZoneBuffer[bar_index] < hullUpZoneBuffer[bar_index - 1]) + ? 3 + : hullUpZoneColorBuffer[bar_index - 1] + : 1; + + // + double downValue = mDownZHull.Calculate( + downPrice, + bar_index, + ratesTotal); + hullDownZoneBuffer[bar_index] = downValue; + double downColorIDX = (bar_index > 0) + ? (hullDownZoneBuffer[bar_index] > hullDownZoneBuffer[bar_index - 1]) + ? 2 + : (hullDownZoneBuffer[bar_index] < hullDownZoneBuffer[bar_index - 1]) + ? 3 + : hullDownZoneColorBuffer[bar_index - 1] + : 1; + + // + hullUpStateBuffer[bar_index] = upColorIDX == 0 ? 1 : upColorIDX; + hullDownStateBuffer[bar_index] = downColorIDX == 0 ? 1 : downColorIDX; + if (showHull) + { + // + hullUpZoneColorBuffer[bar_index] = upColorIDX; + hullDownZoneColorBuffer[bar_index] = downColorIDX; + } + else + { + // + hullUpZoneColorBuffer[bar_index] = mHideColorIDX; + hullDownZoneColorBuffer[bar_index] = mHideColorIDX; + } +} + +// +// Calculate HikenAshi Buffers ... +void CalculateHikenAshi( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[]) +{ + // + double mPrevHKOpenValue; + double mPrevHKCloseValue; + + // + if (ArraySize(open) <= bar_index + 1) + { + // + mPrevHKOpenValue = 0; + mPrevHKCloseValue = 0; + } + else + { + // + mPrevHKOpenValue = hkOpenBuffer[bar_index + 1]; + mPrevHKCloseValue = hkCloseBuffer[bar_index + 1]; + } + + // + double mHKOpenValue = (mPrevHKOpenValue + mPrevHKCloseValue) / 2; + double mHKCloseValue = (open[bar_index] + high[bar_index] + close[bar_index] + low[bar_index]) / 4; + double mHKHighValue = MathMax(high[bar_index], MathMax(mHKOpenValue, mHKCloseValue)); + double mHKLowValue = MathMin(low[bar_index], MathMin(mHKOpenValue, mHKCloseValue)); + + // + hkOpenBuffer[bar_index] = mHKOpenValue; + hkHighBuffer[bar_index] = mHKHighValue; + hkLowBuffer[bar_index] = mHKLowValue; + hkCloseBuffer[bar_index] = mHKCloseValue; + + // + double candleColorValue = + mHKOpenValue < mHKCloseValue ? 1 : 2; + + // + hkStateBuffer[bar_index] = candleColorValue + 1; + hkCandleColorBuffer[bar_index] = showHKCandles ? candleColorValue : 0; +} + +// +// Calculate Candle Timer ... +void CalculateCandleTimer() +{ + // + if (!showCandleTimer) + { + return; + } + + // + XCandleRemains remainTime; + GetCandleRemainsTime( + remainTime, + _Symbol, + _Period, + 0); + + // + string msg = ToString( + remainTime, + "", + "", + "", + "", + "", + ":", + true); + + // + long mSpread = SymbolInfoInteger(Symbol(), SYMBOL_SPREAD); + + // + string _sp = ""; + if (mSpread < 10) + _sp = ".."; + else if (mSpread < 100) + _sp = "."; + + // + string objText = "Spread: " + IntegerToString(mSpread) + _sp + " Next Bar in: " + msg; + + // + ObjectSetString(0, ShortName, OBJPROP_TEXT, objText); + ObjectSetInteger(0, ShortName, OBJPROP_FONTSIZE, 10); + ObjectSetString(0, ShortName, OBJPROP_FONT, "Courier"); + ObjectSetInteger(0, ShortName, OBJPROP_COLOR, candleTimerColor); +} + +// +// Calculate Smoothed Hiken Ashi Candles ... +void CalculateSMHK( + int ratesTotal, // Total Bars + int prevCalculated // Calculated Bars +) +{ + // + // Open ... + int calculatedSMHKOpens = ExponentialMAOnBuffer( + ratesTotal, + prevCalculated, + 0, + mHKSmoothingLength, + hkOpenBuffer, + smhkOpenBuffer); + + // + // High ... + int calculatedSMHKHighs = ExponentialMAOnBuffer( + ratesTotal, + prevCalculated, + 0, + mHKSmoothingLength, + hkHighBuffer, + smhkHighBuffer); + + // + // Low ... + int calculatedSMHKLows = ExponentialMAOnBuffer( + ratesTotal, + prevCalculated, + 0, + mHKSmoothingLength, + hkLowBuffer, + smhkLowBuffer); + + // + // Close ... + int calculatedSMHKCloses = ExponentialMAOnBuffer( + ratesTotal, + prevCalculated, + 0, + mHKSmoothingLength, + hkCloseBuffer, + smhkCloseBuffer); + + // + // Find Calculated Items for Colors ... + int mNumberOfItems = MathMin(calculatedSMHKOpens, calculatedSMHKHighs); + mNumberOfItems = MathMin(mNumberOfItems, calculatedSMHKLows); + mNumberOfItems = MathMin(mNumberOfItems, calculatedSMHKCloses); + + // + // Create a Loop for Color of Candles ... + for (int i = 0; i < mNumberOfItems; i++) + { + // + bool isBearish = + // + smhkOpenBuffer[i] > smhkCloseBuffer[i] + // + ; + + // + if (showSMHKCandles) + { + // + smhkCandleColorBuffer[i] = isBearish + ? 2 + : 1; + } + else + { + // + smhkCandleColorBuffer[i] = mHideColorIDX; + } + } +} + +// +// END Calculation Parts ... +// + +// +// START Utilities ... +// + +// +// Create Candle Timer ... +void CreateIndicatorObject() +{ + // + if (!showCandleTimer) + { + return; + } + + // + ObjectCreate(0, ShortName, OBJ_LABEL, 0, 0, 0); + ObjectSetInteger(0, ShortName, OBJPROP_CORNER, candleTimerCorner); + ObjectSetInteger(0, ShortName, OBJPROP_XDISTANCE, 10); + ObjectSetInteger(0, ShortName, OBJPROP_YDISTANCE, 2); + + // + ENUM_ANCHOR_POINT Anchor = ANCHOR_LEFT_UPPER; + switch (candleTimerCorner) + { + case CORNER_LEFT_UPPER: + Anchor = ANCHOR_LEFT_UPPER; + break; + case CORNER_RIGHT_UPPER: + Anchor = ANCHOR_RIGHT_UPPER; + break; + case CORNER_LEFT_LOWER: + Anchor = ANCHOR_LEFT_LOWER; + break; + case CORNER_RIGHT_LOWER: + Anchor = ANCHOR_RIGHT_LOWER; + break; + } + + // + ObjectSetInteger(0, ShortName, OBJPROP_ANCHOR, Anchor); +} + +// +bool InitMaHandler( + int &handler, + int length, + ENUM_X_MA_METHOD mode, + ENUM_APPLIED_PRICE appliedTo) +{ + // + bool result = false; + + // + if (length <= 0) + { + return result; + } + + // + bool genericMethod = false; + ENUM_MA_METHOD method = NULL; + if (mode == X_MA_AMA) + { + // + handler = iAMA( + _Symbol, + _Period, + length, + mMRBAMAFast, + mMRBAMASlow, + 0, + appliedTo); + } + else if (mode == X_MA_EMA) + { + // + method = MODE_EMA; + genericMethod = true; + } + else if (mode == X_MA_LWMA) + { + // + method = MODE_LWMA; + genericMethod = true; + } + else if (mode == X_MA_SMA) + { + // + method = MODE_SMA; + genericMethod = true; + } + else if (mode == X_MA_SMMA) + { + // + method = MODE_SMMA; + genericMethod = true; + } + + // + if (genericMethod && handler == INVALID_HANDLE) + { + // + handler = iMA( + _Symbol, + _Period, + length, + 0, + method, + appliedTo); + } + + // + result = handler != INVALID_HANDLE; + + // + return result; +} + +// +// Retrieve Cycles Highest High ... +double GetCycleHH( + int bar_index, // Bar Index + ENUM_TIMEFRAMES period // Period +) +{ + // + datetime mCycleStartAt = GetPeriodStartTime( + _Symbol, + period); + + // + int mStartCycleBarIndex = iBarShift( + _Symbol, + _Period, + mCycleStartAt, + false); + + // + int mCycleCount = MathAbs(mStartCycleBarIndex - bar_index); + if (mCycleCount < 1) + { + mCycleCount = 1; + } + + // + // HIGH ... + int hhIndex = iHighest( + _Symbol, + _Period, + hhMode, + mCycleCount, + bar_index); + double result = GetAppliedPrice( + hhIndex, + hhMode); + + // + return result; +} + +// +// Retrieve Cycles Lowest Low ... +double GetCycleLL( + int bar_index, // Bar Index + ENUM_TIMEFRAMES period // Period +) +{ + // + datetime mCycleStartAt = GetPeriodStartTime( + _Symbol, + period); + + // + int mStartCycleBarIndex = iBarShift( + _Symbol, + _Period, + mCycleStartAt, + false); + + // + int mCycleCount = MathAbs(mStartCycleBarIndex - bar_index); + if (mCycleCount < 1) + { + mCycleCount = 1; + } + + // + // LOW ... + int llIndex = iLowest( + _Symbol, + _Period, + llMode, + mCycleCount, + bar_index); + double result = GetAppliedPrice( + llIndex, + llMode); + + // + return result; +} + +// +// Retrieve Cycles Highest High ... +double GetCycleHHC( + int bar_index, // Bar Index + ENUM_TIMEFRAMES period // Period +) +{ + // + int mCycleCount = 0; + if (period == mL1Period) + { + mCycleCount = mL1Candles; + } + else if (period == mL2Period) + { + mCycleCount = mL2Candles; + } + else if (period == mL3Period) + { + mCycleCount = mL3Candles; + } + else if (period == mL4Period) + { + mCycleCount = mL4Candles; + } + + // + // HIGH ... + int hhIndex = iHighest( + _Symbol, + _Period, + hhMode, + mCycleCount, + bar_index); + double result = GetAppliedPrice( + hhIndex, + hhMode); + + // + return result; +} + +// +// Retrieve Cycles Lowest Low ... +double GetCycleLLC( + int bar_index, // Bar Index + ENUM_TIMEFRAMES period // Period +) +{ + // + int mCycleCount = 0; + if (period == mL1Period) + { + mCycleCount = mL1Candles; + } + else if (period == mL2Period) + { + mCycleCount = mL2Candles; + } + else if (period == mL3Period) + { + mCycleCount = mL3Candles; + } + else if (period == mL4Period) + { + mCycleCount = mL4Candles; + } + + // + // LOW ... + int llIndex = iLowest( + _Symbol, + _Period, + llMode, + mCycleCount, + bar_index); + double result = GetAppliedPrice( + llIndex, + llMode); + + // + return result; +} + +// +string GenerateCyclesRepresentation() +{ + // + string result = ""; + + // + result += "C1: " + ToString(mL1Period) + "\n"; + result += "C2: " + ToString(mL2Period) + "\n"; + result += "C3: " + ToString(mL3Period) + "\n"; + result += "C4: " + ToString(mL4Period); + + // + return result; +} + +// +// Apply Custom Chart Style ... +void ApplyCustomChartStyle() +{ + // + // Read Current Chart Config and Store it ... + ReadChartStyle(); + + // + // After Reading Current Chart Style ... + // we have to Save Configs and Change Styles ... + clearStyle = chartStyle; + + // + clearStyle.upColor = CLR_NONE; + clearStyle.downColor = CLR_NONE; + clearStyle.lineColor = CLR_NONE; + clearStyle.bullishColor = CLR_NONE; + clearStyle.bearishColor = CLR_NONE; + + // + // Decide to Show or not Candles based on User Input ... + if (showCandles) + { + SetChartStyle(chartStyle); + } + else + { + SetChartStyle(clearStyle); + } +} + +// +// Read Previous Chart Style ... +void ReadChartStyle() +{ + // + // Retrieve Current Chart ID ... + long chartId = ChartID(); + chartStyle.chartId = chartId; + + // + // Retrieve Chart Mode ... + chartStyle.mode = (ENUM_CHART_MODE)ChartGetInteger(chartId, CHART_MODE); + + // + chartStyle.showBidLine = (bool)ChartGetInteger(chartId, CHART_SHOW_BID_LINE); + chartStyle.showAskLine = (bool)ChartGetInteger(chartId, CHART_SHOW_ASK_LINE); + chartStyle.showGrid = (bool)ChartGetInteger(chartId, CHART_SHOW_GRID); + chartStyle.showVolumes = (bool)ChartGetInteger(chartId, CHART_SHOW_VOLUMES); + chartStyle.showTradeLevels = (bool)ChartGetInteger(chartId, CHART_SHOW_TRADE_LEVELS); + chartStyle.autoScroll = (bool)ChartGetInteger(chartId, CHART_AUTOSCROLL); + chartStyle.quickNavigation = (bool)ChartGetInteger(chartId, CHART_QUICK_NAVIGATION); + + // + chartStyle.foreGroundColor = (color)ChartGetInteger(chartId, CHART_COLOR_FOREGROUND); + chartStyle.backGroundColor = (color)ChartGetInteger(chartId, CHART_COLOR_BACKGROUND); + chartStyle.upColor = (color)ChartGetInteger(chartId, CHART_COLOR_CHART_UP); + chartStyle.downColor = (color)ChartGetInteger(chartId, CHART_COLOR_CHART_DOWN); + chartStyle.bullishColor = (color)ChartGetInteger(chartId, CHART_COLOR_CANDLE_BULL); + chartStyle.bearishColor = (color)ChartGetInteger(chartId, CHART_COLOR_CANDLE_BEAR); + chartStyle.gridColor = (color)ChartGetInteger(chartId, CHART_COLOR_GRID); + chartStyle.bidLineColor = (color)ChartGetInteger(chartId, CHART_COLOR_BID); + chartStyle.askLineColor = (color)ChartGetInteger(chartId, CHART_COLOR_ASK); + chartStyle.stopColor = (color)ChartGetInteger(chartId, CHART_COLOR_STOP_LEVEL); + chartStyle.lineColor = (color)ChartGetInteger(chartId, CHART_COLOR_CHART_LINE); + chartStyle.volumesColor = (color)ChartGetInteger(chartId, CHART_COLOR_VOLUME); + + // + chartStyle.mode = chartMode; + chartStyle.upColor = upColor; + chartStyle.downColor = downColor; + chartStyle.lineColor = lineColor; + chartStyle.bearishColor = bearishColor; + chartStyle.bullishColor = bullishColor; + chartStyle.volumesColor = volumesColor; +} + +// +// Set Chart Style ... +void SetChartStyle( + XChartStyle &mChartStyle // Chart Style to Apply +) +{ + // + ApplyChartStyle( + mChartStyle.chartId, + mChartStyle.mode, + mChartStyle.showBidLine, + mChartStyle.showAskLine, + mChartStyle.showGrid, + mChartStyle.showVolumes, + mChartStyle.showTradeLevels, + mChartStyle.autoScroll, + mChartStyle.quickNavigation, + mChartStyle.foreGroundColor, + mChartStyle.backGroundColor, + mChartStyle.upColor, + mChartStyle.downColor, + mChartStyle.bullishColor, + mChartStyle.bearishColor, + mChartStyle.gridColor, + mChartStyle.bidLineColor, + mChartStyle.askLineColor, + mChartStyle.lineColor, + mChartStyle.stopColor, + mChartStyle.volumesColor); +} + +// +// END Utilities ... +// + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.alert.lib.ex5 b/MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.alert.lib.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..28d697219790e6636119a7ce89bf15c308648eb7 GIT binary patch literal 7466 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 Z0ggLoEuZ-VfcvfJ<{`brBEQ`I{|iiwN9_Or literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.alert.lib.mq5 b/MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.alert.lib.mq5 new file mode 100644 index 0000000..429d830 --- /dev/null +++ b/MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.alert.lib.mq5 @@ -0,0 +1,187 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Alert Library +// -------------------------------------- +// Name: XAlert +// Description: provides Alerts abilities ... +// +// +// 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 + +// +// START Inputs ... +// +input group "Alerts"; +input bool enableAlerts = true; // Enable Alerts +input bool logAlerts = true; // Log Alerts +input bool terminalAlerts = false; // Terminal Alerts +input bool mailAlerts = false; // Mail Alerts +input bool pushAlerts = false; // Push Alerts +// +// END Inputs ... +// + +// +#include "x-saherelm.log.lib.mq5" + +// +// START Global Definitions: Variables, Properties and etc ... +// +string alertPrefix = "X-Alert"; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// +// +// Initial Library if required ... +bool OnInInitAlertLibrary() +{ + return false; +} + +// +// DeInitial Library if required ... +void OnDeinitAlertLibrary() +{ +} + +// +// Attach Alert Prefix to Message ... +string PrepareAlertMessage(string message) +{ + // + StringReplace(message, "\n", " | "); + + // + StringConcatenate(message, alertPrefix, " > ", message); + + // + return message; +} + +// +// Logging an Alert ... +void LogAlert(string message) +{ + // + // Validate Args ... + if (!enableAlerts || !logAlerts) + { + return; + } + + // + LogMessage(alertPrefix, message); +} + +// +// Terminal Alert ... +void TerminalAlert(string message) +{ + // + // Validate Args ... + if (!enableAlerts || !terminalAlerts) + { + return; + } + + // + // Prepare Message ... + message = PrepareAlertMessage(message); + + // Send Terminal Alert ... + Alert(message); +} + +// +// Mail Alert ... +void MailAlert(string message) +{ + // + // Validate Args ... + if (!enableAlerts || !mailAlerts) + { + return; + } + + // + // Send Mail Alert ... + SendMail(alertPrefix, message); +} + +// +// Send Push Notification ... +void PushAlert(string message) +{ + // + // Validate Args ... + if (!enableAlerts || !pushAlerts) + { + return; + } + + // + // Prepare Message ... + message = PrepareAlertMessage(message); + + // + // Send Push Notification Alert ... + SendNotification(message); +} + +// +// Alert Sending ... +void SendAlert(string message) +{ + // + // Validate Args ... + if (!enableAlerts) + { + return; + } + + // + // Log ... + if (logAlerts) + { + LogAlert(message); + } + + // + // Terminal ... + if (terminalAlerts) + { + TerminalAlert(message); + } + + // + // Mail ... + if (mailAlerts) + { + MailAlert(message); + } + + // + // Push ... + if (pushAlerts) + { + PushAlert(message); + } +} +// +// END Provided Functions ... +// diff --git a/MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.common.lib.ex5 b/MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.common.lib.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..34b610c43200ba7ac18cbc7d64067219e615a577 GIT binary patch literal 6308 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 F{$B+J-{SxP literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.common.lib.mq5 b/MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.common.lib.mq5 new file mode 100644 index 0000000..aecc450 --- /dev/null +++ b/MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.common.lib.mq5 @@ -0,0 +1,5095 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Common Library +// -------------------------------------- +// Name: XCommon +// Description: provide all commonly used 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 + +// +// START Inputs ... +// + +// +// END Inputs ... +// + +// +// Include Models Library ... +#include "x-saherelm.models.lib.mq5" + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// + +// +// Detect is new Candle or not ... +bool IsNewCandle() +{ + // + bool result = false; + + // + static int barsOnChart = 0; + int currentBarsOnChart = Bars(_Symbol, _Period); + result = currentBarsOnChart > barsOnChart; + if (!result) + { + return result; + } + + // + barsOnChart = currentBarsOnChart; + result = true; + + // + return result; +} +bool IsNewCandle( + string mSymbol, // Trading Symbol ... + ENUM_TIMEFRAMES mPeriod // Trading Time Frame ... +) +{ + // + bool result = false; + + // + static string mChartTags[]; + static int mChartBars[]; + + // + string chTag = mSymbol + "," + ToString(mPeriod); + + // + int currChTagIdx = -1; + int chCountedBars = 0; + int currentBars = Bars(mSymbol, mPeriod); + + // + if (ArraySize(mChartTags) > 0) + { + // + for (int i = 0; i < ArraySize(mChartTags); i++) + { + // + string iTag = mChartTags[i]; + if (iTag != chTag) + { + continue; + } + + // + currChTagIdx = i; + break; + } + + // + if (currChTagIdx > -1) + { + chCountedBars = mChartBars[currChTagIdx]; + } + } + + // + result = currentBars > chCountedBars; + if (result) + { + // + if (currChTagIdx > -1) + { + // + mChartTags[currChTagIdx] = chTag; + mChartBars[currChTagIdx] = currentBars; + } + else + { + // + Add(chTag, mChartTags); + Add(currentBars, mChartBars); + } + } + + // + return result; +} + +// +double XNZ(double check, double val = 0) +{ + if (check == EMPTY_VALUE || check == 0) + { + return val; + } + else + { + return check; + } +} + +// +// Retrive Ask Price ... +double GetAsk() +{ + return SymbolInfoDouble(_Symbol, SYMBOL_ASK); +} +double GetAsk( + string symbol // selected symbol for calculations +) +{ + // + double result = SymbolInfoDouble(symbol, SYMBOL_ASK); + + // + return result; +} + +// +// Retrieve Bid Price ... +double GetBid() +{ + return SymbolInfoDouble(_Symbol, SYMBOL_BID); +} +double GetBid( + string symbol // selected symbol for calculations +) +{ + // + double result = SymbolInfoDouble(symbol, SYMBOL_BID); + + // + return result; +} + +// +// Calculate and Retrieve Spread Price ... +double GetSpread() +{ + // + double ask = GetAsk(); + double bid = GetBid(); + double result = MathAbs(ask - bid); + + // + return result; +} +double GetSpread( + string symbol // selected symbol for calculations +) +{ + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + double result = MathAbs(ask - bid); + + // + return result; +} + +// +// Get Points ... +double GetPoints() +{ + return _Point; +} +double GetPoints( + string symbol // selected symbol for calculations +) +{ + // + double result = SymbolInfoDouble(symbol, SYMBOL_POINT); + + // + return result; +} + +// +// Get Digits ... +int GetDigits() +{ + return _Digits; +} +int GetDigits( + string symbol // selected symbol for calculations +) +{ + // + int result = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS); + + // + return result; +} + +// +// Get Signal Entry ... +double GetEntry( + ENUM_POSITION_TYPE type // Get entry price for Which direction trade ... +) +{ + // + double result = 0; + + // + bool isLong = type == POSITION_TYPE_BUY; + result = isLong ? GetAsk() : GetBid(); + result = NormalizePrice(result); + + // + return result; +} +double GetEntry( + string symbol, // Specified Symbol + ENUM_POSITION_TYPE type // Get entry price for Which direction trade ... +) +{ + // + double result = 0; + + // + bool isLong = type == POSITION_TYPE_BUY; + result = isLong ? GetAsk(symbol) : GetBid(symbol); + result = NormalizePrice(result, symbol); + + // + return result; +} + +// +// Get Signal Exit ... +double GetExit( + ENUM_POSITION_TYPE type // Get entry price for Which direction trade ... +) +{ + // + double result = 0; + + // + bool isLong = type == POSITION_TYPE_BUY; + result = isLong ? GetBid() : GetAsk(); + result = NormalizePrice(result); + + // + return result; +} +double GetExit( + string symbol, // Specified Symbol + ENUM_POSITION_TYPE type // Get entry price for Which direction trade ... +) +{ + // + double result = 0; + + // + bool isLong = type == POSITION_TYPE_BUY; + result = isLong ? GetBid(symbol) : GetAsk(symbol); + result = NormalizePrice(result, symbol); + + // + return result; +} + +// +// Determine a Position type is Long or not ... +bool IsLong(ENUM_POSITION_TYPE type) +{ + // + bool result = type == POSITION_TYPE_BUY; + + // + return result; +} +bool IsLong(ENUM_ORDER_TYPE type) +{ + // + bool result = type == ORDER_TYPE_BUY; + + // + return result; +} + +// +// Determine a Position type is Short or not ... +bool IsShort(ENUM_POSITION_TYPE type) +{ + // + bool result = type == POSITION_TYPE_SELL; + + // + return result; +} +bool IsShort(ENUM_ORDER_TYPE type) +{ + // + bool result = type == ORDER_TYPE_SELL; + + // + return result; +} + +// +// Get 1 Pip in Price Value ... +double GetPipPrice() +{ + // + double result = _Point; + if (_Digits == 3 || _Digits == 5) + { + result *= 10; + } + + // + return result; +} +double GetPipPrice( + string symbol // selected symbol for calculations +) +{ + // + double symbolPoint = GetPoints(symbol); + int symbolDigits = GetDigits(symbol); + + // + double result = symbolPoint; + if (symbolDigits == 3 || symbolDigits == 5) + { + result *= 10; + } + + // + return result; +} + +// +// Converts Pips To Price ... +double PipsToPrice( + int pips // pips amount +) +{ + // + int digits = GetDigits(); + double pipValue = GetPipPrice(); + double result = pips * pipValue; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} +double PipsToPrice( + double pips // pips amount +) +{ + // + int digits = GetDigits(); + double pipValue = GetPipPrice(); + double result = pips * pipValue; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} +double PipsToPrice( + string symbol, // selected symbol for calculation + int pips // pips amount +) +{ + // + int digits = GetDigits(symbol); + double pipValue = GetPipPrice(symbol); + double result = pips * pipValue; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} +double PipsToPrice( + string symbol, // selected symbol for calculation + double pips // pips amount +) +{ + // + int digits = GetDigits(symbol); + double pipValue = GetPipPrice(symbol); + double result = pips * pipValue; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} + +// +// Converts Price to Pips ... +double PriceToPips( + double price // the price amount which required to calculate +) +{ + // + int digits = GetDigits(); + double pipPrice = GetPipPrice(); + + // + double result = price / pipPrice; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} +double PriceToPips( + string symbol, // Selected Symbol + double price // the price amount which required to calculate +) +{ + // + int digits = GetDigits(symbol); + double pipPrice = GetPipPrice(symbol); + + // + double result = price / pipPrice; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} + +// +// Convert Price to Point ... +double PriceToPoint( + double price // the price amount which required to calculate +) +{ + return PriceToPoint(_Symbol, price); +} +double PriceToPoint( + string symbol, // Selected Symbol + double price // the price amount which required to calculate +) +{ + // + double result = 0; + + // + double point = GetPoints(symbol); + result = price / point; + + // + return result; +} + +// +// Converts Point to Price ... +double PointToPrice( + double points // Points Size +) +{ + return PointToPrice(_Symbol, points); +} +double PointToPrice( + string symbol, // Selected Symbol + double points // Points Size +) +{ + // + double result = 0; + + // + double point = GetPoints(symbol); + result = points * point; + + // + return result; +} + +// +// CANDLES ... + +// +// Validate Candle ... +bool IsValid( + XOHCL &candle // specified candle +) +{ + // + bool result = false; + + // + result = + // + candle.open > 0 && + candle.close > 0 && + candle.high > 0 && + candle.low > 0 + // + ; + + // + return result; +} + +// +// Get a Candle Body ... +double GetCandleBody( + XOHCL &candle // specified candle +) +{ + // + double result = 0; + + // + bool isValid = IsValid(candle); + if (!isValid) + { + return result; + } + + // + result = MathAbs(candle.open - candle.close); + + // + return result; +} + +// +// Get a Candle Range ... +double GetCandleRange( + XOHCL &candle // specified candle +) +{ + // + double result = 0; + + // + bool isValid = IsValid(candle); + if (!isValid) + { + return result; + } + + // + result = MathAbs(candle.high - candle.low); + + // + return result; +} + +// +// Get a Candle Shadow ... +double GetCandleShadow( + XOHCL &candle // specified candle +) +{ + // + double result = 0; + + // + bool isValid = IsValid(candle); + if (!isValid) + { + return 0; + } + + // + double range = GetCandleRange(candle); + double body = GetCandleBody(candle); + + // + result = MathAbs(range - body); + + // + return result; +} + +// +// Retrieve High Shadow of Candle ... +double GetCandleHighShadow( + XOHCL &candle // specified candle +) +{ + // + double result = 0; + + // + bool isValid = IsValid(candle); + if (!isValid) + { + return result; + } + + // + double upPrice = MathMax(candle.open, candle.close); + + // + result = candle.high - upPrice; + + // + return result; +} + +// +// Retrieve Low Shadow of Candle ... +double GetCandleLowShadow( + XOHCL &candle // specified candle +) +{ + // + double result = 0; + + // + bool isValid = IsValid(candle); + if (!isValid) + { + return result; + } + + // + double downPrice = MathMin(candle.open, candle.close); + + // + result = downPrice - candle.low; + + // + return result; +} + +// +// Check a Candle is Base Candle for RTM or not ... +bool IsBaseCandle( + XOHCL &candle // specified candle +) +{ + // + double range = GetCandleRange(candle); + double body = GetCandleBody(candle); + + // + bool result = body > range; + + // + return result; +} + +// +// Check Candle Body Bigger Than it's Shadow ... +bool CandleHasStrongBody(XOHCL &candle) +{ + // + double bodySize = MathAbs(candle.open - candle.close); + double shadowSize = MathAbs(candle.high - candle.low) - bodySize; + + // + bool result = bodySize > (shadowSize * 1.5); + + // + return result; +} + +// +// Detect Doji Candle ... +bool IsDojiCandle( + XOHCL &candle, // Specified Candle + double detectFactor = 0.05 // Detect Factor +) +{ + // + bool result = false; + + // + bool isValid = IsValid(candle); + if ( + !isValid || + detectFactor <= 0 || + detectFactor > 1) + { + return result; + } + + // + // Retrieve Candle Parts ... + double body = GetCandleBody(candle); + double range = GetCandleRange(candle); + double shadows = GetCandleShadow(candle); + + // + // Calculate Candle Rate ... + double factor = range * detectFactor; + double shadowFactor = (1 - detectFactor) * range; + + // + result = + // + body > 0 && + range > 0 && + factor > 0 && + shadows > 0 && + body <= factor && + shadowFactor > 0 && + shadows >= shadowFactor + // + ; + + // + return result; +} + +// +// Detect Shadows of Specific Candles must be same .. +bool IsCrossShadowCandle( + XOHCL &candle, // Specified Candle + double smoothingFactor = 0.05 // Smoothing Factor +) +{ + // + bool result = false; + + // + bool isValid = IsValid(candle); + if (!isValid || + smoothingFactor <= 0 || + smoothingFactor >= 1) + { + return result; + } + + // + // Retrieve Candle Parts ... + double body = GetCandleBody(candle); + double range = GetCandleRange(candle); + double shadows = GetCandleShadow(candle); + + // + double upBody = MathMax(candle.open, candle.close); + double downBody = MathMin(candle.open, candle.close); + + // + double upShadow = candle.high - upBody; + double downShadow = downBody - candle.low; + + // + // Calculate Candle Rate ... + double factor = range * smoothingFactor; + + // + result = + upShadow > 0 && + downShadow > 0 && + body > 0 && + range > 0 && + shadows > 0 && + ((upShadow == downShadow) || + MathAbs(upShadow - downShadow) <= factor); + + // + return result; +} + +// +// Detect a Candle Shadow Hunt Specific price or not ... +bool IsShadowHuntCandle( + XOHCL &candle, // Specified Candle + double price // Specified Price +) +{ + // + bool result = false; + + // + // Validate Args ... + bool isValid = IsValid(candle); + if (!isValid || price <= 0) + { + return result; + } + + // + double upBody = MathMax(candle.open, candle.close); + double downBody = MathMin(candle.open, candle.close); + + // + double hShadow = GetCandleHighShadow(candle); + double lShadow = GetCandleLowShadow(candle); + + // + double range = GetCandleRange(candle); + double factor = range * 0.3; + + // + bool isStrongHShadow = hShadow >= factor; + bool isStrongLShadow = lShadow >= factor; + + // + bool isPriceUp = + price >= candle.high || + price >= upBody; + + // + result = + // + isPriceUp + // + ? + // + isStrongHShadow && + (price == candle.high || + (price > upBody && price < candle.high)) + // + : + // + isStrongLShadow && + (price == candle.low || + (price < downBody && price > candle.low)) + // + ; + + // + return result; +} + +// +// Check a Candle is Bullish or not ... +bool IsBullishCandle( + XOHCL &candle // specified candle +) +{ + // + bool result = false; + + // + bool isValid = IsValid(candle); + if (!isValid) + { + return result; + } + + // + result = candle.open < candle.close; + + // + return result; +} +bool IsBullishCandle( + int bar_index // candle index +) +{ + // + bool result = false; + + // + XOHCL candle = GetCandle(bar_index); + + // + result = IsBullishCandle(candle); + + // + return result; +} +bool IsBullishCandle( + string symbol, // specify symbol + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // candle index +) +{ + // + bool result = false; + + // + XOHCL candle = GetCandle( + symbol, + mPeriod, + bar_index); + + // + result = IsBullishCandle(candle); + + // + return result; +} + +// +// Check a Candle is Bullish or not ... +bool IsBearishCandle( + XOHCL &candle // specified candle +) +{ + // + bool result = false; + + // + bool isValid = IsValid(candle); + if (!isValid) + { + return result; + } + + // + result = candle.open > candle.close; + + // + return result; +} +bool IsBearishCandle( + int bar_index // candle index +) +{ + // + bool result = false; + + // + XOHCL candle = GetCandle(bar_index); + + // + result = IsBearishCandle(candle); + + // + return result; +} +bool IsBearishCandle( + string symbol, // specify symbol + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // candle index +) +{ + // + bool result = false; + + // + XOHCL candle = GetCandle( + symbol, + mPeriod, + bar_index); + + // + result = IsBearishCandle(candle); + + // + return result; +} + +// +// Retrieve Applied Price at Specific Candle ... +double GetAppliedPrice( + XOHCL &candle, // specified candle + ENUM_APPLIED_PRICE source = PRICE_CLOSE // specified Applied To +) +{ + // + double result = EMPTY_VALUE; + + // + switch (source) + { + // + // Open ... + case PRICE_OPEN: + result = candle.open; + break; + + // + // High ... + case PRICE_HIGH: + result = candle.high; + break; + + // + // Low ... + case PRICE_LOW: + result = candle.low; + break; + + // + // Median ((High + Low) / 2) ... + case PRICE_MEDIAN: + result = (candle.high + candle.low) / 2; + break; + + // + // Typical ((High + Low + Close)/3) ... + case PRICE_TYPICAL: + result = (candle.high + candle.low + candle.close) / 3; + break; + + // + // Weighted ((High + Low + Close + Close)/4) ... + case PRICE_WEIGHTED: + result = (candle.high + candle.low + (candle.close * 2)) / 4; + break; + + // + // Close ... + default: + case PRICE_CLOSE: + result = candle.close; + break; + } + + // + return result; +} +double GetAppliedPrice( + int bar_index, // specify candle index + ENUM_APPLIED_PRICE source = PRICE_CLOSE // specified Applied To +) +{ + // + double result = EMPTY_VALUE; + + // + XOHCL candle = GetCandle(bar_index); + result = GetAppliedPrice(candle, source); + + // + return result; +} +double GetAppliedPrice( + int bar_index, // specify candle index + ENUM_SERIESMODE mode // converts Series Mode to Applied Price ... +) +{ + // + double result = 0; + + // + ENUM_APPLIED_PRICE mAppliedTo = To(mode); + result = GetAppliedPrice( + bar_index, + mAppliedTo); + + // + return result; +} + +// +template +double GetAppliedPrice(ENUM_APPLIED_PRICE tprice, T &open[], T &high[], T &low[], T &close[], int i) +{ + switch (tprice) + { + case PRICE_CLOSE: + return (close[i]); + case PRICE_OPEN: + return (open[i]); + case PRICE_HIGH: + return (high[i]); + case PRICE_LOW: + return (low[i]); + case PRICE_MEDIAN: + return ((high[i] + low[i]) / 2.0); + case PRICE_TYPICAL: + return ((high[i] + low[i] + close[i]) / 3.0); + case PRICE_WEIGHTED: + return ((high[i] + low[i] + close[i] + close[i]) / 4.0); + } + return (0); +} + +// +// Converts ... +ENUM_APPLIED_PRICE To( + ENUM_SERIESMODE mode // converts Series Mode to Applied Price ... +) +{ + // + ENUM_APPLIED_PRICE result = PRICE_CLOSE; + + // + switch (mode) + { + // + // High ... + case MODE_HIGH: + result = PRICE_HIGH; + break; + + // + // Open ... + case MODE_OPEN: + result = PRICE_OPEN; + break; + + // + // Low ... + case MODE_LOW: + result = PRICE_LOW; + break; + + // + // Close ... + // Default ... + case MODE_CLOSE: + default: + result = PRICE_CLOSE; + break; + } + + // + return result; +} + +// +// Retrieve a Candel Data ... +XOHCL GetCandle(int bar_index) +{ + // + XOHCL result = {}; + + // + double open = iOpen(_Symbol, _Period, bar_index); + double high = iHigh(_Symbol, _Period, bar_index); + double close = iClose(_Symbol, _Period, bar_index); + double low = iLow(_Symbol, _Period, bar_index); + + // + result.low = low; + result.open = open; + result.high = high; + result.close = close; + + // + return result; +} +XOHCL GetCandle( + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // specify candle index +) +{ + // + XOHCL result = {}; + + // + double open = iOpen(_Symbol, mPeriod, bar_index); + double high = iHigh(_Symbol, mPeriod, bar_index); + double close = iClose(_Symbol, mPeriod, bar_index); + double low = iLow(_Symbol, mPeriod, bar_index); + + // + result.low = low; + result.open = open; + result.high = high; + result.close = close; + + // + return result; +} +XOHCL GetCandle( + string symbol, // specify symbol + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // specify candle index +) +{ + // + XOHCL result = {}; + + // + double open = iOpen(symbol, mPeriod, bar_index); + double high = iHigh(symbol, mPeriod, bar_index); + double close = iClose(symbol, mPeriod, bar_index); + double low = iLow(symbol, mPeriod, bar_index); + + // + result.low = low; + result.open = open; + result.high = high; + result.close = close; + + // + return result; +} + +// +// Get a Series Of Candles ... +bool GetCandles( + XOHCL &result[], // Hold Result ... + string mSymbol = NULL, // Specified Symbol ... + ENUM_TIMEFRAMES mPeriod = NULL, // Specified Period ... + int mStart = 0, // Start Bar Index ... + int mCount = 1 // Specified Number of Candles ... +) +{ + // + bool mResult = false; + + // + if (mStart < 0) + { + mStart = 0; + } + + // + if (mCount <= 0) + { + mCount = 1; + } + + // + Clean(result); + + // + for (int i = mStart; i < mStart + mCount; i++) + { + // + XOHCL iC = GetCandle( + mSymbol, + mPeriod, + i); + + // + Add( + iC, + result); + } + + // + mResult = ArraySize(result) > 0; + + // + return mResult; +} + +// +// Retrieve a candle index in current timeframe inside another timeframe ... +int GetCandleBarIndex( + int bar_index, // Specify Candle index in current timeframe + ENUM_TIMEFRAMES destPeriod // Specify destination timeframe +) +{ + // + int result = -1; + + // + datetime barTime = iTime(_Symbol, _Period, bar_index); + result = iBarShift(_Symbol, destPeriod, barTime); + + // + return result; +} + +// +// Retrieve a symbol candle index in source time frame inside dest timeframe ... +int GetCandleBarIndex( + int bar_index, // Specify Candle index in current timeframe + string symbol, // Specify desired Symbol + ENUM_TIMEFRAMES sourcePeriod, // Specify bar_index timeframe + ENUM_TIMEFRAMES destPeriod // Specify destination timeframe +) +{ + // + int result = -1; + + // + datetime barTime = iTime(symbol, sourcePeriod, bar_index); + result = iBarShift(symbol, destPeriod, barTime); + + // + return result; +} + +// +// Determines a cnadle is Swing High +// or Swing Low order block ... +ENUM_X_SWING_TYPE GetCandleSwing(int bar_index) +{ + // + ENUM_X_SWING_TYPE result = X_NO_SWING; + + // + // Reading Candle Models ... + XOHCL candles[3]; + candles[0] = GetCandle(bar_index + 1); + candles[1] = GetCandle(bar_index + 2); + candles[2] = GetCandle(bar_index + 3); + + // + // Check Swing Start Candle has Strong Body ... + bool isStrongBodyCandle = CandleHasStrongBody(candles[2]); + if (!isStrongBodyCandle) + { + return result; + } + + // + // Check Swing Low Conditions ... + bool isSwingLowOrderBlock = + candles[2].low < candles[1].low && + candles[1].low < candles[0].low && + candles[2].low < candles[0].low; + if (isSwingLowOrderBlock) + { + result = X_SWING_LOW; + } + + // + // Check Swing High Conditions ... + bool isSwingHighOrderBlock = + candles[2].high > candles[1].high && + candles[1].high > candles[0].high && + candles[2].high > candles[0].high; + if (isSwingHighOrderBlock) + { + result = X_SWING_HIGH; + } + + // + return result; +} +ENUM_X_SWING_TYPE GetCandleSwing( + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // specify candle index +) +{ + // + ENUM_X_SWING_TYPE result = X_NO_SWING; + + // + // Reading Candle Models ... + XOHCL candles[3]; + candles[0] = GetCandle(mPeriod, bar_index + 1); + candles[1] = GetCandle(mPeriod, bar_index + 2); + candles[2] = GetCandle(mPeriod, bar_index + 3); + + // + // Check Swing Start Candle has Strong Body ... + bool isStrongBodyCandle = CandleHasStrongBody(candles[2]); + if (!isStrongBodyCandle) + { + return result; + } + + // + // Check Swing Low Conditions ... + bool isSwingLowOrderBlock = + candles[2].low < candles[1].low && + candles[1].low < candles[0].low && + candles[2].low < candles[0].low; + if (isSwingLowOrderBlock) + { + result = X_SWING_LOW; + } + + // + // Check Swing High Conditions ... + bool isSwingHighOrderBlock = + candles[2].high > candles[1].high && + candles[1].high > candles[0].high && + candles[2].high > candles[0].high; + if (isSwingHighOrderBlock) + { + result = X_SWING_HIGH; + } + + // + return result; +} +ENUM_X_SWING_TYPE GetCandleSwing( + string symbol, // specify symbol + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // specify candle index +) +{ + // + ENUM_X_SWING_TYPE result = X_NO_SWING; + + // + // Reading Candle Models ... + XOHCL candles[3]; + candles[0] = GetCandle(symbol, mPeriod, bar_index + 1); + candles[1] = GetCandle(symbol, mPeriod, bar_index + 2); + candles[2] = GetCandle(symbol, mPeriod, bar_index + 3); + + // + // Check Swing Start Candle has Strong Body ... + bool isStrongBodyCandle = CandleHasStrongBody(candles[2]); + if (!isStrongBodyCandle) + { + return result; + } + + // + // Check Swing Low Conditions ... + bool isSwingLowOrderBlock = + candles[2].low < candles[1].low && + candles[1].low < candles[0].low && + candles[2].low < candles[0].low; + if (isSwingLowOrderBlock) + { + result = X_SWING_LOW; + } + + // + // Check Swing High Conditions ... + bool isSwingHighOrderBlock = + candles[2].high > candles[1].high && + candles[1].high > candles[0].high && + candles[2].high > candles[0].high; + if (isSwingHighOrderBlock) + { + result = X_SWING_HIGH; + } + + // + return result; +} + +// +// Find Swing Points ... +int FindSwing( + string mSymbol, // Trading Symbol ... + ENUM_TIMEFRAMES mPeriod, // Trading Period ... + ENUM_SERIESMODE mode, // Swing Based On Price mode ... + int mLength, // Loopback ... + int bar_index // BarIndex ... +) +{ + // + int result = -1; + + // + if (StringLen(mSymbol) == 0 || (mode != MODE_HIGH && mode != MODE_LOW)) + { + return result; + } + + // + int current = bar_index; + int founded = FindNextSwing( + mSymbol, + mPeriod, + mode, + (mLength * 2) + 1, + current - mLength); + + // + while (founded != current) + { + // + current = FindNextSwing( + mSymbol, + mPeriod, + mode, + mLength, + current + 1); + + // + founded = FindNextSwing( + mSymbol, + mPeriod, + mode, + (mLength * 2) + 1, + current - mLength); + } + + // + result = current; + + // + return result; +} + +// +// Find Next Swing ... +int FindNextSwing( + string mSymbol, // Trading Symbol ... + ENUM_TIMEFRAMES mPeriod, // Trading Period ... + ENUM_SERIESMODE mode, // Swing Based On Price mode ... + int mLength, // Loopback ... + int bar_index // BarIndex ... +) +{ + // + int result = -1; + + // + if (bar_index < 0) + { + mLength += bar_index; + bar_index = 0; + } + + // + result = mode == MODE_HIGH + ? iHighest( + mSymbol, + mPeriod, + mode, + mLength, + bar_index) + : iLowest( + mSymbol, + mPeriod, + mode, + mLength, + bar_index); + + // + return result; +} + +// +// Retrieve Market Highest High ... +double GetHighestHigh( + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iHighest( + _Symbol, + _Period, + MODE_HIGH, + mLength, + bar_index); + + // + result = iHigh( + _Symbol, + _Period, + rIdx); + + // + return result; +} +double GetHighestHigh( + int mLength, // Which market Length use + int bar_index, // bar index + ENUM_SERIESMODE mode // Calculation mode +) +{ + // + double result = -1; + + // + int rIdx = iHighest( + _Symbol, + _Period, + mode, + mLength, + bar_index); + + // + result = iHigh( + _Symbol, + _Period, + rIdx); + + // + return result; +} +double GetHighestHigh( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES mPeriod, // Specified Period + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iHighest( + symbol, + mPeriod, + MODE_HIGH, + mLength, + bar_index); + + // + result = iHigh( + symbol, + mPeriod, + rIdx); + + // + return result; +} +double GetHighestHigh( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES mPeriod, // Specified Period + ENUM_SERIESMODE mode, // Calculation mode + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iHighest( + symbol, + mPeriod, + mode, + mLength, + bar_index); + + // + result = iHigh( + symbol, + mPeriod, + rIdx); + + // + return result; +} + +// +// Retrieve Market Lowest Low ... +double GetLowestLow( + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iLowest( + _Symbol, + _Period, + MODE_LOW, + mLength, + bar_index); + + // + result = iLow( + _Symbol, + _Period, + rIdx); + + // + return result; +} +double GetLowestLow( + int mLength, // Which market Length use + int bar_index, // bar index + ENUM_SERIESMODE mode // Calculation mode +) +{ + // + double result = -1; + + // + int rIdx = iLowest( + _Symbol, + _Period, + mode, + mLength, + bar_index); + + // + result = iLow( + _Symbol, + _Period, + rIdx); + + // + return result; +} +double GetLowestLow( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES mPeriod, // Specified Period + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iLowest( + symbol, + mPeriod, + MODE_LOW, + mLength, + bar_index); + + // + result = iLow( + symbol, + mPeriod, + rIdx); + + // + return result; +} +double GetLowestLow( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES mPeriod, // Specified Period + ENUM_SERIESMODE mode, // Calculation mode + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iLowest( + symbol, + mPeriod, + mode, + mLength, + bar_index); + + // + result = iLow( + symbol, + mPeriod, + rIdx); + + // + return result; +} + +// +// Find Support and Resistance for Specific Bar based on provided Buffer ... +XOHCLSupRes ExtractSupportAndResistance( + int barIndex, // Bar Index ... + const double &pivots[], // Provided Pivot Points ... + int count = 3, // Number of Requireds ... + string mSymbol = NULL, // Trading Symbol ... + ENUM_TIMEFRAMES mPeriod = NULL // Trading Period ... +) +{ + // + if (StringLen(mSymbol) == 0 || mSymbol == NULL) + { + mSymbol = _Symbol; + } + + // + if (mPeriod == NULL) + { + mPeriod = _Period; + } + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + XOHCLSupRes result; + Clean(result.res); + Clean(result.sup); + + // + int pivotsCount = ArraySize(pivots); + if (pivotsCount <= 0) + { + return result; + } + + // + if (count <= 0 || + count > pivotsCount - 1) + { + return result; + } + + // + XOHCL cBar = GetCandle( + mSymbol, + mPeriod, + barIndex); + + // + double tmpR[]; + + // + double tmpS[]; + + // + // Extract Supports ... + // which prices is under low of candle ... + // + // Extract Resistance ... + // which prices is over high of candle ... + for (int i = 0; i < pivotsCount; i++) + { + // + double iFlat = pivots[i]; + + // + if (iFlat > cBar.high) + { + Add( + iFlat, + tmpR); + } + else if (iFlat < cBar.low) + { + Add( + iFlat, + tmpS); + } + } + + // + // Sorting Founded Resistance and Supports ... + + // + // Since Resistance Levels must be Increasing ... + ArraySort(tmpR); + + // + // Since Support Levels must be Decreasing ... + ArraySort(tmpS); + ArrayReverse(tmpS); + + // + // Fill Resistance ... + int tmpRCount = ArraySize(tmpR); + if (tmpRCount > 0) + { + // + if (tmpRCount < count) + { + // + ArrayCopy( + result.res, + tmpR); + } + else + { + // + ArrayCopy( + result.res, + tmpR, + 0, + 0, + count); + } + } + + // + // Fill Supports ... + int tmpSCount = ArraySize(tmpS); + if (tmpSCount > 0) + { + // + if (tmpSCount < count) + { + // + ArrayCopy( + result.sup, + tmpS); + } + else + { + // + ArrayCopy( + result.sup, + tmpS, + 0, + 0, + count); + } + } + + // + return result; +} + +// +// Find Support and Resistance for Specific Price based on provided Buffer ... +XOHCLSupRes ExtractSupportAndResistance( + double price, // Price ... + const double &pivots[], // Provided Pivot Points ... + int count = 3 // Number of Requireds ... +) +{ + // + XOHCLSupRes result; + Clean(result.res); + Clean(result.sup); + + // + if (price <= 0) + { + return result; + } + + // + int pivotsCount = ArraySize(pivots); + if (pivotsCount <= 0) + { + return result; + } + + // + if (count <= 0 || + count > pivotsCount - 1) + { + return result; + } + + // + double tmpR[]; + + // + double tmpS[]; + + // + // Extract Supports ... + // which prices is under low of candle ... + // + // Extract Resistance ... + // which prices is over high of candle ... + for (int i = 0; i < pivotsCount; i++) + { + // + double iFlat = pivots[i]; + + // + if (iFlat > price) + { + Add( + iFlat, + tmpR); + } + else if (iFlat < price) + { + Add( + iFlat, + tmpS); + } + } + + // + // Sorting Founded Resistance and Supports ... + + // + // Since Resistance Levels must be Increasing ... + ArraySort(tmpR); + + // + // Since Support Levels must be Decreasing ... + ArraySort(tmpS); + ArrayReverse(tmpS); + + // + // Fill Resistance ... + int tmpRCount = ArraySize(tmpR); + if (tmpRCount > 0) + { + // + if (tmpRCount < count) + { + // + ArrayCopy( + result.res, + tmpR); + } + else + { + // + ArrayCopy( + result.res, + tmpR, + 0, + 0, + count); + } + } + + // + // Fill Supports ... + int tmpSCount = ArraySize(tmpS); + if (tmpSCount > 0) + { + // + if (tmpSCount < count) + { + // + ArrayCopy( + result.sup, + tmpS); + } + else + { + // + ArrayCopy( + result.sup, + tmpS, + 0, + 0, + count); + } + } + + // + return result; +} + +// +// Find a Value less than Specified ... +double FindLesserThanValue( + double value, // Specified Value ... + const double &source[], // Source ... + bool isDescend = false // Find Biggest Lesser Value ... +) +{ + // + double result = -1; + + // + int itemsCount = ArraySize(source); + if (itemsCount <= 0) + { + return result; + } + + // + // Make a Copy of source ... + double tmp[]; + + // + ArrayResize( + tmp, + ArraySize(source)); + + // + ArrayCopy( + tmp, + source); + + // + // Sort Temp Buffer ... + ArraySort(tmp); + if (isDescend) + { + ArrayReverse(tmp); + } + + // + int tmpCount = ArraySize(tmp); + for (int i = 0; i < tmpCount; i++) + { + // + double iValue = tmp[i]; + + // + if (iValue < value) + { + // + result = iValue; + break; + } + } + + // + return result; +} + +// +// Find a Value less than Specified ... +double FindBiggerThanValue( + double value, // Specified Value ... + const double &source[], // Source ... + bool isDescend = false // Find Smallest Bigger Value ... +) +{ + // + double result = -1; + + // + int itemsCount = ArraySize(source); + if (itemsCount <= 0) + { + return result; + } + + // + // Make a Copy of source ... + double tmp[]; + + // + ArrayResize( + tmp, + ArraySize(source)); + + // + ArrayCopy( + tmp, + source); + + // + // Sort Temp Buffer ... + ArraySort(tmp); + if (!isDescend) + { + ArrayReverse(tmp); + } + + // + int tmpCount = ArraySize(tmp); + for (int i = 0; i < tmpCount; i++) + { + // + double iValue = tmp[i]; + + // + if (iValue > value) + { + // + result = iValue; + break; + } + } + + // + return result; +} + +// +// Calculate Fib Level ... +double GetFibonacciLevel( + double upPrice, + double downPrice, + double level, + int direction) +{ + // + double ling = upPrice - downPrice; + double pLevel = (ling / 100) * (level * 100); + + // + double result = direction > 0 ? upPrice - pLevel : downPrice + pLevel; + result = NormalizeDouble(result, _Digits); + + // + return result; +} + +// +// Check first Cross Over second at bar_index ... +bool IsCrossOver( + const double &first[], // the buffer which check crossing over second buffer + const double &second[], // first buffer checks based on this buffer + const int bar_index // check crosses in specific index +) +{ + // + bool result = false; + + // + ArraySetAsSeries(first, true); + ArraySetAsSeries(second, true); + + // + // Validate Args ... + if (ArraySize(first) < bar_index + 1 || ArraySize(second) < bar_index + 1) + { + return result; + } + + // + result = first[bar_index] > second[bar_index] && + !(first[bar_index + 1] > second[bar_index + 1]); + + // + return result; +} + +// +// Check first is Over second at bar_index ... +bool IsOver( + const double &first[], // the buffer which check over second buffer + const double &second[], // first buffer checks based on this buffer + const int bar_index // check crosses in specific index +) +{ + // + bool result = false; + + // + ArraySetAsSeries(first, true); + ArraySetAsSeries(second, true); + + // + // Validate Args ... + if (ArraySize(first) < bar_index + 1 || ArraySize(second) < bar_index + 1) + { + return result; + } + + // + result = first[bar_index] > second[bar_index] && + first[bar_index + 1] > second[bar_index + 1]; + + // + return result; +} + +// +// Check first Cross Under second at bar_index ... +bool IsCrossUnder( + const double &first[], // the buffer which check crossing under second buffer + const double &second[], // first buffer checks based on this buffer + const int bar_index // check crosses in specific index +) +{ + // + bool result = false; + + // + ArraySetAsSeries(first, true); + ArraySetAsSeries(second, true); + + // + // Validate Args ... + if (ArraySize(first) < bar_index + 1 || ArraySize(second) < bar_index + 1) + { + return result; + } + + // + result = first[bar_index] < second[bar_index] && + !(first[bar_index + 1] < second[bar_index + 1]); + + // + return result; +} + +// +// Check first is Under second at bar_index ... +bool IsUnder( + const double &first[], // the buffer which check under second buffer + const double &second[], // first buffer checks based on this buffer + const int bar_index // check crosses in specific index +) +{ + // + bool result = false; + + // + ArraySetAsSeries(first, true); + ArraySetAsSeries(second, true); + + // + // Validate Args ... + if (ArraySize(first) < bar_index + 1 || ArraySize(second) < bar_index + 1) + { + return result; + } + + // + result = first[bar_index] < second[bar_index] && + first[bar_index + 1] < second[bar_index + 1]; + + // + return result; +} + +// +// Calculate Slope of Specified Buffer at Specified Index ... +double GetSlope( + int from, // In Past Index ... + int to, // In Past Index ... + double &buffer[]) +{ + // + double result = 0; + + // + double toValue = buffer[to]; + double fromValue = buffer[from]; + double deltaValue = toValue - fromValue; + double deltaTime = from - to; + + // + result = deltaValue / deltaTime; + + // + return result; +} + +// +// Check if a Value Increasing in Loopback ... +bool IsIncreasing( + int from, // Last Time Index + int to, // Fisr Tima Index + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + from <= to || + ArraySize(buffer) < from + 1) + { + return result; + } + + // + // Loop through Items ... + double toValue = buffer[to]; + double fromValue = buffer[from]; + result = toValue > fromValue; + for (int i = to + 1; i <= from - 1; i++) + { + // + double iValue = buffer[i]; + bool isPassed = toValue >= iValue; + + // + bool isIIncreasing = IsIncreasing( + from, + i, + buffer); + + // + // Check Result ... + result = result && isPassed && isIIncreasing; + if (!result) + { + break; + } + } + + // + return result; +} + +// +// Check if a Value Decreasing in Loopback ... +bool IsDecreasing( + int from, // Last Time Index + int to, // Fisr Tima Index + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + from <= to || + ArraySize(buffer) < from + 1) + { + return result; + } + + // + // Loop through Items ... + double toValue = buffer[to]; + double fromValue = buffer[from]; + result = toValue < fromValue; + for (int i = to + 1; i <= from - 1; i++) + { + // + double iValue = buffer[i]; + bool isPassed = toValue <= iValue; + + // + bool isIDecreasing = IsDecreasing( + from, + i, + buffer); + + // + // Check Result ... + result = result && isPassed && isIDecreasing; + if (!result) + { + break; + } + } + + // + return result; +} + +// +// Get Max Value of Specific Loopback of a Buffer ... +double GetMaxValue( + int mLoopback, // loopback length + double &buffer[] // the Buffer which required to search +) +{ + // + double result = 0; + + // + // Validate Args ... + if ( + mLoopback < 2 || + ArraySize(buffer) < mLoopback) + { + return result; + } + + // + // Loop Through LoopBack ... + for (int i = 0; i < mLoopback; i++) + { + // + double iValue = buffer[i]; + + // + result = + // + result == 0 || result < iValue + // + ? iValue + // + : result + // + ; + } + + // + return result; +} + +// +// Get Min Value of Specific Loopback of a Buffer ... +double GetMinValue( + int mLoopback, // loopback length + double &buffer[] // the Buffer which required to search +) +{ + // + double result = 0; + + // + // Validate Args ... + if ( + mLoopback < 2 || + ArraySize(buffer) < mLoopback) + { + return result; + } + + // + // Loop Through LoopBack ... + for (int i = 0; i < mLoopback; i++) + { + // + double iValue = buffer[i]; + + // + result = + // + result == 0 || result > iValue + // + ? iValue + // + : result + // + ; + } + + // + return result; +} + +// +// Find Same Values in Array ... +void FindSameValueInBuffer( + double &result[], // Holds Result ... + double &source[], // Source ... + int verifications = 3 // Number of Consequence Repeat ... +) +{ + // + Clean(result); + + // + // TenkanSen Flats ... + int sourceCount = ArraySize(source); + if (sourceCount > verifications) + { + // + double mLast = 0; + int mVerified = 0; + for (int i = 0; i < sourceCount; i++) + { + // + double iVal = source[i]; + if (mLast == 0) + { + mLast = iVal; + } + else if (mLast == iVal) + { + mVerified++; + } + else + { + mLast = iVal; + mVerified = 0; + } + + // + if (iVal == mLast && mVerified >= verifications) + { + // + Add( + iVal, + result); + + // + mLast = 0; + mVerified = 0; + } + } + } +} + +// +bool IsInPeak( + int mLoopback, // loopback length + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + mLoopback < 2 || + ArraySize(buffer) < mLoopback + 1) + { + return result; + } + + // + int q1Length = mLoopback / 4; + int halfLength = mLoopback / 2; + int q2Length = halfLength + q1Length; + + // + double firstValue = buffer[1]; + double q1Value = buffer[q1Length]; + double q2Value = buffer[q2Length]; + double halfValue = buffer[halfLength]; + double lastValue = buffer[ArraySize(buffer) - 1]; + + // + // Peak ... + result = + // + firstValue > lastValue + // + && + // + ( + firstValue > q1Value && + firstValue > halfValue) + // + ; + + // + return result; +} + +// +bool IsInVale( + int mLoopback, // loopback length + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + mLoopback < 2 || + ArraySize(buffer) < mLoopback + 1) + { + return result; + } + + // + int q1Length = mLoopback / 4; + int halfLength = mLoopback / 2; + int q2Length = halfLength + q1Length; + + // + double firstValue = buffer[1]; + double q1Value = buffer[q1Length]; + double q2Value = buffer[q2Length]; + double halfValue = buffer[halfLength]; + double lastValue = buffer[ArraySize(buffer) - 1]; + + // + // Peak ... + result = + // + firstValue < lastValue + // + && + // + ( + firstValue < q1Value && + firstValue < halfValue) + // + ; + + // + return result; +} + +// +// Check Sharp Happens or not ... +bool IsSharpChanged( + double fromValue, // Past Value + double toValue, // Present Value + double maxValue, // Max in Range Value + double minValue // Min in Range Value +) +{ + // + bool result = false; + + // + // This Used In Increased or Decreased Sharp Detection ... + bool isIncreased = toValue > fromValue; + + // + double toFromDelta = MathAbs(toValue - fromValue); + double minMaxDelta = maxValue - minValue; + + // + result = toFromDelta >= (minMaxDelta / 3); + + // + return result; +} +bool IsSharpChanged( + int from, // Past Index in Series + int to, // Present Index in Series + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + from <= to || + ArraySize(buffer) < from + 1) + { + return result; + } + + // + // Loop through Items ... + double toValue = buffer[to]; + double fromValue = buffer[from]; + + // + // This Used In Increased or Decreased Sharp Detection ... + bool isIncreased = toValue > fromValue; + + // + double minValue = GetMinValue( + ArraySize(buffer) - 1, + buffer); + double maxValue = GetMaxValue( + ArraySize(buffer) - 1, + buffer); + double minMaxDelta = maxValue - minValue; + + // + // Sharp Detection ... + result = IsSharpChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} +bool IsSharpChanged( + int from, // Past Bar Index + int to, // Present Bar Index + ENUM_APPLIED_PRICE appliedPrice // Which Price Choose in From or To +) +{ + // + bool result = false; + + // + double toValue = GetAppliedPrice( + to, + appliedPrice); + double fromValue = GetAppliedPrice( + from, + appliedPrice); + + // + int hIdx = iHighest( + _Symbol, + _Period, + MODE_HIGH, + from, + to); + double maxValue = iHigh( + _Symbol, + _Period, + hIdx); + + // + int lIdx = iLowest( + _Symbol, + _Period, + MODE_LOW, + from, + to); + double minValue = iLow( + _Symbol, + _Period, + lIdx); + + // + result = IsSharpChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} + +// +// Check InCreased Sharp Happens or not ... +bool IsSharpIncreasedChanged( + double fromValue, // Past Value + double toValue, // Present Value + double maxValue, // Max in Range Value + double minValue // Min in Range Value +) +{ + // + bool result = false; + + // + // This Used In Increased or Decreased Sharp Detection ... + bool isIncreased = toValue > fromValue; + + // + double toFromDelta = MathAbs(toValue - fromValue); + double minMaxDelta = maxValue - minValue; + + // + result = + isIncreased && + toFromDelta >= (minMaxDelta / 3); + + // + return result; +} +bool IsSharpIncreasedChanged( + int from, // Past Index in Series + int to, // Present Index in Series + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + from <= to || + ArraySize(buffer) < from + 1) + { + return result; + } + + // + // Loop through Items ... + double toValue = buffer[to]; + double fromValue = buffer[from]; + + // + double minValue = GetMinValue( + ArraySize(buffer) - 1, + buffer); + double maxValue = GetMaxValue( + ArraySize(buffer) - 1, + buffer); + double minMaxDelta = maxValue - minValue; + + // + // Sharp Detection ... + result = IsSharpIncreasedChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} +bool IsSharpIncreasedChanged( + int from, // Past Bar Index + int to, // Present Bar Index + ENUM_APPLIED_PRICE appliedPrice // Which Price Choose in From or To +) +{ + // + bool result = false; + + // + double toValue = GetAppliedPrice( + to, + appliedPrice); + double fromValue = GetAppliedPrice( + from, + appliedPrice); + + // + int hIdx = iHighest( + _Symbol, + _Period, + MODE_HIGH, + from, + to); + double maxValue = iHigh( + _Symbol, + _Period, + hIdx); + + // + int lIdx = iLowest( + _Symbol, + _Period, + MODE_LOW, + from, + to); + double minValue = iLow( + _Symbol, + _Period, + lIdx); + + // + result = IsSharpIncreasedChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} + +// +// Check Decreased Sharp Happens or not ... +bool IsSharpDecreasedChanged( + double fromValue, // Past Value + double toValue, // Present Value + double maxValue, // Max in Range Value + double minValue // Min in Range Value +) +{ + // + bool result = false; + + // + // This Used In Increased or Decreased Sharp Detection ... + bool isIncreased = toValue > fromValue; + + // + double toFromDelta = MathAbs(toValue - fromValue); + double minMaxDelta = maxValue - minValue; + + // + result = + !isIncreased && + toFromDelta >= (minMaxDelta / 3); + + // + return result; +} +bool IsSharpDecreasedChanged( + int from, // Past Index in Series + int to, // Present Index in Series + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + from <= to || + ArraySize(buffer) < from + 1) + { + return result; + } + + // + // Loop through Items ... + double toValue = buffer[to]; + double fromValue = buffer[from]; + + // + double minValue = GetMinValue( + ArraySize(buffer) - 1, + buffer); + double maxValue = GetMaxValue( + ArraySize(buffer) - 1, + buffer); + double minMaxDelta = maxValue - minValue; + + // + // Sharp Detection ... + result = IsSharpDecreasedChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} +bool IsSharpDecreasedChanged( + int from, // Past Bar Index + int to, // Present Bar Index + ENUM_APPLIED_PRICE appliedPrice // Which Price Choose in From or To +) +{ + // + bool result = false; + + // + double toValue = GetAppliedPrice( + to, + appliedPrice); + double fromValue = GetAppliedPrice( + from, + appliedPrice); + + // + int hIdx = iHighest( + _Symbol, + _Period, + MODE_HIGH, + from, + to); + double maxValue = iHigh( + _Symbol, + _Period, + hIdx); + + // + int lIdx = iLowest( + _Symbol, + _Period, + MODE_LOW, + from, + to); + double minValue = iLow( + _Symbol, + _Period, + lIdx); + + // + result = IsSharpDecreasedChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} + +// +void Clean(int &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} +void Clean(ulong &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} +void Clean(string &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} +void Clean(double &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} + +// +bool GetLastItem( + double &item, // Holds Result + double &buffer[] // Specified Buffer +) +{ + // + bool result = false; + + // + int bufferSize = ArraySize(buffer); + if (bufferSize <= 0) + { + return result; + } + + // + item = buffer[bufferSize - 1]; + + // + result = true; + return result; +} +bool GetLastItem( + datetime &item, // Holds Result + datetime &buffer[] // Specified Buffer +) +{ + // + bool result = false; + + // + int bufferSize = ArraySize(buffer); + if (bufferSize <= 0) + { + return result; + } + + // + item = buffer[bufferSize - 1]; + + // + result = true; + return result; +} + +// +void Add( + int item, // item want to add + int &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + ulong item, // item want to add + ulong &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + string item, // item want to add + string &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + double item, // item want to add + double &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + XOHCL &item, // item want to add + XOHCL &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + datetime &item, // item want to add + datetime &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} + +// +// Add an Item to a Buffer if not Exists ... +void AddIfNotExists( + double value, + double &values[], + double smoothingPoint = 3) +{ + // + double smoothingValue = smoothingPoint * GetPoints(_Symbol); + + // + int valuesCount = ArraySize(values); + if (valuesCount <= 0) + { + // + Add(value, + values); + } + else + { + // + bool isExists = false; + for (int i = 0; i < valuesCount; i++) + { + // + double iVal = values[i]; + + // + double diff = MathAbs(iVal - value); + + // + if (iVal == value || diff < smoothingValue) + { + // + isExists = true; + break; + } + } + + // + if (!isExists) + { + // + Add(value, + values); + } + } +} + +// +// Add a Buffers Child to another Buffer +// if it's not Contains them ... +void AddsIfNotExists( + double &source[], + double &dest[], + double smoothingPoint = 3) +{ + // + double smoothingValue = smoothingPoint * GetPoints(_Symbol); + + // + int sourceCount = ArraySize(source); + if (sourceCount <= 0) + { + return; + } + + // + for (int i = 0; i < sourceCount; i++) + { + // + double iSource = source[i]; + + // + AddIfNotExists( + iSource, + dest, + smoothingPoint); + } +} + +// +// Converts a Buffer to String Representation ... +string ToString( + const int &buffer[], // Specified Buffer + string separator = ",", // Specified Separator + bool addIndex = false, // Specified Add Items Indexes or Not + string indexLabel = "i:", // Specified Index Label + string indexSeparator = ">" // Specified Index Separator + +) +{ + // + string result = ""; + + // + int bufferSize = ArraySize(buffer); + if (bufferSize <= 0) + { + return result; + } + + // + for (int i = 0; i < bufferSize; i++) + { + // + if (addIndex) + { + // + if (StringLen(indexLabel) > 0) + { + result += indexLabel + " "; + } + + // + result += (string)i + " "; + + // + if (StringLen(indexSeparator) > 0) + { + result += indexSeparator + " "; + } + } + + // + string iItemString = (string)buffer[i]; + + // + result += iItemString; + + // + if (i < bufferSize - 1) + { + result += separator; + } + } + + // + return result; +} +string ToString( + const double &buffer[], // Specified Buffer + string separator = ",", // Specified Separator + bool addIndex = false, // Specified Add Items Indexes or Not + string indexLabel = "i:", // Specified Index Label + string indexSeparator = ">" // Specified Index Separator + +) +{ + // + string result = ""; + + // + int bufferSize = ArraySize(buffer); + if (bufferSize <= 0) + { + return result; + } + + // + for (int i = 0; i < bufferSize; i++) + { + // + if (addIndex) + { + // + if (StringLen(indexLabel) > 0) + { + result += indexLabel + " "; + } + + // + result += (string)i + " "; + + // + if (StringLen(indexSeparator) > 0) + { + result += indexSeparator + " "; + } + } + + // + string iItemString = (string)buffer[i]; + + // + result += iItemString; + + // + if (i < bufferSize - 1) + { + result += separator; + } + } + + // + return result; +} +string ToString( + const string &buffer[], // Specified Buffer + string separator = ",", // Specified Separator + bool addIndex = false, // Specified Add Items Indexes or Not + string indexLabel = "i:", // Specified Index Label + string indexSeparator = ">" // Specified Index Separator + +) +{ + // + string result = ""; + + // + int bufferSize = ArraySize(buffer); + if (bufferSize <= 0) + { + return result; + } + + // + for (int i = 0; i < bufferSize; i++) + { + // + if (addIndex) + { + // + if (StringLen(indexLabel) > 0) + { + result += indexLabel + " "; + } + + // + result += (string)i + " "; + + // + if (StringLen(indexSeparator) > 0) + { + result += indexSeparator + " "; + } + } + + // + string iItemString = (string)buffer[i]; + + // + result += iItemString; + + // + if (i < bufferSize - 1) + { + result += separator; + } + } + + // + return result; +} +string ToString( + const datetime &buffer[], // Specified Buffer + string separator = ",", // Specified Separator + bool addIndex = false, // Specified Add Items Indexes or Not + string indexLabel = "i:", // Specified Index Label + string indexSeparator = ">" // Specified Index Separator +) +{ + // + string result = ""; + + // + int bufferSize = ArraySize(buffer); + if (bufferSize <= 0) + { + return result; + } + + // + for (int i = 0; i < bufferSize; i++) + { + // + if (addIndex) + { + // + if (StringLen(indexLabel) > 0) + { + result += indexLabel + " "; + } + + // + result += (string)i + " "; + + // + if (StringLen(indexSeparator) > 0) + { + result += indexSeparator + " "; + } + } + + // + string iItemString = (string)buffer[i]; + + // + result += iItemString; + + // + if (i < bufferSize - 1) + { + result += separator; + } + } + + // + return result; +} +template +string ToString(T value) +{ + return (string)value; +} + +// +// Converts String to boolean ... +bool ToBoolean(string value) +{ + // + bool result = false; + + // + if (StringLen(value) <= 0) + { + return result; + } + + // + StringToLower(value); + result = value == "true"; + + // + return result; +} + +// +// Search Array For Specific Item ... +template +int FindIndex( + T item, // What is Search ... + T &buffer[] // Search in ... +) +{ + // + int result = -1; + + // + int count = ArraySize(buffer); + if (count <= 0) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + T iT = buffer[i]; + + // + if (iT == item) + { + // + result = i; + break; + } + } + + // + return result; +} + +template +bool Contains( + T item, // What is Search ... + T &buffer[] // Search in ... +) +{ + // + bool result = false; + + // + int idx = FindIndex( + item, + buffer); + result = idx > -1; + + // + return result; +} + +// +// Split an String Representation of an Array ... +void SplitContent( + string &result[], // Hold Result ... + string content, // Source ... + string separator = ",", // Separator ... + bool forceCleanResult = true // Clean Result ... +) +{ + // + if (forceCleanResult) + { + Clean(result); + } + + // + if (separator == NULL || StringLen(separator) == 0) + { + separator = ","; + } + + // + if (StringLen(content) == 0) + { + return; + } + + // + StringSplit( + content, + StringGetCharacter( + separator, + 0), + result); +} + +// +// Extract Data from String ... +string ExtractString( + const string source, // Source String used for Extracting + const string startString, // Expression Start String must be Unique + const string endString // Where to End Extraction, usually a Sign +) +{ + // + string result = ""; + + // + // Validate String ... + if ( + StringLen(source) == 0 || + StringLen(endString) == 0 || + StringLen(startString) == 0) + { + return result; + } + + // + // Find Start String Position ... + int sPos = StringFind( + source, + startString); + if (sPos < 0) + { + return result; + } + + // + // Find End String Position after Start String ... + int searchEndFromPos = sPos + StringLen(startString); + int ePos = StringFind( + source, + endString, + searchEndFromPos); + if (ePos < 0) + { + return result; + } + + // + // Extract Data from Source ... + int dLength = ePos - searchEndFromPos; + result = StringSubstr( + source, + searchEndFromPos, + dLength); + + // + return result; +} + +// +// Extract an Array of Contents ... +int ExtractStrings( + string &result[], // Hold Result + const string source, // Source String used for Extracting + const string startString, // Expression Start String must be Unique + const string endString // Where to End Extraction, usually a Sign +) +{ + // + int mResult = 0; + + // + Clean(result); + + // + // Validate Args ... + int sourceLength = StringLen(source); + int startLength = StringLen(startString); + int endLength = StringLen(endString); + + // + int minRequiredLength = startLength + endLength; + + // + if ( + endLength <= 0 || + startLength <= 0 || + sourceLength <= 0 || + sourceLength < minRequiredLength) + { + return mResult; + } + + // + // Make a Copy of Source for Manipulating ... + string workStr = source; + + // + // Define a Loop ... + while (StringLen(workStr) > minRequiredLength) + { + // + // Find Item ... + string item = ExtractString( + workStr, + startString, + endString); + + // + // Breakout when couldn't find anymore item ... + int itemLength = StringLen(item); + if (itemLength <= 0) + { + break; + } + + // + // Prepare Item Source String for Replacing in Work String ... + string itemSource = startString + item + endString; + + // + // Add Item to Result Array ... + Add( + item, + result); + + // + // Replace Item Soure in Work String ... + StringReplace( + workStr, + itemSource, + ""); + } + + // + // Calculate Size of Array ... + mResult = ArraySize(result); + + // + return mResult; +} + +// +// Normalize a give Volume ... +double NormalizeVolume( + double volume, // desired volume to normalize + string symbol = NULL, // Specified Symbol for Normalization + int mLength = 2 // Length of Digits +) +{ + // + double result = volume; + + // + // Normalize Symbol ... + if (StringLen(symbol) == 0) + { + symbol = _Symbol; + } + + // + // Normalize Digits ... + int digits = GetDigits(symbol); + mLength = + mLength == 0 || mLength > digits + ? digits + : MathMin(mLength, digits); + + // + // Normalize Volume ... + result = NormalizeDouble(result, mLength); + + // + double maxAvailableVolume = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX); + double minAvailableVolume = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN); + + // + // Validate Result ... + if (result > maxAvailableVolume) + { + result = maxAvailableVolume; + } + else if (result < minAvailableVolume) + { + result = minAvailableVolume; + } + + // + return result; +} + +// +// Normallize Price ... +double NormalizePrice( + double price, // desired Price for normalization + string symbol = NULL // Specified Symbol for Normalization +) +{ + // + double result = 0; + + // + // Mormalize Symbol ... + if (StringLen(symbol) == 0) + { + symbol = _Symbol; + } + + // + int digits = GetDigits(symbol); + result = NormalizeDouble(price, digits); + + // + return result; +} + +// +// Do All Normalization on Specific Signal ... +void NormalizeSignal(XSignal &signal) +{ + // + // ENTRY ... + if (signal.entry > 0) + { + signal.entry = NormalizePrice(signal.entry, signal.symbol); + } + + // + // TP ... + if (signal.tp > 0) + { + signal.tp = NormalizePrice(signal.tp, signal.symbol); + } + + // + // SL ... + if (signal.sl > 0) + { + signal.sl = NormalizePrice(signal.sl, signal.symbol); + } + + // + // VOLUME ... + if (signal.volume > 0) + { + signal.volume = NormalizeVolume(signal.volume, signal.symbol); + } +} + +// +// Check Expert Running in Testing Mode or not ... +bool IsRunningOnTestMode() +{ + // + bool result = false; + + // + // check programm mode ... + result = MQL5InfoInteger(MQL5_TESTING); + + // + return result; +} + +// +// Calculate Volume Weighted Moving Average ... +double iVWMA( + double price, + double volume, + int period, + int i, + int bars, + int instance = 0 // +) +{ +#define ¤ instance +#ifdef _averageInstances +#define _functionInstances _averageInstances +#else #define _functionInstances 1 +#endif + struct sVwmaArrayStruct + { + double price; + double volume; + double sump; + double sumv; + }; + static sVwmaArrayStruct m_array[][_functionInstances]; + static int m_arraySize = 0; + if (m_arraySize < bars) + { + int _res = ArrayResize(m_array, bars + 500); + if (_res <= bars) + return (0); + m_arraySize = _res; + } + + // + //--- + // + + if (volume == 0) + volume = 1; + m_array[i][¤].price = volume * price; + m_array[i][¤].volume = volume; + if (i > period) + { + m_array[i][¤].sump = m_array[i - 1][¤].sump + m_array[i][¤].price - m_array[i - period][¤].price; + m_array[i][¤].sumv = m_array[i - 1][¤].sumv + volume - m_array[i - period][¤].volume; + } + else + { + m_array[i][¤].sump = m_array[i][¤].price; + m_array[i][¤].sumv = m_array[i][¤].volume; + for (int k = 1; k < period && i >= k; k++) + { + m_array[i][¤].sump += m_array[i - k][¤].price; + m_array[i][¤].sumv += m_array[i - k][¤].volume; + } + } + return (m_array[i][¤].sump / m_array[i][¤].sumv); + + // + //--- + // + +#undef ¤ #undef _functionInstances +} + +// +// Date Time Manipulation Functions ... +// + +// +// Representation of Time Struct ... +// struct MqlDateTime +// { +// int year; // Year +// int mon; // Month +// int day; // Day +// int hour; // Hour +// int min; // Minutes +// int sec; // Seconds +// int day_of_week; // Day of week (0-Sunday, 1-Monday, ... ,6-Saturday) +// int day_of_year; // Day number of the year (January 1st is assigned the number value of zero) +// }; + +// +// Converts Time to Seconds ... +ulong TimeToSeconds( + datetime time // Specify time to Convert ... +) +{ + // + ulong result = (ulong)time; + + // + return result; +} +ulong TimeToSeconds( + MqlDateTime &time // Specify time to Convert ... +) +{ + // + datetime dTime = StructToTime(time); + + // + ulong result = TimeToSeconds(dTime); + + // + return result; +} + +// +// Converts Seconds To Time ... +datetime SecondsToTime( + ulong seconds // Specify Seconds to Convert ... +) +{ + // + datetime result = (datetime)seconds; + + // + return result; +} +MqlDateTime SecondsToStruct( + ulong seconds // Specify Seconds to Convert ... +) +{ + // + datetime dTime = SecondsToTime(seconds); + + // + MqlDateTime result = {}; + TimeToStruct( + dTime, + result); + + // + return result; +} + +// +// Converts Time to MilliSeconds ... +ulong TimeToMilliSeconds( + datetime time // Specify time to Convert ... +) +{ + // + ulong result = TimeToSeconds(time) * 1000; + + // + return result; +} +ulong TimeToMilliSeconds( + MqlDateTime &time // Specify time to Convert ... +) +{ + // + datetime dTime = StructToTime(time); + + // + ulong result = TimeToMilliSeconds(dTime); + + // + return result; +} + +// +// Converts MillisSeconds to Time ... +datetime MilliSecondsToTiem( + ulong milliSeconds // Specify MilliSeconds to Convert ... +) +{ + // + ulong seconds = milliSeconds / 1000; + + // + datetime result = SecondsToTime(seconds); + + // + return result; +} +MqlDateTime MilliSecondsToStruct( + ulong milliSeconds // Specify MilliSeconds to Convert ... +) +{ + // + datetime dTime = MilliSecondsToTiem(milliSeconds); + + // + MqlDateTime result = {}; + TimeToStruct( + dTime, + result); + + // + return result; +} + +// +// Retrieve DateTime Structure ... +MqlDateTime GetCurrentTime() +{ + // + MqlDateTime result = {}; + + // + TimeCurrent(result); + + // + return result; +} + +// +// Retrieve Current Time as Seconds ... +ulong GetCurrentTimeAsSeconds() +{ + // + datetime time = TimeCurrent(); + + // + ulong result = TimeToSeconds(time); + + // + return result; +} + +// +// Retrieve Current Time as MilliSeconds ... +ulong GetCurrentTimeAsMilliSeconds() +{ + // + datetime time = TimeCurrent(); + + // + ulong result = TimeToMilliSeconds(time); + + // + return result; +} + +// +// Retrieve Specified Candle Time ... +datetime GetCandleTime( + string symbol = "", // Specify Symbol + ENUM_TIMEFRAMES period = NULL, // Specify TimeFrame + int bar_index = 0 // Specify Bar Index +) +{ + // + // Validate and Normalize Args ... + + // + // Normalize Symbol ... + symbol = StringLen(symbol) == 0 + ? _Symbol + : symbol; + + // + // Normalize Period ... + period = period == NULL + ? _Period + : period; + + // + // Retrieve Bar Time ... + datetime result = iTime( + symbol, + period, + bar_index); + + // + return result; +} + +// +// Retrieve Specified Candle Time ... +ulong GetCandleTimeAsSeconds( + string symbol = "", // Specify Symbol + ENUM_TIMEFRAMES period = NULL, // Specify TimeFrame + int bar_index = 0 // Specify Bar Index +) +{ + // + // Retrieve Bar Time ... + datetime time = GetCandleTime( + symbol, + period, + bar_index); + + // + ulong result = TimeToSeconds(time); + + // + return result; +} + +// +// Retrieve Specified Candle Time ... +ulong GetCandleTimeAsMilliSeconds( + string symbol = "", // Specify Symbol + ENUM_TIMEFRAMES period = NULL, // Specify TimeFrame + int bar_index = 0 // Specify Bar Index +) +{ + // + // Retrieve Bar Time ... + datetime time = GetCandleTime( + symbol, + period, + bar_index); + + // + ulong result = TimeToMilliSeconds(time); + + // + return result; +} + +// +// Retrieve a Candle Time Structure ... +MqlDateTime GetCandleTimeStruct( + string symbol = "", // Specify Symbol + ENUM_TIMEFRAMES period = NULL, // Specify TimeFrame + int bar_index = 0 // Specify Bar Index +) +{ + // + MqlDateTime result = {}; + + // + // Retrieve Bar Time ... + datetime barTime = GetCandleTime( + symbol, + period, + bar_index); + + // + // Convert to Structure ... + TimeToStruct(barTime, result); + + // + return result; +} + +// +// Retrieve Number of Candles in a Day ... +int GetDailyCandleCount(ENUM_TIMEFRAMES mPeriod) +{ + // + int seconds = PeriodSeconds(mPeriod); + + // + int daySeconds = 24 * 60 * 60; + + // + int result = daySeconds / seconds; + + // + return result; +} + +int GetDailyCandleCount() +{ + // + int result = GetDailyCandleCount(_Period); + + // + return result; +} + +// +// +// + +// +// Holds Month ... +static int xMonth = -1; + +// +// Holds Day Of Week ... +static int xDayOfWeek = -1; +static int xForWeekDay = -1; + +// +// Holds Day ... +static int xDay = -1; + +// +// Holds Hour ... +static int xHour = -1; + +// +// Reset Timing Variables ... +void ResetTiming() +{ + // + xHour = -1; + xDay = -1; + xDayOfWeek = -1; + xMonth = -1; +} + +// +// Detecting New Houre ... +bool IsNewHour() +{ + // + bool result = false; + + // + // Retrieve Current Time as Struct ... + MqlDateTime timeStruct = GetCurrentTime(); + + // + // Check Houre ... + result = timeStruct.hour != xHour; + if (result) + { + xHour = timeStruct.hour; + } + + // + return result; +} + +// +// Detecting New Day ... +bool IsNewDay() +{ + // + bool result = false; + + // + // Retrieve Current Time as Struct ... + MqlDateTime timeStruct = GetCurrentTime(); + + // + // Check Houre ... + result = timeStruct.day_of_year != xDay; + if (result) + { + xDay = timeStruct.day_of_year; + } + + // + return result; +} + +// +// Detecting New Week ... +bool IsNewWeek() +{ + // + bool result = false; + + // + // Retrieve Current Time as Struct ... + MqlDateTime timeStruct = GetCurrentTime(); + + // + // Check Week ... + // Since Week Starts From Monday in Forex World ... + // we Calculate Start of Week by 1-Monday ... + result = + xDayOfWeek == -1 && + xForWeekDay == -1 + ? true + : timeStruct.day_of_week == 1 && + timeStruct.day_of_year > xForWeekDay; + + // + xForWeekDay = timeStruct.day_of_year; + xDayOfWeek = timeStruct.day_of_week; + + // + return result; +} + +// +// Detecting End Of Week ... +bool IsWeekEnd() +{ + // + bool result = false; + + // + // Retrieve Current Time as Struct ... + MqlDateTime timeStruct = GetCurrentTime(); + + // + // Check WeekEnd ... + // Since Week Starts From Monday in Forex World ... + // we Calculate End of Week by 5-Friday ... + result = + xDayOfWeek != -1 && + timeStruct.day_of_week == 5 && + timeStruct.hour == 23 && + timeStruct.min == 59 && + timeStruct.sec == 59; + + // + return result; +} + +// +// Detecting New Month ... +bool IsNewMonth() +{ + // + bool result = false; + + // + // Retrieve Current Time as Struct ... + MqlDateTime timeStruct = GetCurrentTime(); + + // + // Check Houre ... + result = timeStruct.mon != xMonth; + if (result) + { + xMonth = timeStruct.mon; + } + + // + return result; +} + +// +// Find Hindmost Time Frame ... +ENUM_TIMEFRAMES GetHindmostTimeFrame( + ENUM_TIMEFRAMES mPeriod // Specified Period +) +{ + // + ENUM_TIMEFRAMES result = NULL; + + // + // Normalize Period ... + if ( + mPeriod < 0 || + mPeriod == NULL) + { + mPeriod = _Period; + } + + // + switch (mPeriod) + { + // + case PERIOD_M1: + case PERIOD_M2: + case PERIOD_M3: + case PERIOD_M4: + result = PERIOD_H4; + break; + + // + case PERIOD_M5: + case PERIOD_M6: + case PERIOD_M10: + case PERIOD_M12: + result = PERIOD_H8; + break; + + // + case PERIOD_M15: + case PERIOD_M20: + result = PERIOD_H12; + break; + + // + case PERIOD_M30: + result = PERIOD_D1; + break; + + // + case PERIOD_H1: + case PERIOD_H2: + case PERIOD_H3: + result = PERIOD_W1; + break; + + // + case PERIOD_H4: + case PERIOD_H6: + case PERIOD_H8: + result = PERIOD_MN1; + break; + + // + case PERIOD_H12: + result = PERIOD_MN1; + break; + + // + case PERIOD_D1: + result = PERIOD_MN1; + break; + + // + case PERIOD_W1: + result = PERIOD_MN1; + break; + + // + default: + result = PERIOD_MN1; + break; + } + + // + return result; +} + +// +// Find Farest Time Frame ... +ENUM_TIMEFRAMES GetFarestTimeFrame( + ENUM_TIMEFRAMES mPeriod // Specified Period +) +{ + // + ENUM_TIMEFRAMES result = NULL; + + // + // Normalize Period ... + if ( + mPeriod < 0 || + mPeriod == NULL) + { + mPeriod = _Period; + } + + // + switch (mPeriod) + { + // + case PERIOD_M1: + case PERIOD_M2: + case PERIOD_M3: + case PERIOD_M4: + result = PERIOD_H1; + break; + + // + case PERIOD_M5: + case PERIOD_M6: + case PERIOD_M10: + case PERIOD_M12: + result = PERIOD_H2; + break; + + // + case PERIOD_M15: + case PERIOD_M20: + result = PERIOD_H3; + break; + + // + case PERIOD_M30: + result = PERIOD_H4; + break; + + // + case PERIOD_H1: + case PERIOD_H2: + case PERIOD_H3: + result = PERIOD_H8; + break; + + // + case PERIOD_H4: + case PERIOD_H6: + case PERIOD_H8: + result = PERIOD_D1; + break; + + // + case PERIOD_H12: + result = PERIOD_MN1; + break; + + // + case PERIOD_D1: + result = PERIOD_MN1; + break; + + // + case PERIOD_W1: + result = PERIOD_MN1; + break; + + // + default: + result = PERIOD_MN1; + break; + } + + // + return result; +} + +// +// Find Medium Time Frame ... +ENUM_TIMEFRAMES GetMediestTimeFrame( + ENUM_TIMEFRAMES mPeriod // Specified Period +) +{ + // + ENUM_TIMEFRAMES result = NULL; + + // + // Normalize Period ... + if ( + mPeriod < 0 || + mPeriod == NULL) + { + mPeriod = _Period; + } + + // + switch (mPeriod) + { + // + case PERIOD_M1: + case PERIOD_M2: + case PERIOD_M3: + case PERIOD_M4: + result = PERIOD_M12; + break; + + // + case PERIOD_M5: + case PERIOD_M6: + case PERIOD_M10: + case PERIOD_M12: + result = PERIOD_M30; + break; + + // + case PERIOD_M15: + case PERIOD_M20: + result = PERIOD_H1; + break; + + // + case PERIOD_M30: + result = PERIOD_H2; + break; + + // + case PERIOD_H1: + case PERIOD_H2: + case PERIOD_H3: + result = PERIOD_H6; + break; + + // + case PERIOD_H4: + case PERIOD_H6: + case PERIOD_H8: + result = PERIOD_H12; + break; + + // + case PERIOD_H12: + result = PERIOD_W1; + break; + + // + case PERIOD_D1: + result = PERIOD_MN1; + break; + + // + case PERIOD_W1: + result = PERIOD_MN1; + break; + + // + default: + result = PERIOD_MN1; + break; + } + + // + return result; +} + +// +// Find Nearest Time Frame ... +ENUM_TIMEFRAMES GetNearestTimeFrame( + ENUM_TIMEFRAMES mPeriod // Specified Period +) +{ + // + ENUM_TIMEFRAMES result = NULL; + + // + // Normalize Period ... + if ( + mPeriod < 0 || + mPeriod == NULL) + { + mPeriod = _Period; + } + + // + switch (mPeriod) + { + // + case PERIOD_M1: + case PERIOD_M2: + case PERIOD_M3: + case PERIOD_M4: + result = PERIOD_M5; + break; + + // + case PERIOD_M5: + case PERIOD_M6: + case PERIOD_M10: + case PERIOD_M12: + result = PERIOD_M15; + break; + + // + case PERIOD_M15: + case PERIOD_M20: + result = PERIOD_M30; + break; + + // + case PERIOD_M30: + result = PERIOD_H1; + break; + + // + case PERIOD_H1: + case PERIOD_H2: + case PERIOD_H3: + result = PERIOD_H4; + break; + + // + case PERIOD_H4: + case PERIOD_H6: + case PERIOD_H8: + result = PERIOD_H12; + break; + + // + case PERIOD_H12: + result = PERIOD_D1; + break; + + // + case PERIOD_D1: + result = PERIOD_W1; + break; + + // + case PERIOD_W1: + result = PERIOD_MN1; + break; + + // + default: + result = PERIOD_MN1; + break; + } + + // + return result; +} + +// +// Get Specific Time Frame Start Candle Time ... +datetime GetPeriodStartTime( + string mSymbol = NULL, // Specified Symbol ... + ENUM_TIMEFRAMES mPeriod = NULL, // Specified Period ... + datetime mTime = NULL // Specified Bar Time ... +) +{ + // + // Normalize Arg ... + + // + if ( + mSymbol == NULL || + StringLen(mSymbol) == 0) + { + mSymbol = _Symbol; + } + + // + if ( + mPeriod < 0 || + mPeriod == NULL) + { + mPeriod = _Period; + } + + // + if ( + mTime < 0 || + mTime == NULL) + { + mTime = TimeCurrent(); + } + + // + int barIndex = iBarShift( + mSymbol, + mPeriod, + mTime, + false); + + // + datetime result = iTime( + mSymbol, + mPeriod, + barIndex); + + // + return result; +} + +// +struct XCandleRemains +{ + // + int days; + int hours; + int minutes; + int seconds; +}; + +// +string ToString( + XCandleRemains &item, + string dayId = "d", + string hourId = "h", + string minuteId = "m", + string secondId = "s", + string idSeparator = ": ", + string separator = ", ", + bool ignoreZeroValues = true) +{ + // + string result = ""; + + // + // Days ... + if (!ignoreZeroValues || item.days > 0) + { + result += dayId + idSeparator + (string)item.days + separator; + } + + // + // Hours ... + if (!ignoreZeroValues || item.hours > 0) + { + // + string strHour = ToString(item.hours); + if (StringLen(strHour) == 1) + { + strHour = "0" + strHour; + } + + // + result += hourId + idSeparator + strHour + separator; + } + + // + // Minutes ... + if (!ignoreZeroValues || item.minutes > 0) + { + // + string strMinute = ToString(item.minutes); + if (StringLen(strMinute) == 1) + { + strMinute = "0" + strMinute; + } + + // + result += minuteId + idSeparator + strMinute + separator; + } + + // + // Seconds ... + if (!ignoreZeroValues || item.seconds > 0) + { + // + string strSec = ToString(item.seconds); + if (StringLen(strSec) == 1) + { + strSec = "0" + strSec; + } + + // + result += secondId + idSeparator + strSec; + } + + // + return result; +} + +// +// Retrieve Specific Candles Ramained Time ... +void GetCandleRemainsTime( + XCandleRemains &result, // Holds Result ... + string mSymbol = NULL, // Specified Symbol ... + ENUM_TIMEFRAMES mPeriod = NULL, // Specified Period ... + int mBarIndex = 0 // Specified Bar Index ... +) +{ + // + int minuteSecoonds = 60; + int hourSeconds = minuteSecoonds * 60; + int daySeconds = 24 * hourSeconds; + + // + int periodSeconds = PeriodSeconds( + mPeriod); + datetime startTime = GetCandleTime( + mSymbol, + mPeriod, + mBarIndex); + + // + int secondsDiff = (int)startTime + periodSeconds - (int)TimeCurrent(); + + // + int days = 0; + int hours = 0; + int minutes = 0; + int seconds = 0; + + // + int mWorkingSecondsDiff = secondsDiff; + if (mWorkingSecondsDiff > daySeconds) + { + // + days = mWorkingSecondsDiff / daySeconds; + mWorkingSecondsDiff -= days * daySeconds; + } + if (mWorkingSecondsDiff > hourSeconds) + { + // + hours = mWorkingSecondsDiff / hourSeconds; + mWorkingSecondsDiff -= hours * hourSeconds; + } + if (mWorkingSecondsDiff > minuteSecoonds) + { + // + minutes = mWorkingSecondsDiff / minuteSecoonds; + mWorkingSecondsDiff -= minutes * minuteSecoonds; + } + seconds = mWorkingSecondsDiff; + + // + result.days = days; + result.hours = hours; + result.minutes = minutes; + result.seconds = seconds; +} + +// +// Converts an String to TimeFrame ... +ENUM_TIMEFRAMES ToPeriod(string value) +{ + // + if (StringLen(value) == 0) + { + return _Period; + } + + // + StringTrimLeft(value); + StringTrimRight(value); + + // + ENUM_TIMEFRAMES result = _Period; + + // + if (value == "M1") + { + result = PERIOD_M1; + } + else if (value == "M2") + { + result = PERIOD_M2; + } + else if (value == "M3") + { + result = PERIOD_M3; + } + else if (value == "M4") + { + result = PERIOD_M4; + } + else if (value == "M5") + { + result = PERIOD_M5; + } + else if (value == "M6") + { + result = PERIOD_M6; + } + else if (value == "M10") + { + result = PERIOD_M10; + } + else if (value == "M12") + { + result = PERIOD_M12; + } + else if (value == "M15") + { + result = PERIOD_M15; + } + else if (value == "M20") + { + result = PERIOD_M20; + } + else if (value == "M30") + { + result = PERIOD_M30; + } + else if (value == "H1") + { + result = PERIOD_H1; + } + else if (value == "H2") + { + result = PERIOD_H2; + } + else if (value == "H3") + { + result = PERIOD_H3; + } + else if (value == "H4") + { + result = PERIOD_H4; + } + else if (value == "H6") + { + result = PERIOD_H6; + } + else if (value == "H8") + { + result = PERIOD_H8; + } + else if (value == "H12") + { + result = PERIOD_H12; + } + else if (value == "D1") + { + result = PERIOD_D1; + } + else if (value == "W1") + { + result = PERIOD_W1; + } + else if (value == "MN1") + { + result = PERIOD_MN1; + } + + // + return result; +} + +// +// Converts Period to String ... +string ToString(ENUM_TIMEFRAMES period) +{ + // + string result = ""; + + // + string mPStr = EnumToString(period); + + string mPStrParts[]; + int partsCount = StringSplit( + mPStr, + StringGetCharacter("_", 0), + mPStrParts); + if (partsCount <= 0) + { + return result; + } + + // + result = mPStrParts[1]; + + // + return result; +} + +// +// TYPES ... +// + +// +// Retrieve Specific Object Types Name ... +template +string GetTypeName(const T &t) +{ + return typename(T); +} + +// +// END Provided Functions ... +// diff --git a/MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.draw.lib.ex5 b/MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.draw.lib.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..1be43388a4f4ab0b53f0cabcfd5e6e05eef7ad5f GIT binary patch literal 6322 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 0; iObj--) + { + // + string on = ObjectName(chartId, iObj, subWindow); + if (StringFind(on, tag) >= 0) + { + ObjectDelete(chartId, on); + } + } + + // + // Redraw Chart ... + ChartRedraw(); +} + +// +bool RemoveDraw( + string name, + int chartId = -1, + int subWindow = -1) +{ + // + bool result = false; + + // + if (chartId == -1) + { + chartId = 0; + } + + // + if (subWindow == -1) + { + subWindow = 0; + } + + // + string objName = ""; + for (int iObj = ObjectsTotal(chartId, subWindow) - 1; iObj >= 0; iObj--) + { + // + string on = ObjectName(chartId, iObj, subWindow); + if (StringFind(on, name) >= 0) + { + // + objName = on; + break; + } + } + + // + if (StringLen(objName) > 0) + { + result = ObjectDelete(chartId, objName); + } + + // + return result; +} + +// +// Deselect All Draws ... +void DeselectAllDraws() +{ + // + int objs = ObjectsTotal(ChartID(), 0); + for (int o = 0; o < objs; o++) + { + ObjectSetInteger(ChartID(), ObjectName(ChartID(), o, 0), OBJPROP_SELECTED, false); + } + + // + ChartRedraw(); +} + +// +// Check Object Exists ... +bool IsDrawExists( + string name, + int chartId = -1, + int subWindow = -1) +{ + // + bool result = false; + + // + if (chartId == -1) + { + chartId = 0; + } + + // + if (subWindow == -1) + { + subWindow = 0; + } + + // + for (int iObj = ObjectsTotal(chartId, subWindow) - 1; iObj >= 0; iObj--) + { + // + string on = ObjectName(chartId, iObj, subWindow); + result = StringFind(on, name) >= 0; + if (result) + { + break; + } + } + + // + return result; +} +// +// END Provided Functions ... +// + +// +// START Regular Draws ... +// + +// +// START Arrow Functions ... +// +// +// Draw an Arrow Object on Chart ... +bool DrawArrow( + const long chartID = 0, // chart's ID + const string name = "Arrow", // arrow name + const int subWindow = 0, // subwindow index + datetime time = 0, // anchor point time + double price = 0, // anchor point price + const uchar arrowCode = 252, // arrow code + const ENUM_ARROW_ANCHOR anchor = ANCHOR_BOTTOM, // anchor point position + const color clr = clrAqua, // arrow color + const ENUM_LINE_STYLE style = STYLE_SOLID, // border line style + const int width = 3, // arrow size + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // Order Object ... +) +{ + // + // set anchor point coordinates if they are not set ... + ChangeArrowEmptyPoint(time, price); + + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // create an arrow ... + if (!ObjectCreate(chartID, objName, OBJ_ARROW, subWindow, time, price)) + { + // + string message = + __FUNCTION__ + + ": failed to create an arrow! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // set the arrow code ... + ObjectSetInteger(chartID, objName, OBJPROP_ARROWCODE, arrowCode); + + // + // set anchor type ... + ObjectSetInteger(chartID, objName, OBJPROP_ANCHOR, anchor); + + // + // set the arrow color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set the border line style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set the arrow's size ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground false or background true ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable true or disable false the mode of moving the arrow by mouse + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is false by default, if you want making it possible to highlight and move the object + // change it to true ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // hide true or display false graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return true; +} + +// +// Move the anchor point of Arrow ... +bool MoveArrow( + const long chartID = 0, // chart's ID + const string name = "Arrow", // object name + datetime time = 0, // anchor point time coordinate + double price = 0 // anchor point price coordinate +) +{ + // + // if point position is not set, move it to the current bar having Bid price ... + if (!time) + { + time = TimeCurrent(); + } + + // + if (!price) + { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } + + // + // reset the error value + ResetLastError(); + + // + // move the anchor point ... + if (!ObjectMove(chartID, name, 0, time, price)) + { + // + string message = + __FUNCTION__ + + ": failed to move the anchor point! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Delete an arrow ... +bool DeleteArrow( + const long chartID = 0, // chart's ID + const string name = "Arrow" // arrow name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete an arrow ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete an arrow! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Change the arrow code ... +bool ArrowCodeChange( + const long chartID = 0, // chart's ID + const string name = "Arrow", // object name + const uchar code = 252 // arrow code +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // change the arrow code ... + if (!ObjectSetInteger(chartID, name, OBJPROP_ARROWCODE, code)) + { + // + string message = + __FUNCTION__ + + ": failed to change the arrow code! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Change anchor type ... +bool ArrowAnchorChange( + const long chartID = 0, // chart's ID + const string name = "Arrow", // object name + const ENUM_ARROW_ANCHOR anchor = ANCHOR_TOP // anchor type +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // change anchor type ... + if (!ObjectSetInteger(chartID, name, OBJPROP_ANCHOR, anchor)) + { + // + string message = + __FUNCTION__ + + ": failed to change anchor type! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Check anchor point values and set default values +// for empty ones ... +void ChangeArrowEmptyPoint( + datetime &time, + double &price) +{ + // + // if the point's time is not set, it will be on the current bar ... + if (!time) + { + time = TimeCurrent(); + } + + // + // if the point's price is not set, it will have Bid value ... + if (!price) + { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } +} +// +// END Arrow Functions ... +// + +// +// START Horizontal Line Functions ... +// +// +// Create, Draw the horizontal line ... +bool DrawHorizontalLine( + const long chartID = 0, // chart's ID + const string name = "HLine", // line name + const int subWindow = 0, // subwindow index + double price = 0, // line price + const color clr = clrRed, // line color + const ENUM_LINE_STYLE style = STYLE_SOLID, // line style + const int width = 1, // line width + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // if the price is not set, set it at the current Bid price level ... + if (!price) + { + price = SymbolInfoDouble(Symbol(), SYMBOL_BID); + } + + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // create a horizontal line ... + if (!ObjectCreate(chartID, objName, OBJ_HLINE, subWindow, 0, price)) + { + // + string message = + __FUNCTION__ + + ": failed to create a horizontal line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // set line color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set line display style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground false or background true ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable true or disable false the mode of moving the line by mouse + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, selection); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // hide true or display false graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return true; +} + +// +// Move horizontal line ... +bool MoveHorizontalLine( + const long chartID = 0, // chart's ID + const string name = "HLine", // line name + double price = 0 // line price +) +{ + // + // if the line price is not set, move it to the current Bid price level ... + if (!price) + { + price = SymbolInfoDouble(Symbol(), SYMBOL_BID); + } + + // + // reset the error value ... + ResetLastError(); + + // + // move a horizontal line ... + if (!ObjectMove(chartID, name, 0, 0, price)) + { + // + string message = + __FUNCTION__ + + ": failed to move the horizontal line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Delete a horizontal line ... +bool DeleteHorizontalLine( + const long chartID = 0, // chart's ID + const string name = "HLine" // line name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete a horizontal line ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete a horizontal line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} +// +// END Horizontal Line Functions ... +// + +// +// START Vertical Line Functions ... +// +// +// Create the vertical line ... +bool DrawVerticalLine( + const long chartID = 0, // chart's ID + const string name = "VLine", // line name + const int subWindow = 0, // subwindow index + datetime time = 0, // line time + const color clr = clrRed, // line color + const ENUM_LINE_STYLE style = STYLE_SOLID, // line style + const int width = 1, // line width + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // if the line time is not set, draw it via the last bar ... + if (!time) + { + time = TimeCurrent(); + } + + // + // reset the error value + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // create a vertical line ... + if (!ObjectCreate(chartID, objName, OBJ_VLINE, subWindow, time, 0)) + { + // + string message = + __FUNCTION__ + + ": failed to create a vertical line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // set line color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set line display style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground false or background true ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable true or disable false the mode of moving the line by mouse + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // hide true or display false graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return true; +} + +// +// Move the vertical line ... +bool MoveVerticalLine( + const long chartID = 0, // chart's ID + const string name = "VLine", // line name + datetime time = 0 // line time +) +{ + // + // if line time is not set, move the line to the last bar ... + if (!time) + { + time = TimeCurrent(); + } + + // + // reset the error value ... + ResetLastError(); + + // + // move the vertical line ... + if (!ObjectMove(chartID, name, 0, time, 0)) + { + // + string message = + __FUNCTION__ + + ": failed to move the vertical line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Delete the vertical line ... +bool DeleteVerticalLine( + const long chartID = 0, // chart's ID + const string name = "VLine" // line name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete the vertical line ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete the vertical line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} +// +// END Vertical Line Functions ... +// + +// +// START RectangleLabel Functions ... +// +// +// Create Rectangle Label Object ... +bool DrawRectangleLabel( + const long chartID = 0, // chart's ID + const string name = "RectLabel", // label name + const int subWindow = 0, // subwindow index + const int x = 0, // X coordinate + const int y = 0, // Y coordinate + const int width = 50, // width + const int height = 18, // height + const color bgColor = clrWhiteSmoke, // background color + const ENUM_BORDER_TYPE border = BORDER_SUNKEN, // border type + const ENUM_BASE_CORNER corner = CORNER_LEFT_UPPER, // chart corner for anchoring + const color clr = clrRed, // flat border color (Flat) + const ENUM_LINE_STYLE style = STYLE_SOLID, // flat border style + const int lineWidth = 1, // flat border width + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // + // create a rectangle label + if (!ObjectCreate(chartID, objName, OBJ_RECTANGLE_LABEL, subWindow, 0, 0)) + { + // + string message = + __FUNCTION__ + + ": failed to create a rectangle label! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // set label coordinates ... + ObjectSetInteger(chartID, objName, OBJPROP_XDISTANCE, x); + ObjectSetInteger(chartID, objName, OBJPROP_YDISTANCE, y); + + // + // set label size ... + ObjectSetInteger(chartID, objName, OBJPROP_XSIZE, width); + ObjectSetInteger(chartID, objName, OBJPROP_YSIZE, height); + + // + // set background color ... + ObjectSetInteger(chartID, objName, OBJPROP_BGCOLOR, bgColor); + + // + // set border type ... + ObjectSetInteger(chartID, objName, OBJPROP_BORDER_TYPE, border); + + // + // set the chart's corner, relative to which point coordinates are defined ... + ObjectSetInteger(chartID, objName, OBJPROP_CORNER, corner); + + // + // set flat border color (in Flat mode) ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set flat border line style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set flat border width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, lineWidth); + + // + // display in the foreground false or background true ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable true or disable false the mode of moving the label by mouse ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, selection); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // hide true or display false graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return true; +} + +// +// Move Rectangle Label .. +bool MoveRectangleLabel( + const long chartID = 0, // chart's ID + const string name = "RectLabel", // label name + const int x = 0, // X coordinate + const int y = 0 // Y coordinate +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // move the rectangle label ... + if (!ObjectSetInteger(chartID, name, OBJPROP_XDISTANCE, x)) + { + // + string message = + __FUNCTION__ + + ": failed to move X coordinate of the label! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + if (!ObjectSetInteger(chartID, name, OBJPROP_YDISTANCE, y)) + { + // + string message = + __FUNCTION__ + + ": failed to move Y coordinate of the label! Error code = " + + (string)GetLastError(); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Delete the rectangle label ... +bool DeleteRectangleLabel( + const long chartID = 0, // chart's ID + const string name = "RectLabel" // label name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete the label ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete a rectangle label! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Change Rectangle Label Size ... +bool ChangeSizeRectangleLabel( + const long chartID = 0, // chart's ID + const string name = "RectLabel", // label name + const int width = 50, // label width + const int height = 18 // label height +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // change label size ... + if (!ObjectSetInteger(chartID, name, OBJPROP_XSIZE, width)) + { + // + string message = + __FUNCTION__ + + ": failed to change the label's width! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + if (!ObjectSetInteger(chartID, name, OBJPROP_YSIZE, height)) + { + // + string message = + __FUNCTION__ + + ": failed to change the label's height! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Change rectangle label border type ... +bool RectLabelChangeBorderType( + const long chartID = 0, // chart's ID + const string name = "RectLabel", // label name + const ENUM_BORDER_TYPE border = BORDER_SUNKEN // border type +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // change border type ... + if (!ObjectSetInteger(chartID, name, OBJPROP_BORDER_TYPE, border)) + { + // + string message = + __FUNCTION__ + + ": failed to change the border type! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} +// +// END RectangleLabel Functions ... +// + +// +// START TrendLine Funcions ... +// +// Create a trend line by the given coordinates ... +bool DrawTrendLine( + const long chartID = 0, // chart's ID + const string name = "TrendLine", // line name + const int subWindow = 0, // subwindow index + datetime time1 = 0, // first point time + double price1 = 0, // first point price + datetime time2 = 0, // second point time + double price2 = 0, // second point price + const color clr = clrYellow, // line color + const ENUM_LINE_STYLE style = STYLE_SOLID, // line style + const int width = 1, // line width + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool rayRight = false, // line's continuation to the right + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // set anchor points' coordinates if they are not set ... + ChangeTrendLineEmptyPoints( + time1, + price1, + time2, + price2); + + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // create a trend line by the given coordinates ... + if (!ObjectCreate(chartID, objName, OBJ_TREND, subWindow, time1, price1, time2, price2)) + { + // + string message = + __FUNCTION__ + + ": failed to create a trend line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // set line color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set line display style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground false or background true ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable true or disable false the mode of moving the line by mouse + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // enable true or disable false the mode of continuation of the line's display to the right ... + ObjectSetInteger(chartID, objName, OBJPROP_RAY_RIGHT, rayRight); + + // + // hide true or display false graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return true; +} + +// +// Move trend line anchor point ... | +bool ChangeTrendLinePoint( + const long chartID = 0, // chart's ID + const string name = "TrendLine", // line name + const int pointindex = 0, // anchor point index + datetime time = 0, // anchor point time coordinate + double price = 0 // anchor point price coordinate +) +{ + // + // if point position is not set, move it to the current bar having Bid price ... + if (!time) + { + time = TimeCurrent(); + } + + // + if (!price) + { + price = SymbolInfoDouble(Symbol(), SYMBOL_BID); + } + + // + // reset the error value ... + ResetLastError(); + + // + // move trend line's anchor point ... + if (!ObjectMove(chartID, name, pointindex, time, price)) + { + // + string message = + __FUNCTION__ + + ": failed to move the anchor point! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// The function deletes the trend line from the chart ... +bool DeleteTrendLine( + const long chartID = 0, // chart's ID + const string name = "TrendLine" // line name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete a trend line ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete a trend line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Check the values of trend line's anchor points and set default ... +// values for empty ones ... +void ChangeTrendLineEmptyPoints( + datetime &time1, + double &price1, + datetime &time2, + double &price2) +{ + // + // if the first point's time is not set, it will be on the current bar ... + if (!time1) + { + time1 = TimeCurrent(); + } + + // + // if the first point's price is not set, it will have Bid value ... + if (!price1) + { + price1 = SymbolInfoDouble(Symbol(), SYMBOL_BID); + } + + // + // if the second point's time is not set, it is located 9 bars left from the second one ... + if (!time2) + { + // + // array for receiving the open time of the last 10 bars ... + datetime temp[10]; + CopyTime(Symbol(), Period(), time1, 10, temp); + + // + // set the second point 9 bars left from the first one ... + time2 = temp[0]; + } + + // + // if the second point's price is not set, it is equal to the first point's one ... + if (!price2) + { + price2 = price1; + } +} +// +// END TrendLine Functions ... +// + +// +// START Text Functions ... +// +// Create and Draw a Text Object ... +bool DrawText( + const long chartID = 0, // chart's ID + const string name = "Text", // object name + const int subWindow = 0, // subwindow index + datetime time = 0, // anchor point time + double price = 0, // anchor point price + const string text = "Text", // the text itself + const string font = "Arial", // font + const int fontSize = 10, // font size + const color clr = clrRed, // color + const double angle = 0.0, // text slope + const ENUM_ANCHOR_POINT anchor = ANCHOR_CENTER, // anchor type + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = true, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // set anchor point coordinates if they are not set ... + ChangeTextEmptyPoint(time, price); + + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // + // create Text object + if (!ObjectCreate(chartID, objName, OBJ_TEXT, subWindow, time, price)) + { + // + string message = + __FUNCTION__ + + ": failed to create \"Text\" object! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // set the text ... + ObjectSetString(chartID, objName, OBJPROP_TEXT, text); + + // + // set text font ... + ObjectSetString(chartID, objName, OBJPROP_FONT, font); + + // + // set font size ... + ObjectSetInteger(chartID, objName, OBJPROP_FONTSIZE, fontSize); + + // + // set the slope angle of the text ... + ObjectSetDouble(chartID, objName, OBJPROP_ANGLE, angle); + + // + // set anchor type ... + ObjectSetInteger(chartID, objName, OBJPROP_ANCHOR, anchor); + + // + // set color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // display in the foreground false or background true ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable true or disable false the mode of moving the object by mouse ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // hide true or display false graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return true; +} + +// +// Move the anchor point ... +bool MoveText( + const long chartID = 0, // chart's ID + const string name = "Text", // object name + datetime time = 0, // anchor point time coordinate + double price = 0 // anchor point price coordinate +) +{ + // + // + // if point position is not set, move it to the current bar having Bid price + if (!time) + { + time = TimeCurrent(); + } + + // + if (!price) + { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } + + // + // reset the error value ... + ResetLastError(); + + // + // move the anchor point .. + if (!ObjectMove(chartID, name, 0, time, price)) + { + // + string message = + __FUNCTION__ + + ": failed to move the anchor point! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Change the object text ... +bool ChangeText( + const long chartID = 0, // chart's ID + const string name = "Text", // object name + const string text = "Text" // text +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // change object text ... + if (!ObjectSetString(chartID, name, OBJPROP_TEXT, text)) + { + // + string message = + __FUNCTION__ + + ": failed to change the text! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Delete Text object ... +bool DeleteText( + const long chartID = 0, // chart's ID + const string name = "Text" // object name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete the object ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete \"Text\" object! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution + return true; +} + +// +// Check anchor point values and set default values +// for empty ones ... +void ChangeTextEmptyPoint( + datetime &time, + double &price) +{ + // + // if the point's time is not set, it will be on the current bar ... + if (!time) + { + time = TimeCurrent(); + } + + // + // if the point's price is not set, it will have Bid value ... + if (!price) + { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } +} +// +// END Text Functions ... +// + +// +// START Fibonacchi Functions ... +// +// +// Create Fibonacci Retracement by the given coordinates ... +bool DrawFibonacci( + const long chartID = 0, // chart's ID + const string name = "Fibonacci", // object name + const int subWindow = 0, // subwindow index + datetime time1 = 0, // first point time + double price1 = 0, // first point price + datetime time2 = 0, // second point time + double price2 = 0, // second point price + const color clr = clrRed, // object color + const ENUM_LINE_STYLE style = STYLE_SOLID, // object line style + const int width = 1, // object line width + const bool back = false, // in the background + const bool selection = true, // highlight to move + const bool rayRight = false, // object's continuation to the right + const bool hidden = true, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // set anchor points' coordinates if they are not set ... + ChangeFibonacciEmptyPoints(time1, price1, time2, price2); + + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // Create Fibonacci Retracement by the given coordinates ... + if (!ObjectCreate(chartID, objName, OBJ_FIBO, subWindow, time1, price1, time2, price2)) + { + // + string message = + __FUNCTION__ + + ": failed to create \"Fibonacci Retracement\"! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // set color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set line style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground false or background true ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable true or disable false the mode of highlighting the channel for moving + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // enable true or disable false the mode of continuation of the object's display to the right ... + ObjectSetInteger(chartID, objName, OBJPROP_RAY_RIGHT, rayRight); + + // + // hide true or display false graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return true; +} + +// +// Create Fibonacci Retracement by the given coordinates ... +bool DrawCustomFibonacci( + // + int levels, // number of level lines + double &values[], // values of level lines + color &colors[], // color of level lines + ENUM_LINE_STYLE &styles[], // style of level lines + int &widths[], // width of level lines + string &descriptions[], // level Descriptions + // + const long chartID = 0, // chart's ID + const string name = "Fibonacci", // object name + const int subWindow = 0, // subwindow index + datetime time1 = 0, // first point time + double price1 = 0, // first point price + datetime time2 = 0, // second point time + double price2 = 0, // second point price + const color clr = clrAqua, // object color + const ENUM_LINE_STYLE style = STYLE_DOT, // object line style + const int width = 1, // object line width + const bool back = false, // in the background + const bool selection = true, // highlight to move + const bool rayRight = false, // object's continuation to the right + const bool hidden = true, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // set anchor points' coordinates if they are not set ... + ChangeFibonacciEmptyPoints(time1, price1, time2, price2); + + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // Create Fibonacci Retracement by the given coordinates ... + if (!ObjectCreate(chartID, name, OBJ_FIBO, subWindow, time1, price1, time2, price2)) + { + // + string message = + __FUNCTION__ + + ": failed to create \"Fibonacci Retracement\"! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // set color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set line style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground false or background true ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable true or disable false the mode of highlighting the channel for moving + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // enable true or disable false the mode of continuation of the object's display to the right ... + ObjectSetInteger(chartID, objName, OBJPROP_RAY_RIGHT, rayRight); + + // + // hide true or display false graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // Change Levels Of Fibonacci ... + bool result = FibonacciLevelsSet( + levels, + values, + colors, + styles, + widths, + descriptions, + chartID, + objName); + + // + // successful execution ... + return result; +} + +// +// Set number of levels and their parameters ... +bool FibonacciLevelsSet( + int levels, // number of level lines + double &values[], // values of level lines + color &colors[], // color of level lines + ENUM_LINE_STYLE &styles[], // style of level lines + int &widths[], // width of level lines + string &descriptions[], // level Descriptions + const long chartID = 0, // chart's ID + const string name = "Fibonacci" // object name +) +{ + // + // check array sizes ... + if ( + levels != ArraySize(colors) || + levels != ArraySize(styles) || + levels != ArraySize(widths) || + levels != ArraySize(widths)) + { + // + string message = + __FUNCTION__ + + ": array length does not correspond to the number of levels, error!"; + + // + LogMessage(message); + + // + return false; + } + + // + // set the number of levels ... + ObjectSetInteger(chartID, name, OBJPROP_LEVELS, levels); + + // + // set the properties of levels in the loop ... + for (int i = 0; i < levels; i++) + { + // + // level value ... + ObjectSetDouble(chartID, name, OBJPROP_LEVELVALUE, i, values[i]); + + // + // level color ... + ObjectSetInteger(chartID, name, OBJPROP_LEVELCOLOR, i, colors[i]); + + // + // level style ... + ObjectSetInteger(chartID, name, OBJPROP_LEVELSTYLE, i, styles[i]); + + // + // level width ... + ObjectSetInteger(chartID, name, OBJPROP_LEVELWIDTH, i, widths[i]); + + // + // level description ... + // ObjectSetString(chartID, name, OBJPROP_LEVELTEXT, i, DoubleToString(100 * values[i], 1)); + ObjectSetString(chartID, name, OBJPROP_LEVELTEXT, i, descriptions[i]); + } + + // + // successful execution ... + return true; +} + +// +// Move Fibonacci Retracement anchor point ... +bool FibonacciPointChange( + const long chartID = 0, // chart's ID + const string name = "Fibonacci", // object name + const int pointIndex = 0, // anchor point index + datetime time = 0, // anchor point time coordinate + double price = 0 // anchor point price coordinate +) +{ + // + // if point position is not set, move it to the current bar having Bid price ... + if (!time) + { + time = TimeCurrent(); + } + + // + if (!price) + { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } + + // + // reset the error value ... + ResetLastError(); + + // + // move the anchor point ... + if (!ObjectMove(chartID, name, pointIndex, time, price)) + { + // + string message = + __FUNCTION__ + + ": failed to move the anchor point! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Delete Fibonacci Retracement ... +bool DeleteFibonachi( + const long chartID = 0, // chart's ID + const string name = "Fibonacci" // object name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete the object ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete \"Fibonacci Retracement\"! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} + +// +// Check the values of Fibonacci Retracement anchor points and set +// default values for empty ones ... +void ChangeFibonacciEmptyPoints( + datetime &time1, + double &price1, + datetime &time2, + double &price2) +{ + // + // if the second point's time is not set, it will be on the current bar ... + if (!time2) + { + time2 = TimeCurrent(); + } + + // + // if the second point's price is not set, it will have Bid value ... + if (!price2) + { + price2 = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } + + // + // if the first point's time is not set, it is located 9 bars left from the second one ... + if (!time1) + { + // + // array for receiving the open time of the last 10 bars ... + datetime temp[10]; + CopyTime(Symbol(), Period(), time2, 10, temp); + + // + // set the first point 9 bars left from the second one ... + time1 = temp[0]; + } + + // + // if the first point's price is not set, move it 200 points below the second one ... + if (!price1) + { + price1 = price2 - 200 * SymbolInfoDouble(_Symbol, SYMBOL_POINT); + } +} +// +// END Fibonacci Functions ... +// + +// +// START Event Functions ... +// + +// +// Create an Event ... +bool EventCreate( + const long chartID = 0, // chart's ID + const string name = "Event", // object name + const int subWindow = 0, // subwindow index + const string text = "Content", // event text + datetime time = 0, // anchor point time + const color clr = clrRed, // color + const int width = 1, // point width when highlighted + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = true, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + if (!time) + { + time = TimeCurrent(); + } + + // + ResetLastError(); + + // + if (!ObjectCreate(chartID, name, OBJ_EVENT, subWindow, time, 0)) + { + // + string message = + __FUNCTION__ + + ": failed to create \"Event\" object! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // set event text + ObjectSetString(chartID, name, OBJPROP_TEXT, text); + + // + // set color + ObjectSetInteger(chartID, name, OBJPROP_COLOR, clr); + + // + // set anchor point width if the object is highlighted + ObjectSetInteger(chartID, name, OBJPROP_WIDTH, width); + + // + // display in the foreground false or background true + ObjectSetInteger(chartID, name, OBJPROP_BACK, back); + + // + // enable true or disable false the mode of moving event by mouse + ObjectSetInteger(chartID, name, OBJPROP_SELECTABLE, selection); + ObjectSetInteger(chartID, name, OBJPROP_SELECTED, selection); + + // + // hide true or display false graphical object name in the object list + ObjectSetInteger(chartID, name, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart + ObjectSetInteger(chartID, name, OBJPROP_ZORDER, zOrder); + + // + // successful execution + return true; +} + +// +// Change Event object text +bool EventTextChange( + const long chartID = 0, // chart's ID + const string name = "Event", // event name + const string text = "Content" // text +) +{ + // + // reset the error value + ResetLastError(); + + // + // change object text + if (!ObjectSetString(chartID, name, OBJPROP_TEXT, text)) + { + // + string message = + __FUNCTION__ + + ": failed to change the text! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution + return true; +} + +// +// Move Event object +bool EventMove( + const long chartID = 0, // chart's ID + const string name = "Event", // event name + datetime time = 0 // time +) +{ + // + // if time is not set, move event to the last bar + if (!time) + { + time = TimeCurrent(); + } + + // + // reset the error value + ResetLastError(); + + // + // move the object + if (!ObjectMove(chartID, name, 0, time, 0)) + { + // + string message = + __FUNCTION__ + + ": failed to move \"Event\" object! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution + return true; +} + +// +// Delete Event object +bool EventDelete( + const long chartID = 0, // chart's ID + const string name = "Event" // event name +) +{ + // + // reset the error value + ResetLastError(); + + // + // delete the object + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete \"Event\" object! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution + return true; +} + +// +// END Event Functions ... +// + +// +// START Button Functions ... +// + +// +// Create the button ... +bool ButtonCreate( + const long chartID = 0, // chart's ID + const string name = "Button", // button name + const int subWindow = 0, // subwindow index + const int x = 0, // X coordinate + const int y = 0, // Y coordinate + const int width = 50, // button width + const int height = 15, // button height + const ENUM_BASE_CORNER corner = CORNER_LEFT_UPPER, // chart corner for anchoring + const string text = "Button", // text + const string font = "Arial", // font + const int fontSize = 8, // font size + const color clr = clrBlack, // text color + const color bgColor = clrLightGray, // background color + const color borderColor = clrNONE, // border color + const bool state = false, // pressed/released + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = true, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + bool result = false; + + // + // create the button + result = ObjectCreate(chartID, name, OBJ_BUTTON, subWindow, 0, 0); + if (!result) + { + return result; + } + + // + // set button coordinates + ObjectSetInteger(chartID, name, OBJPROP_XDISTANCE, x); + ObjectSetInteger(chartID, name, OBJPROP_YDISTANCE, y); + + // + // set button size + ObjectSetInteger(chartID, name, OBJPROP_XSIZE, width); + ObjectSetInteger(chartID, name, OBJPROP_YSIZE, height); + + // + // set the chart's corner, relative to which point coordinates are defined + ObjectSetInteger(chartID, name, OBJPROP_CORNER, corner); + + // + // set the text + ObjectSetString(chartID, name, OBJPROP_TEXT, text); + + // + // set text font + ObjectSetString(chartID, name, OBJPROP_FONT, font); + + // + // set font size + ObjectSetInteger(chartID, name, OBJPROP_FONTSIZE, fontSize); + + // + // set text color + ObjectSetInteger(chartID, name, OBJPROP_COLOR, clr); + + // + // set background color + ObjectSetInteger(chartID, name, OBJPROP_BGCOLOR, bgColor); + + // + // set border color + ObjectSetInteger(chartID, name, OBJPROP_BORDER_COLOR, borderColor); + + // + // display in the foreground false or background true + ObjectSetInteger(chartID, name, OBJPROP_BACK, back); + + // + // set button state + ObjectSetInteger(chartID, name, OBJPROP_STATE, state); + + // + // enable true or disable false the mode of moving the button by mouse + ObjectSetInteger(chartID, name, OBJPROP_SELECTABLE, selection); + ObjectSetInteger(chartID, name, OBJPROP_SELECTED, selection); + + // + // hide true or display false graphical object name in the object list + ObjectSetInteger(chartID, name, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart + ObjectSetInteger(chartID, name, OBJPROP_ZORDER, zOrder); + + // + return result; +} + +// +// Move the button ... +bool ButtonMove( + const long chartID = 0, // chart's ID + const string name = "Button", // button name + const int x = 0, // X coordinate + const int y = 0 // Y coordinate +) +{ + // + bool result = false; + + // + // move the button + + // + result = ObjectSetInteger(chartID, name, OBJPROP_XDISTANCE, x); + if (!result) + { + return result; + } + + // + result = ObjectSetInteger(chartID, name, OBJPROP_YDISTANCE, y); + + // + return result; +} + +// +// Change button size ... +bool ButtonChangeSize( + const long chartID = 0, // chart's ID + const string name = "Button", // button name + const int width = 50, // button width + const int height = 18 // button height +) +{ + // + bool result = false; + + // + // change the button size + + // + result = ObjectSetInteger(chartID, name, OBJPROP_XSIZE, width); + if (!result) + { + return result; + } + + // + result = ObjectSetInteger(chartID, name, OBJPROP_YSIZE, height); + + // + return result; +} + +// +// Change corner of the chart for binding the button ... +bool ButtonChangeCorner( + const long chartID = 0, // chart's ID + const string name = "Button", // button name + const ENUM_BASE_CORNER corner = CORNER_LEFT_UPPER // chart corner for anchoring +) +{ + // + bool result = false; + + // + // change anchor corner + + // + result = ObjectSetInteger(chartID, name, OBJPROP_CORNER, corner); + + // + return result; +} + +// +// Change button text ... +bool ButtonTextChange( + const long chartID = 0, // chart's ID + const string name = "Button", // button name + const string text = "Text" // text +) +{ + // + bool result = false; + + // + // change object text + result = ObjectSetString(chartID, name, OBJPROP_TEXT, text); + + // + return result; +} + +// +// Delete the button ... +bool ButtonDelete( + const long chartID = 0, // chart's ID + const string name = "Button" // button name +) +{ + // + bool result = false; + + // + // delete the button + result = ObjectDelete(chartID, name); + + // + return result; +} +// +// END Button Functions ... +// + +// +// END Regular Draws ... +// + +// +// START Chart Style Drawers ... +// +// +// Apply Styles On Chart ... +void ApplyChartStyle( + long mChartId = -1, // chart's ID + ENUM_CHART_MODE mMode = CHART_CANDLES, // chart's mMode + bool mShowBidLine = true, // show bid line + bool mShowAskLine = true, // show ask line + bool mShowGrid = false, // show grids on chart + bool mShowVolumes = false, // show volumes + bool mShowTradeLevels = true, // Displaying trade levels in the chart (levels of open positions, Stop Loss, Take Profit and pending orders) + bool mAutoScroll = true, // chart autoscroll + bool mQuickNavigation = true, // chart quick navigation state + color mForeGroundColor = clrWhite, // chart's foreground color + color mBackGroundColor = clrBlack, // chart's background color + color mUpColor = clrGreen, // Up Color + color mDownColor = clrRed, // Down Color + color mBullishColor = clrGreen, // Bullish color + color mBearishColor = clrRed, // Bearish color + color mGridColor = clrGray, // grid color + color mBidLineColor = clrGray, // bid line color + color mAskLineColor = clrRed, // ask line color + color mLineColor = clrLime, // line mMode and doji candlestick color + color mStopColor = clrGold, // Color of stop order levels (Stop Loss and Take Profit) + color mVolumesColor = clrGreen // volumes color +) +{ + // + // Validate Args ... + if (mChartId == -1) + { + mChartId = 0; + } + + // + ChartSetInteger(mChartId, CHART_MODE, mMode); + ChartSetInteger(mChartId, CHART_SHOW_BID_LINE, mShowBidLine); + ChartSetInteger(mChartId, CHART_SHOW_ASK_LINE, mShowAskLine); + ChartSetInteger(mChartId, CHART_SHOW_GRID, mShowGrid); + ChartSetInteger(mChartId, CHART_SHOW_VOLUMES, mShowVolumes); + ChartSetInteger(mChartId, CHART_SHOW_TRADE_LEVELS, mShowTradeLevels); + ChartSetInteger(mChartId, CHART_AUTOSCROLL, mAutoScroll); + ChartSetInteger(mChartId, CHART_QUICK_NAVIGATION, mQuickNavigation); + ChartSetInteger(mChartId, CHART_COLOR_FOREGROUND, mForeGroundColor); + ChartSetInteger(mChartId, CHART_COLOR_BACKGROUND, mBackGroundColor); + ChartSetInteger(mChartId, CHART_COLOR_CHART_UP, mUpColor); + ChartSetInteger(mChartId, CHART_COLOR_CHART_DOWN, mDownColor); + ChartSetInteger(mChartId, CHART_COLOR_CANDLE_BULL, mBullishColor); + ChartSetInteger(mChartId, CHART_COLOR_CANDLE_BEAR, mBearishColor); + ChartSetInteger(mChartId, CHART_COLOR_GRID, mGridColor); + ChartSetInteger(mChartId, CHART_COLOR_BID, mBidLineColor); + ChartSetInteger(mChartId, CHART_COLOR_ASK, mAskLineColor); + ChartSetInteger(mChartId, CHART_COLOR_STOP_LEVEL, mStopColor); + ChartSetInteger(mChartId, CHART_COLOR_CHART_LINE, mLineColor); + ChartSetInteger(mChartId, CHART_COLOR_VOLUME, mVolumesColor); +} + +// +// Retrieve Chart Size in Pixel ... +struct XSize +{ + long width; + long height; + + // + int x; + int y; + int w; + int h; + + // + int wStep; + int hStep; +}; + +// +// Retrieve Chart Size ... +bool GetChartSize( + XSize &result, // Holds Result ... + long chartID = 0 // Specified Chart ID ... +) +{ + // + bool mResult = false; + + // + mResult = ChartGetInteger(0, CHART_WIDTH_IN_PIXELS, 0, result.width); + if (!mResult) + { + return mResult; + } + + // + mResult = ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS, 0, result.height); + + // + return mResult; +} + +// +// END Chart Style Drawers ... +// \ No newline at end of file diff --git a/MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.http.lib.ex5 b/MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.http.lib.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..87463a3d27bde5f7e1d5e6a7074870044928fbb8 GIT binary patch literal 3554 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 NK1?j0Q$7F>{0Gk}g+BlQ literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.http.lib.mq5 b/MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.http.lib.mq5 new file mode 100644 index 0000000..97f7ac0 --- /dev/null +++ b/MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.http.lib.mq5 @@ -0,0 +1,177 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Http Library +// ------------------------------------------ +// Name: XHttp +// Description: provide http communication +// abilities ... +// +// +// 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 + +// +// START Model Definition ... +// +enum X_HTTP_METHOD +{ + X_HTTP_GET, + X_HTTP_POST +}; +// +// END Model Definition ... +// + +// +// START Inputs ... +// +// +// END Inputs ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// +// +// Initial Library if required ... +bool OnInInitHttpLibrary() +{ + return false; +} + +// +// DeInitial Library if required ... +void OnDeinitHttpLibrary() +{ +} + +// +// Convert enum to String ... +string ToString(X_HTTP_METHOD method) +{ + // + string result = ""; + + // + switch (method) + { + // + case X_HTTP_GET: + result = "GET"; + break; + + // + case X_HTTP_POST: + result = "POST"; + break; + } + + // + return result; +} + +// +// Send Global Request ... +int SendRequest( + X_HTTP_METHOD method, // Httm Request Method + const string url, // Server Address + const string headers, // Headers providing + const char &payload[], // the Data which needs to Send + char &response[], // Response of request + string responseHeaders, // Response Headers + int timeout = 500 // Timeout for response default is 500 +) +{ + // + int result = -1; + + // + string strMethod = ToString(method); + if (StringLen(strMethod) == 0) { + return result; + } + + // + result = WebRequest( + strMethod, + url, + headers, + timeout, + payload, + response, + responseHeaders + ); + + // + return result; +} + +// +// Get Request ... +int GetRequest( + const string url, // Server Address + const string headers, // Headers providing + const char &payload[], // the Data which needs to Send + char &response[], // Response of request + string responseHeaders, // Response Headers + int timeout = 500 // Timeout for response default is 500 +) { + // + int result = SendRequest( + X_HTTP_GET, + url, + headers, + payload, + response, + responseHeaders, + timeout + ); + + // + return result; +} + +// +// Post Request ... +int PostRequest( + const string url, // Server Address + const string headers, // Headers providing + const char &payload[], // the Data which needs to Send + char &response[], // Response of request + string responseHeaders, // Response Headers + int timeout = 500 // Timeout for response default is 500 +) { + // + int result = SendRequest( + X_HTTP_POST, + url, + headers, + payload, + response, + responseHeaders, + timeout + ); + + // + return result; +} +// +// END Provided Functions ... +// diff --git a/MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.log.lib.ex5 b/MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.log.lib.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..cf6a0ccb70aa806d695dbd4169332e6c3f1e6448 GIT binary patch literal 5860 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 iU3yIP9;(G4^R*oAYbXrQm|CHW` ", message); +} +void LogMessage(string tag, string message) +{ + // + if (!enableLogging) + { + return; + } + + // + Print(tag, " > ", message); +} + +// +void LogEmptyLine() +{ + LogMessage(" "); +} + +// +void LogError( + int error = -1 // Specific Error +) { + // + if (error <= -1) { + error = GetLastError(); + } + + // + string errorMsg = GetErrorDescription(error); + + // + LogMessage("Error: " + errorMsg); +} + +// +// Logging an Array ... +void LogArray(int &array[]) +{ + // + if (!enableLogging) + { + return; + } + + // + Print(logTag, ">"); + ArrayPrint(array); +} +void LogArray(double &array[]) +{ + // + if (!enableLogging) + { + return; + } + + // + Print(logTag, ">"); + ArrayPrint(array); +} +void LogArray(string &array[]) +{ + // + if (!enableLogging) + { + return; + } + + // + Print(logTag, ">"); + ArrayPrint(array); +} +// +// END Provided Functions ... +// + + +// +// Error Descriptions Functions ... +// + +// +// Retrieve Specified Error Code Description ... +string GetErrorDescription(int err_code) +{ + // + string result = ""; + + // + switch (err_code) + { + // + //--- Constant Description + + // + case ERR_SUCCESS: + result = "The operation completed successfully"; + break; + + // + case ERR_INTERNAL_ERROR: + result = "Unexpected internal error"; + break; + + // + case ERR_WRONG_INTERNAL_PARAMETER: + result = "Wrong parameter in the inner call of the client terminal function"; + break; + + // + case ERR_INVALID_PARAMETER: + result = "Wrong parameter when calling the system function"; + break; + + // + case ERR_NOT_ENOUGH_MEMORY: + result = "Not enough memory to perform the system function"; + break; + + // + case ERR_STRUCT_WITHOBJECTS_ORCLASS: + result = "The structure contains objects of strings and/or dynamic arrays and/or structure of such objects and/or classes"; + break; + + // + case ERR_INVALID_ARRAY: + result = "Array of a wrong type, wrong size, or a damaged object of a dynamic array"; + break; + + // + case ERR_ARRAY_RESIZE_ERROR: + result = "Not enough memory for the relocation of an array, or an attempt to change the size of a static array"; + break; + + // + case ERR_STRING_RESIZE_ERROR: + result = "Not enough memory for the relocation of string"; + break; + + // + case ERR_NOTINITIALIZED_STRING: + result = "Not initialized string"; + break; + + // + case ERR_INVALID_DATETIME: + result = "Invalid date and/or time"; + break; + + // + case ERR_ARRAY_BAD_SIZE: + result = "Requested array size exceeds 2 GB"; + break; + + // + case ERR_INVALID_POINTER: + result = "Wrong pointer"; + break; + + // + case ERR_INVALID_POINTER_TYPE: + result = "Wrong type of pointer"; + break; + + // + case ERR_FUNCTION_NOT_ALLOWED: + result = "System function is not allowed to call"; + break; + + // + //--- Charts + + // + case ERR_CHART_WRONG_ID: + result = "Wrong chart ID"; + break; + + // + case ERR_CHART_NO_REPLY: + result = "Chart does not respond"; + break; + + // + case ERR_CHART_NOT_FOUND: + result = "Chart not found"; + break; + + // + case ERR_CHART_NO_EXPERT: + result = "No Expert Advisor in the chart that could handle the event"; + break; + + // + case ERR_CHART_CANNOT_OPEN: + result = "Chart opening error"; + break; + + // + case ERR_CHART_CANNOT_CHANGE: + result = "Failed to change chart symbol and period"; + break; + + // + case ERR_CHART_CANNOT_CREATE_TIMER: + result = "Failed to create timer"; + break; + + // + case ERR_CHART_WRONG_PROPERTY: + result = "Wrong chart property ID"; + break; + + // + case ERR_CHART_SCREENSHOT_FAILED: + result = "Error creating screenshots"; + break; + + // + case ERR_CHART_NAVIGATE_FAILED: + result = "Error navigating through chart"; + break; + + // + case ERR_CHART_TEMPLATE_FAILED: + result = "Error applying template"; + break; + + // + case ERR_CHART_WINDOW_NOT_FOUND: + result = "Subwindow containing the indicator was not found"; + break; + + // + case ERR_CHART_INDICATOR_CANNOT_ADD: + result = "Error adding an indicator to chart"; + break; + + // + case ERR_CHART_INDICATOR_CANNOT_DEL: + result = "Error deleting an indicator from the chart"; + break; + + // + case ERR_CHART_INDICATOR_NOT_FOUND: + result = "Indicator not found on the specified chart"; + break; + + // + //--- Graphical Objects + case ERR_OBJECT_ERROR: + result = "Error working with a graphical object"; + break; + + // + case ERR_OBJECT_NOT_FOUND: + result = "Graphical object was not found"; + break; + + // + case ERR_OBJECT_WRONG_PROPERTY: + result = "Wrong ID of a graphical object property"; + break; + + // + case ERR_OBJECT_GETDATE_FAILED: + result = "Unable to get date corresponding to the value"; + break; + + // + case ERR_OBJECT_GETVALUE_FAILED: + result = "Unable to get value corresponding to the date"; + break; + + // + //--- MarketInfo + + // + case ERR_MARKET_UNKNOWN_SYMBOL: + result = "Unknown symbol"; + break; + + // + case ERR_MARKET_NOT_SELECTED: + result = "Symbol is not selected in MarketWatch"; + break; + + // + case ERR_MARKET_WRONG_PROPERTY: + result = "Wrong identifier of a symbol property"; + break; + + // + case ERR_MARKET_LASTTIME_UNKNOWN: + result = "Time of the last tick is not known (no ticks)"; + break; + + // + case ERR_MARKET_SELECT_ERROR: + result = "Error adding or deleting a symbol in MarketWatch"; + break; + + // + //--- History Access + + // + case ERR_HISTORY_NOT_FOUND: + result = "Requested history not found"; + break; + + // + case ERR_HISTORY_WRONG_PROPERTY: + result = "Wrong ID of the history property"; + break; + + // + //--- Global_Variables + + // + case ERR_GLOBALVARIABLE_NOT_FOUND: + result = "Global variable of the client terminal is not found"; + break; + + // + case ERR_GLOBALVARIABLE_EXISTS: + result = "Global variable of the client terminal with the same name already exists"; + break; + + // + case ERR_MAIL_SEND_FAILED: + result = "Email sending failed"; + break; + + // + case ERR_PLAY_SOUND_FAILED: + result = "Sound playing failed"; + break; + + // + case ERR_MQL5_WRONG_PROPERTY: + result = "Wrong identifier of the program property"; + break; + + // + case ERR_TERMINAL_WRONG_PROPERTY: + result = "Wrong identifier of the terminal property"; + break; + + // + case ERR_FTP_SEND_FAILED: + result = "File sending via ftp failed"; + break; + + // + case ERR_NOTIFICATION_SEND_FAILED: + result = "Error in sending notification"; + break; + + // + //--- Custom Indicator Buffers + + // + case ERR_BUFFERS_NO_MEMORY: + result = "Not enough memory for the distribution of indicator buffers"; + break; + + // + case ERR_BUFFERS_WRONG_INDEX: + result = "Wrong indicator buffer index"; + break; + + // + //--- Custom Indicator Properties + + // + case ERR_CUSTOM_WRONG_PROPERTY: + result = "Wrong ID of the custom indicator property"; + break; + + // + //--- Account + + // + case ERR_ACCOUNT_WRONG_PROPERTY: + result = "Wrong account property ID"; + break; + + // + case ERR_TRADE_WRONG_PROPERTY: + result = "Wrong trade property ID"; + break; + + // + case ERR_TRADE_DISABLED: + result = "Trading by Expert Advisors prohibited"; + break; + + // + case ERR_TRADE_POSITION_NOT_FOUND: + result = "Position not found"; + break; + + // + case ERR_TRADE_ORDER_NOT_FOUND: + result = "Order not found"; + break; + + // + case ERR_TRADE_DEAL_NOT_FOUND: + result = "Deal not found"; + break; + + // + case ERR_TRADE_SEND_FAILED: + result = "Trade request sending failed"; + break; + + // + //--- Indicators + + // + case ERR_INDICATOR_UNKNOWN_SYMBOL: + result = "Unknown symbol"; + break; + + // + case ERR_INDICATOR_CANNOT_CREATE: + result = "Indicator cannot be created"; + break; + + // + case ERR_INDICATOR_NO_MEMORY: + result = "Not enough memory to add the indicator"; + break; + + // + case ERR_INDICATOR_CANNOT_APPLY: + result = "The indicator cannot be applied to another indicator"; + break; + + // + case ERR_INDICATOR_CANNOT_ADD: + result = "Error applying an indicator to chart"; + break; + + // + case ERR_INDICATOR_DATA_NOT_FOUND: + result = "Requested data not found"; + break; + + // + case ERR_INDICATOR_WRONG_HANDLE: + result = "Wrong indicator handle"; + break; + + // + case ERR_INDICATOR_WRONG_PARAMETERS: + result = "Wrong number of parameters when creating an indicator"; + break; + + // + case ERR_INDICATOR_PARAMETERS_MISSING: + result = "No parameters when creating an indicator"; + break; + + // + case ERR_INDICATOR_CUSTOM_NAME: + result = "The first parameter in the array must be the name of the custom indicator"; + break; + + // + case ERR_INDICATOR_PARAMETER_TYPE: + result = "Invalid parameter type in the array when creating an indicator"; + break; + + // + case ERR_INDICATOR_WRONG_INDEX: + result = "Wrong index of the requested indicator buffer"; + break; + + // + //--- Depth of Market + + // + case ERR_BOOKS_CANNOT_ADD: + result = "Depth Of Market can not be added"; + break; + + // + case ERR_BOOKS_CANNOT_DELETE: + result = "Depth Of Market can not be removed"; + break; + + // + case ERR_BOOKS_CANNOT_GET: + result = "The data from Depth Of Market can not be obtained"; + break; + + // + case ERR_BOOKS_CANNOT_SUBSCRIBE: + result = "Error in subscribing to receive new data from Depth Of Market"; + break; + + // + //--- File Operations + + // + case ERR_TOO_MANY_FILES: + result = "More than 64 files cannot be opened at the same time"; + break; + + // + case ERR_WRONG_FILENAME: + result = "Invalid file name"; + break; + + // + case ERR_TOO_LONG_FILENAME: + result = "Too long file name"; + break; + + // + case ERR_CANNOT_OPEN_FILE: + result = "File opening error"; + break; + + // + case ERR_FILE_CACHEBUFFER_ERROR: + result = "Not enough memory for cache to read"; + break; + + // + case ERR_CANNOT_DELETE_FILE: + result = "File deleting error"; + break; + + // + case ERR_INVALID_FILEHANDLE: + result = "A file with this handle was closed, or was not opening at all"; + break; + + // + case ERR_WRONG_FILEHANDLE: + result = "Wrong file handle"; + break; + + // + case ERR_FILE_NOTTOWRITE: + result = "The file must be opened for writing"; + break; + + // + case ERR_FILE_NOTTOREAD: + result = "The file must be opened for reading"; + break; + + // + case ERR_FILE_NOTBIN: + result = "The file must be opened as a binary one"; + break; + + // + case ERR_FILE_NOTTXT: + result = "The file must be opened as a text"; + break; + + // + case ERR_FILE_NOTTXTORCSV: + result = "The file must be opened as a text or CSV"; + break; + + // + case ERR_FILE_NOTCSV: + result = "The file must be opened as CSV"; + break; + + // + case ERR_FILE_READERROR: + result = "File reading error"; + break; + + // + case ERR_FILE_BINSTRINGSIZE: + result = "String size must be specified, because the file is opened as binary"; + break; + + // + case ERR_INCOMPATIBLE_FILE: + result = "A text file must be for string arrays, for other arrays - binary"; + break; + + // + case ERR_FILE_IS_DIRECTORY: + result = "This is not a file, this is a directory"; + break; + + // + case ERR_FILE_NOT_EXIST: + result = "File does not exist"; + break; + + // + case ERR_FILE_CANNOT_REWRITE: + result = "File can not be rewritten"; + break; + + // + case ERR_WRONG_DIRECTORYNAME: + result = "Wrong directory name"; + break; + + // + case ERR_DIRECTORY_NOT_EXIST: + result = "Directory does not exist"; + break; + + // + case ERR_FILE_ISNOT_DIRECTORY: + result = "This is a file, not a directory"; + break; + + // + case ERR_CANNOT_DELETE_DIRECTORY: + result = "The directory cannot be removed"; + break; + + // + case ERR_CANNOT_CLEAN_DIRECTORY: + result = "Failed to clear the directory (probably one or more files are blocked and removal operation failed)"; + break; + + // + case ERR_FILE_WRITEERROR: + result = "Failed to write a resource to a file"; + break; + + // + //--- String Casting + + // + case ERR_NO_STRING_DATE: + result = "No date in the string"; + break; + + // + case ERR_WRONG_STRING_DATE: + result = "Wrong date in the string"; + break; + + // + case ERR_WRONG_STRING_TIME: + result = "Wrong time in the string"; + break; + + // + case ERR_STRING_TIME_ERROR: + result = "Error converting string to date"; + break; + + // + case ERR_STRING_OUT_OF_MEMORY: + result = "Not enough memory for the string"; + break; + + // + case ERR_STRING_SMALL_LEN: + result = "The string length is less than expected"; + break; + + // + case ERR_STRING_TOO_BIGNUMBER: + result = "Too large number, more than ULONG_MAX"; + break; + + // + case ERR_WRONG_FORMATSTRING: + result = "Invalid format string"; + break; + + // + case ERR_TOO_MANY_FORMATTERS: + result = "Amount of format specifiers more than the parameters"; + break; + + // + case ERR_TOO_MANY_PARAMETERS: + result = "Amount of parameters more than the format specifiers"; + break; + + // + case ERR_WRONG_STRING_PARAMETER: + result = "Damaged parameter of string type"; + break; + + // + case ERR_STRINGPOS_OUTOFRANGE: + result = "Position outside the string"; + break; + + // + case ERR_STRING_ZEROADDED: + result = "0 added to the string end, a useless operation"; + break; + + // + case ERR_STRING_UNKNOWNTYPE: + result = "Unknown data type when converting to a string"; + break; + + // + case ERR_WRONG_STRING_OBJECT: + result = "Damaged string object"; + break; + + // + //--- Operations with Arrays + + // + case ERR_INCOMPATIBLE_ARRAYS: + result = "Copying incompatible arrays. String array can be copied only to a string array, and a numeric array - in numeric array only"; + break; + + // + case ERR_SMALL_ASSERIES_ARRAY: + result = "The receiving array is declared as AS_SERIES, and it is of insufficient size"; + break; + + // + case ERR_SMALL_ARRAY: + result = "Too small array, the starting position is outside the array"; + break; + + // + case ERR_ZEROSIZE_ARRAY: + result = "An array of zero length"; + break; + + // + case ERR_NUMBER_ARRAYS_ONLY: + result = "Must be a numeric array"; + break; + + // + case ERR_ONEDIM_ARRAYS_ONLY: + result = "Must be a one-dimensional array"; + break; + + // + case ERR_SERIES_ARRAY: + result = "Timeseries cannot be used"; + break; + + // + case ERR_DOUBLE_ARRAY_ONLY: + result = "Must be an array of type double"; + break; + + // + case ERR_FLOAT_ARRAY_ONLY: + result = "Must be an array of type float"; + break; + + // + case ERR_LONG_ARRAY_ONLY: + result = "Must be an array of type long"; + break; + + // + case ERR_INT_ARRAY_ONLY: + result = "Must be an array of type int"; + break; + + // + case ERR_SHORT_ARRAY_ONLY: + result = "Must be an array of type short"; + break; + + // + case ERR_CHAR_ARRAY_ONLY: + result = "Must be an array of type char"; + break; + + // + //--- Operations with OpenCL + + // + case ERR_OPENCL_NOT_SUPPORTED: + result = "OpenCL functions are not supported on this computer"; + break; + + // + case ERR_OPENCL_INTERNAL: + result = "Internal error occurred when running OpenCL"; + break; + + // + case ERR_OPENCL_INVALID_HANDLE: + result = "Invalid OpenCL handle"; + break; + + // + case ERR_OPENCL_CONTEXT_CREATE: + result = "Error creating the OpenCL context"; + break; + + // + case ERR_OPENCL_QUEUE_CREATE: + result = "Failed to create a run queue in OpenCL"; + break; + + // + case ERR_OPENCL_PROGRAM_CREATE: + result = "Error occurred when compiling an OpenCL program"; + break; + + // + case ERR_OPENCL_TOO_LONG_KERNEL_NAME: + result = "Too long kernel name (OpenCL kernel)"; + break; + + // + case ERR_OPENCL_KERNEL_CREATE: + result = "Error creating an OpenCL kernel"; + break; + + // + case ERR_OPENCL_SET_KERNEL_PARAMETER: + result = "Error occurred when setting parameters for the OpenCL kernel"; + break; + + // + case ERR_OPENCL_EXECUTE: + result = "OpenCL program runtime error"; + break; + + // + case ERR_OPENCL_WRONG_BUFFER_SIZE: + result = "Invalid size of the OpenCL buffer"; + break; + + // + case ERR_OPENCL_WRONG_BUFFER_OFFSET: + result = "Invalid offset in the OpenCL buffer"; + break; + + // + case ERR_OPENCL_BUFFER_CREATE: + result = "Failed to create and OpenCL buffer"; + break; + + // + //--- User-Defined Errors + default: + result = "UNKNOWN Erro ..."; + break; + } + + // + return result; +} + +// +// Retrieve Specified Error Code Description ... +string GetTradeServerReturnCodeDescription(int return_code) +{ + // + string result = ""; + + // + switch (return_code) + { + // + case TRADE_RETCODE_REQUOTE: + result = "Requote"; + break; + + // + case TRADE_RETCODE_REJECT: + result = "Request rejected"; + break; + + // + case TRADE_RETCODE_CANCEL: + result = "Request canceled by trader"; + break; + + // + case TRADE_RETCODE_PLACED: + result = "Order placed"; + break; + + // + case TRADE_RETCODE_DONE: + result = "Request completed"; + break; + + // + case TRADE_RETCODE_DONE_PARTIAL: + result = "Only part of the request was completed"; + break; + + // + case TRADE_RETCODE_ERROR: + result = "Request processing error"; + break; + + // + case TRADE_RETCODE_TIMEOUT: + result = "Request canceled by timeout"; + break; + + // + case TRADE_RETCODE_INVALID: + result = "Invalid request"; + break; + + // + case TRADE_RETCODE_INVALID_VOLUME: + result = "Invalid volume in the request"; + break; + + // + case TRADE_RETCODE_INVALID_PRICE: + result = "Invalid price in the request"; + break; + + // + case TRADE_RETCODE_INVALID_STOPS: + result = "Invalid stops in the request"; + break; + + // + case TRADE_RETCODE_TRADE_DISABLED: + result = "Trade is disabled"; + break; + + // + case TRADE_RETCODE_MARKET_CLOSED: + result = "Market is closed"; + break; + + // + case TRADE_RETCODE_NO_MONEY: + result = "There is not enough money to complete the request"; + break; + + // + case TRADE_RETCODE_PRICE_CHANGED: + result = "Prices changed"; + break; + + // + case TRADE_RETCODE_PRICE_OFF: + result = "There are no quotes to process the request"; + break; + + // + case TRADE_RETCODE_INVALID_EXPIRATION: + result = "Invalid order expiration date in the request"; + break; + + // + case TRADE_RETCODE_ORDER_CHANGED: + result = "Order state changed"; + break; + + // + case TRADE_RETCODE_TOO_MANY_REQUESTS: + result = "Too frequent requests"; + break; + + // + case TRADE_RETCODE_NO_CHANGES: + result = "No changes in request"; + break; + + // + case TRADE_RETCODE_SERVER_DISABLES_AT: + result = "Autotrading disabled by server"; + break; + + // + case TRADE_RETCODE_CLIENT_DISABLES_AT: + result = "Autotrading disabled by client terminal"; + break; + + // + case TRADE_RETCODE_LOCKED: + result = "Request locked for processing"; + break; + + // + case TRADE_RETCODE_FROZEN: + result = "Order or position frozen"; + break; + + // + case TRADE_RETCODE_INVALID_FILL: + result = "Invalid order filling type"; + break; + + // + case TRADE_RETCODE_CONNECTION: + result = "No connection with the trade server"; + break; + + // + case TRADE_RETCODE_ONLY_REAL: + result = "Operation is allowed only for live accounts"; + break; + + // + case TRADE_RETCODE_LIMIT_ORDERS: + result = "The number of pending orders has reached the limit"; + break; + + // + case TRADE_RETCODE_LIMIT_VOLUME: + result = "The volume of orders and positions for the symbol has reached the limit"; + break; + + // + default: + result = "Invalid return code of the trade server"; + break; + } + + // + return result; +} diff --git a/MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.models.lib.ex5 b/MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.models.lib.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..243afa6bb6e10b55a0d0a5f23a4af32919fed7ac GIT binary patch literal 4868 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 W +void Add( + T &item, + T &buffer[]) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} + +template +void Clean(T &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} + +template +void Copy( + T &source[], // Source Buffer ... + T &dest[], // Dest Buffer ... + bool cleanDest = true // Force Clen Dest Buffer ... +) +{ + // + if (cleanDest) + { + Clean(dest); + } + + // + int sourceCount = ArraySize(source); + if (sourceCount <= 0) + { + return; + } + + // + for (int i = 0; i < sourceCount; i++) + { + // + T iSource = source[i]; + + // + Add( + iSource, + dest); + } +} + +// +// END Provided Functions ... +// diff --git a/MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.seriallizer.lib.ex5 b/MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.seriallizer.lib.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..d0c83c51f9a52c2baa9e5fb760cb949475e642e9 GIT binary patch literal 9686 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 J{|kzbcoYBt literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.seriallizer.lib.mq5 b/MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.seriallizer.lib.mq5 new file mode 100644 index 0000000..2c7aa24 --- /dev/null +++ b/MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.seriallizer.lib.mq5 @@ -0,0 +1,1273 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Seriallize Library +// --------------------------------------- +// Name: XSeriallizer +// Description: provides Seriallizing EA abilities ... +// +// +// 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 + +// +#include "../Libraries/x-saherelm.models.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xtrade.class.mq5" +#include "../Classes/x-saherelm.x121.provider.class.mq5" + +// +string XProviderToken = "PRV"; +string XSupportToken = "SP"; +string XSLTrailToken = "SLT"; +string XPeriodToken = "PR"; + +// +string XConfigToken = "XPV"; +string XItemSeparator = "|"; +string XItemContentSeparator = ","; + +// +// PERIOD ... + +// +// Detect a Comment has period or not ... +bool HasPeriod(string comment) +{ + // + bool result = false; + + // + if (StringLen(comment) == 0) + { + return result; + } + + // + int tokenPos = StringFind( + comment, + XPeriodToken); + result = tokenPos >= 0; + + // + return result; +} + +// +// Extract Period String ... +string ExtractPeriodString(string comment) +{ + // + string result = ""; + + // + bool hasPeriod = HasPeriod(comment); + if (!hasPeriod) + { + return result; + } + + // + result = ExtractString( + comment, + XPeriodToken + "(", + ")"); + + // + return result; +} + +// +// Extract Time Frame From Comment ... +ENUM_TIMEFRAMES ExtractPeriod(string comment) +{ + // + ENUM_TIMEFRAMES result = NULL; + + // + if (StringLen(comment) <= 0) + { + return result; + } + + // + string periodStr = ExtractPeriodString(comment); + if (StringLen(periodStr) <= 0) + { + return result; + } + + // + result = ToPeriod(periodStr); + + // + return result; +} + +// +// PROVIDER ... + +// +// Extract a Provider name if exists from a Comment ... +string ExtractProvider(string comment) +{ + // + string result = ""; + if (StringLen(comment) <= 0) + { + return result; + } + + // + result = ExtractString( + comment, + XProviderToken + "(", + ")"); + + // + return result; +} + +// +// Generate Provider String for Using in Positions Comment ... +// NOTE: if there is more than One Provider, it takes first +// provider as main and the others used to increase volume ... +string GenerateProvidersString(XSignal &signal) +{ + // + string result = ""; + + // + int providersCount = ArraySize(signal.providers); + if (providersCount <= 0) + { + return result; + } + + // + result = XProviderToken + "(" + signal.providers[0] + ")"; + + // + return result; +} + +// +// SLTRAIL ... + +// +string GenerateSLTrailComment(int level) +{ + // + string result = ""; + + // + if (level <= 0) + { + return result; + } + + // + result = XSLTrailToken + "(" + ToString(level) + ")"; + + // + return result; +} + +// +int ExtractSLTrailLevel(string comment) +{ + // + int result = 0; + + // + if (StringLen(comment) == 0) + { + return result; + } + + // + string levelStr = ExtractString( + comment, + XSLTrailToken + "(", + ")"); + if (StringLen(levelStr) == 0) + { + return result; + } + + // + result = (int)levelStr; + + // + return result; +} + +// +string PrepareSLTrailComment( + const string comment // Original Position Comment ... +) +{ + // + string result = ""; + + // + if (StringLen(comment) == 0) + { + return result; + } + + // + int level = 0; + result = comment; + + // + // Check Comment Contains SL Trailing or not ... + int lastTrailLevel = ExtractSLTrailLevel(comment); + if (lastTrailLevel <= 0) + { + level++; + } + else + { + // + level = lastTrailLevel + 1; + string lastLevelStr = GenerateSLTrailComment(lastTrailLevel); + StringReplace( + result, + lastLevelStr, + ""); + } + + // + // Generate level Comment ... + string levelStr = GenerateSLTrailComment(level); + result += levelStr; + + // + return result; +} + +// +// SUPPORT ... + +// +// Generate Specific Position's Support Comment +// index is number of Supports ... +string GenerateSupportSignalComment( + ulong ticket, // Position/Order Ticket + int index // Support Index ... +) +{ + // + string result = ""; + + // + result = XSupportToken + "(" + (string)ticket + "," + ToString(index) + ")"; + + // + return result; +} + +// +// Extract Support Parameters String from specified Comment ... +string ExtractSupportParam(string comment) +{ + // + string result = ""; + if (StringLen(comment) <= 0) + { + return result; + } + + // + result = ExtractString( + comment, + XSupportToken + "(", + ")"); + + // + return result; +} + +// +// Extract Support Info as String array for Specific Comment ... +bool ExtractSupportParams( + string comment, // Specified Comment ... + string ¶ms[] // Hold Result ... +) +{ + // + bool result = false; + + // + string supParam = ExtractSupportParam(comment); + if (StringLen(supParam) == 0) + { + return result; + } + + // + SplitContent( + params, + supParam); + int paramsCount = ArraySize(params); + + // + result = paramsCount == 2; + + // + return result; +} + +// +// Extract Support Parent Ticket ... +ulong ExtractParentTicket(string comment) +{ + // + ulong result = 0; + + // + string params[]; + bool isSupport = ExtractSupportParams( + comment, + params); + if (!isSupport) + { + return result; + } + + // + result = (ulong)params[0]; + + // + return result; +} + +// +// Extract Support Index ... +int ExtractSupportIndex(string comment) +{ + // + int result = -1; + + // + string params[]; + bool isSupport = ExtractSupportParams( + comment, + params); + if (!isSupport) + { + return result; + } + + // + result = (int)params[1]; + + // + return result; +} + +// +// XCONFIG X121Provider Struct ... + +// +// Extract Signallers from User Input ... +int ExtractSignallers( + string &result[], // Hold Result + const string source // Source Content +) +{ + // + int mResult = 0; + + // + Clean(result); + + // + SplitContent( + result, + source); + + // + mResult = ArraySize(result); + + // + return mResult; +} + +// +// Validate Specified Provider Descriptor Model ... +bool IsValid(X121SignalProvider &item) +{ + // + bool result = false; + + // + result = + // + StringLen(item.symbol) > 0 && + item.period != NULL && + item.riskAmount > 0 + // + ; + + // + return result; +} + +// +// Compare Source item with Dest item to check their Same or not ... +bool IsSame( + X121SignalProvider &source, // Source Item + X121SignalProvider &dest // Dest Item +) +{ + // + bool result = false; + + // + bool isValidDest = IsValid(dest); + bool isValidSource = IsValid(source); + if (!isValidDest || + !isValidSource) + { + return result; + } + + // + result = + // + source.symbol == dest.symbol && + source.period == dest.period && + source.riskAmount == dest.riskAmount && + source.useRiskAmountAsStaticVolume == dest.useRiskAmountAsStaticVolume + // + ; + + // + return result; +} + +// +// Check Specified Provider Exists in a Collection or not ... +bool Contains( + X121SignalProvider &item, // Specified Item + X121SignalProvider &items[] // Given Collection +) +{ + // + bool result = false; + + // + int itemsCount = ArraySize(items); + if (itemsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < itemsCount; i++) + { + // + X121SignalProvider iProvider = items[i]; + + // + result = IsSame(item, iProvider); + if (result) + { + // + break; + } + } + + // + return result; +} + +// +// Extract Provider Descriptor Parts from given Source Input ... +int ExtractProviderDescriptorItems( + string &result[], // Hold Result + const string source // Source Descriptor +) +{ + // + int mResult = 0; + + // + Clean(result); + + // + SplitContent( + result, + source, + XItemSeparator); + + // + mResult = ArraySize(result); + + // + return mResult; +} + +// +// Extract Provider Descriptor Items Content from given Source Input ... +int ExtractProviderDescriptorItemsContent( + string &result[], // Hold Result + const string source // Source Descriptor +) +{ + // + int mResult = 0; + + // + Clean(result); + + // + SplitContent( + result, + source, + XItemContentSeparator); + + // + mResult = ArraySize(result); + + // + return mResult; +} + +// +// Validate and add provider to providers if not exists ... +bool AddProviderDescriptor( + X121SignalProvider &item, + X121SignalProvider &items[]) +{ + // + bool result = false; + + // + // Validate and add ... + result = IsValid(item); + if (!result) + { + return result; + } + + // + bool isExists = Contains( + item, + items); + if (isExists) + { + return result; + } + + // + result = true; + + // + Add( + item, + items); + + // + return result; +} + +// +// Extract Provider Descriptors from given Source Input ... +int ExtractProviderConfigurations( + X121SignalProvider &result[], // Hold Result + const string source, // Source String + const string defaultSignallers, // Default Available Signallers for Each Providers + const double defaultRiskAmount, // Default Risk Amount per Trade for Each Provider + const bool useRiskAmountAsStaticVolume = true // Use Provided Risk Amount as Static Volume +) +{ + // + int mResult = 0; + + // + Clean(result); + + // + // if there is no Pairs ... + // Check as One Model ... + string descriptors[]; + mResult = ExtractStrings( + descriptors, + source, + XConfigToken + "(", + ")"); + + // + // Retrieve Signallers ... + string defaultSignallersArr[]; + ExtractSignallers( + defaultSignallersArr, + defaultSignallers); + + // + if (mResult == 0) + { + // + // Here we Check given source String Length ... + // if it is bigger than zero we assuem it is one line descriptor ... + if (StringLen(source) > 0) + { + // + // One Model ... + Add( + source, + descriptors); + } + } + + // + // Each Provider Must Contains at least two things : + // - Asset; + int descriptorsCount = ArraySize(descriptors); + if (descriptorsCount > 0) + { + // + // Loop through descriptors to parse models ... + for (int i = 0; i < descriptorsCount; i++) + { + // + string iDescriptor = descriptors[i]; + + // + X121SignalProvider iProviderDescriptor; + iProviderDescriptor.symbol = ""; + iProviderDescriptor.period = NULL; + iProviderDescriptor.riskAmount = 0; + Clean(iProviderDescriptor.providers); + + // + string iParts[]; + int iPartsCount = ExtractProviderDescriptorItems( + iParts, + iDescriptor); + + // + // Check Parts Count ... + // Now we have to Decide How to Config Signal Providers using Parts ... + + // + // asset => default; + // period => default; + // risk amount => default; + // signallers => default; + // use as static volume => default; + if (iPartsCount == 0) + { + // + // Here we Instance as Current Config Descriptor ... + iProviderDescriptor.symbol = _Symbol; + iProviderDescriptor.period = _Period; + iProviderDescriptor.riskAmount = defaultRiskAmount; + iProviderDescriptor.useRiskAmountAsStaticVolume = useRiskAmountAsStaticVolume; + + // + // Add Default Signallers ... + Copy( + defaultSignallersArr, + iProviderDescriptor.providers); + + // + AddProviderDescriptor( + iProviderDescriptor, + result); + + // + continue; + } + + // + // asset => provided; + // period => default; + // risk amount => default; + // signallers => default; + // use as static volume => default; + if (iPartsCount == 1) + { + + // + iProviderDescriptor.period = _Period; + iProviderDescriptor.riskAmount = defaultRiskAmount; + iProviderDescriptor.useRiskAmountAsStaticVolume = useRiskAmountAsStaticVolume; + + // + // Add Default Signallers ... + Copy( + defaultSignallersArr, + iProviderDescriptor.providers); + + // + // Extract Provided Assets ... + string symbols[]; + int symbolsCount = ExtractProviderDescriptorItemsContent( + symbols, + iParts[0]); + for (int j = 0; j < symbolsCount; j++) + { + // + string jSymbol = symbols[j]; + + // + iProviderDescriptor.symbol = jSymbol; + + // + AddProviderDescriptor( + iProviderDescriptor, + result); + } + + // + continue; + } + + // + // asset => provided; + // period => provided; + // risk amount => default; + // signallers => default; + // use as static volume => default; + if (iPartsCount == 2) + { + // + iProviderDescriptor.riskAmount = defaultRiskAmount; + iProviderDescriptor.useRiskAmountAsStaticVolume = useRiskAmountAsStaticVolume; + + // + // Add Default Signallers ... + Copy( + defaultSignallersArr, + iProviderDescriptor.providers); + + // + // Extract Provided Assets ... + string symbols[]; + int symbolsCount = ExtractProviderDescriptorItemsContent( + symbols, + iParts[0]); + for (int j = 0; j < symbolsCount; j++) + { + // + string jSymbol = symbols[j]; + + // + iProviderDescriptor.symbol = jSymbol; + + // + // Extract Periods ... + string periods[]; + int periodsCount = ExtractProviderDescriptorItemsContent( + periods, + iParts[1]); + for (int k = 0; k < periodsCount; k++) + { + // + string kPeriodStr = periods[k]; + ENUM_TIMEFRAMES kPeriod = ToPeriod(kPeriodStr); + + // + iProviderDescriptor.period = kPeriod; + + // + AddProviderDescriptor( + iProviderDescriptor, + result); + } + } + + // + continue; + } + + // + // asset => provided; + // period => provided; + // risk amount => provided; + // signallers => default; + // use as static volume => default; + if (iPartsCount == 3) + { + // + iProviderDescriptor.useRiskAmountAsStaticVolume = useRiskAmountAsStaticVolume; + + // + // Add Default Signallers ... + Copy( + defaultSignallersArr, + iProviderDescriptor.providers); + + // + // Extract Provided Assets ... + string symbols[]; + int symbolsCount = ExtractProviderDescriptorItemsContent( + symbols, + iParts[0]); + + // + string riskAmounts[]; + int riskAmountsCount = ExtractProviderDescriptorItemsContent( + riskAmounts, + iParts[2]); + + // + for (int j = 0; j < symbolsCount; j++) + { + // + string jSymbol = symbols[j]; + + // + iProviderDescriptor.symbol = jSymbol; + + // + // Extract Periods ... + string periods[]; + int periodsCount = ExtractProviderDescriptorItemsContent( + periods, + iParts[1]); + for (int k = 0; k < periodsCount; k++) + { + // + string kPeriodStr = periods[k]; + ENUM_TIMEFRAMES kPeriod = ToPeriod(kPeriodStr); + + // + iProviderDescriptor.period = kPeriod; + + // + string selectedRiskAmount = + riskAmountsCount == 0 + ? ToString(defaultRiskAmount) + : riskAmountsCount == periodsCount + ? riskAmounts[k] + : riskAmounts[0]; + double riskAmount = (double)selectedRiskAmount; + iProviderDescriptor.riskAmount = riskAmount; + + // + AddProviderDescriptor( + iProviderDescriptor, + result); + } + } + + // + continue; + } + + // + // asset => provided; + // period => provided; + // risk amount => provided; + // signallers => provided; + // use as static volume => default; + if (iPartsCount == 4) + { + // + iProviderDescriptor.useRiskAmountAsStaticVolume = useRiskAmountAsStaticVolume; + + // + // Extract Signallers ... + string signallers[]; + int signallersCount = ExtractSignallers( + signallers, + iParts[3]); + if (signallersCount <= 0) + { + // + Copy( + defaultSignallersArr, + signallers); + } + + // + // Set Extracted Signallers in Provider Descriptor ... + Copy( + signallers, + iProviderDescriptor.providers); + + // + // + // Extract Provided Assets ... + string symbols[]; + int symbolsCount = ExtractProviderDescriptorItemsContent( + symbols, + iParts[0]); + + // + string riskAmounts[]; + int riskAmountsCount = ExtractProviderDescriptorItemsContent( + riskAmounts, + iParts[2]); + + // + for (int j = 0; j < symbolsCount; j++) + { + // + string jSymbol = symbols[j]; + + // + iProviderDescriptor.symbol = jSymbol; + + // + // Extract Periods ... + string periods[]; + int periodsCount = ExtractProviderDescriptorItemsContent( + periods, + iParts[1]); + for (int k = 0; k < periodsCount; k++) + { + // + string kPeriodStr = periods[k]; + ENUM_TIMEFRAMES kPeriod = ToPeriod(kPeriodStr); + + // + iProviderDescriptor.period = kPeriod; + + // + string selectedRiskAmount = + riskAmountsCount == 0 + ? ToString(defaultRiskAmount) + : riskAmountsCount == periodsCount + ? riskAmounts[k] + : riskAmounts[0]; + double riskAmount = (double)selectedRiskAmount; + iProviderDescriptor.riskAmount = riskAmount; + + // + AddProviderDescriptor( + iProviderDescriptor, + result); + } + } + + // + continue; + } + + // + // asset => provided; + // period => provided; + // risk amount => provided; + // signallers => provided; + // use as static volume => provided; + if (iPartsCount == 5) + { + // + // Extract Signallers ... + string signallers[]; + int signallersCount = ExtractSignallers( + signallers, + iParts[3]); + if (signallersCount <= 0) + { + // + Copy( + defaultSignallersArr, + signallers); + } + + // + // Set Extracted Signallers in Provider Descriptor ... + Copy( + signallers, + iProviderDescriptor.providers); + + // + // + // Extract Provided Assets ... + string symbols[]; + int symbolsCount = ExtractProviderDescriptorItemsContent( + symbols, + iParts[0]); + + // + string riskAmounts[]; + int riskAmountsCount = ExtractProviderDescriptorItemsContent( + riskAmounts, + iParts[2]); + + // + string useRiskAmountAsStaticVolumes[]; + int useRiskAmountAsStaticVolumesCount = ExtractProviderDescriptorItemsContent( + useRiskAmountAsStaticVolumes, + iParts[4]); + + // + for (int j = 0; j < symbolsCount; j++) + { + // + string jSymbol = symbols[j]; + + // + iProviderDescriptor.symbol = jSymbol; + + // + // Extract Periods ... + string periods[]; + int periodsCount = ExtractProviderDescriptorItemsContent( + periods, + iParts[1]); + for (int k = 0; k < periodsCount; k++) + { + // + string kPeriodStr = periods[k]; + ENUM_TIMEFRAMES kPeriod = ToPeriod(kPeriodStr); + + // + iProviderDescriptor.period = kPeriod; + + // + string selectedRiskAmount = + riskAmountsCount == 0 + ? ToString(defaultRiskAmount) + : riskAmountsCount == periodsCount + ? riskAmounts[k] + : riskAmounts[0]; + double riskAmount = (double)selectedRiskAmount; + iProviderDescriptor.riskAmount = riskAmount; + + // + string selectedUseRiskAmountAsStaticVolume = + useRiskAmountAsStaticVolumesCount == 0 + ? ToString(useRiskAmountAsStaticVolume) + : useRiskAmountAsStaticVolumesCount == periodsCount + ? useRiskAmountAsStaticVolumes[k] + : useRiskAmountAsStaticVolumes[0]; + bool useRiskAmountAsStaticVolume = ToBoolean(selectedUseRiskAmountAsStaticVolume); + iProviderDescriptor.useRiskAmountAsStaticVolume = useRiskAmountAsStaticVolume; + + // + AddProviderDescriptor( + iProviderDescriptor, + result); + } + } + + // + continue; + } + } + } + else + { + // + // Use All Defaults to Create One Instance ... + X121SignalProvider iProviderDescriptor; + iProviderDescriptor.symbol = ""; + iProviderDescriptor.period = NULL; + iProviderDescriptor.riskAmount = 0; + Clean(iProviderDescriptor.providers); + + // + iProviderDescriptor.symbol = _Symbol; + iProviderDescriptor.period = _Period; + iProviderDescriptor.riskAmount = defaultRiskAmount; + iProviderDescriptor.useRiskAmountAsStaticVolume = useRiskAmountAsStaticVolume; + + // + // Add Default Signallers ... + Copy( + defaultSignallersArr, + iProviderDescriptor.providers); + + // + AddProviderDescriptor( + iProviderDescriptor, + result); + } + + // + mResult = ArraySize(result); + + // + return mResult; +} + +// +// START XEQM Support ... +// + +// +string XEQMSupportToken = "XEQM"; + +// +// Generate String Tag for EQM Support Signals ... +string GenerateXEQMSupportComment() +{ + // + string result = XEQMSupportToken; + + // + return result; +} + +// +// Check a Comment belongs to a EQM Support or not ... +bool IsEQMSupport(string comment) +{ + // + bool result = false; + + // + if (StringLen(comment) <= 0) + { + return result; + } + + // + int tokenPosition = StringFind( + comment, + XEQMSupportToken); + result = tokenPosition >= 0; + + // + return result; +} + +// +// Select EQM Support Orders ... +int GetEQMSupportOrders( + XOrder &supports[], // Hold Result ... + XOrder &orders[], // List of All Orders ... + ENUM_TIMEFRAMES period = NULL // Specified Period ... +) +{ + // + int result = 0; + + // + // Cleanup Array ... + Clean(supports); + + // + // Count Orders ... + int ordersCount = ArraySize(orders); + if (ordersCount <= 0) + { + return result; + } + + // + // Loop through Orders ... + for (int i = 0; i < ordersCount; i++) + { + // + // Select Indexed Order ... + XOrder iOrder = orders[i]; + + // + // Check Order is Support or not ... + bool isSupport = IsEQMSupport(iOrder.comment); + if (!isSupport) + { + continue; + } + + // + // Check Order is not Triggered ... + if (iOrder.state != ORDER_STATE_PLACED) + { + continue; + } + + // + // Check Period ... + if (period != NULL && iOrder.period != period) + { + continue; + } + + // + // we now sure this order is EQM Support ... + Add( + iOrder, + supports); + } + + // + // Count Result ... + result = ArraySize(supports); + + // + return result; +} + +// +// Select EQM Support Positions ... +int GetEQMSupportPositions( + XPosition &supports[], // Hold Result ... + XPosition &positions[], // List of All Positions ... + ENUM_TIMEFRAMES period = NULL // Specified Period ... +) +{ + // + int result = 0; + + // + // Cleanup Array ... + Clean(supports); + + // + // Count Positions ... + int positionsCount = ArraySize(positions); + if (positionsCount <= 0) + { + return result; + } + + // + // Loop through Positions ... + for (int i = 0; i < positionsCount; i++) + { + // + // Select Indexed Position ... + XPosition iPosition = positions[i]; + + // + // Check Position is Support or not ... + bool isSupport = IsEQMSupport(iPosition.comment); + if (!isSupport) + { + continue; + } + + // + // Check Period ... + if (period != NULL && iPosition.period != period) + { + continue; + } + + // + // we now sure this order is EQM Support ... + Add( + iPosition, + supports); + } + + // + // Count Result ... + result = ArraySize(supports); + + // + return result; +} + +// +// END XEQM Support ... +// \ No newline at end of file diff --git a/MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.x121.condition.parser.lib.mq5 b/MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.x121.condition.parser.lib.mq5 new file mode 100644 index 0000000..5815ba6 --- /dev/null +++ b/MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.x121.condition.parser.lib.mq5 @@ -0,0 +1,2475 @@ +//////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X12 Conditions Parser Library +// ----------------------------------------------------- +// Name: X121ConditionsParser +// Description: provides Market Conditions +// Parsing Requirements ... +// +// +// 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 + +// +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Libraries/x-saherelm.models.lib.mq5" +#include "../Classes/x-saherelm.x121.provider.class.mq5" + +// +// START Functions ... +// + +// +// PARSE STATES ... +// + +// +// SSLC ... +// + +// +bool IsSSLCBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.sslcUps[index] > conditions.xmanInfo.sslcDowns[index] + // + ; + + // + return result; +} + +// +bool IsSSLCSwitchedToBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSSLCBullish(conditions, index) && + !IsSSLCBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsSSLCBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.sslcUps[index] < conditions.xmanInfo.sslcDowns[index] + // + ; + + // + return result; +} + +// +bool IsSSLCSwitchedToBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSSLCBearish(conditions, index) && + !IsSSLCBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// HULL ... +// + +// +bool IsHullBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsHullUpBullish(conditions, index) && + IsHullDownBullish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsHullSwitchedBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsHullBullish(conditions, index) && + !IsHullBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsHullBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsHullUpBearish(conditions, index) && + IsHullDownBearish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsHullSwitchedBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsHullBearish(conditions, index) && + !IsHullBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// UP ... + +// +// BULLISH ... + +// +bool IsHullUpBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.hullUps[index] > conditions.xmanInfo.hullUps[index + 1] + // + ; + + // + return result; +} + +// +bool IsHullUpSwitchedToBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsHullUpBullish(conditions, index) && + !IsHullUpBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// BEARISH ... + +// +bool IsHullUpBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.hullUps[index] < conditions.xmanInfo.hullUps[index + 1] + // + ; + + // + return result; +} + +// +bool IsHullUpSwitchedToBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsHullUpBearish(conditions, index) && + !IsHullUpBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// DOWN ... + +// +// BULLISH ... + +// +bool IsHullDownBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.hullDowns[index] > conditions.xmanInfo.hullDowns[index + 1] + // + ; + + // + return result; +} + +// +bool IsHullDownSwitchedToBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsHullDownBullish(conditions, index) && + !IsHullDownBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// BEARISH ... + +// +bool IsHullDownBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.hullDowns[index] < conditions.xmanInfo.hullDowns[index + 1] + // + ; + + // + return result; +} + +// +bool IsHullDownSwitchedToBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsHullDownBearish(conditions, index) && + !IsHullDownBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// TREND ... +// + +// +// Check Trend Bullish ... +bool IsTrendBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.candles[index].low > conditions.xmanInfo.trends[index] + // + ; + + // + return result; +} + +// +// Check Trend Switched To Bullish ... +bool IsTrendSwitchedToBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsTrendBullish(conditions, index) && + !IsTrendBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// Check Trend Bearish ... +bool IsTrendBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.candles[index].high < conditions.xmanInfo.trends[index] + // + ; + + // + return result; +} + +// +// Check Trend Switched To Bearish ... +bool IsTrendSwitchedToBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsTrendBearish(conditions, index) && + !IsTrendBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// RIBBON ... +// + +// +double GetRibbonMax( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + double result = 0; + + // + result = MathMax(conditions.xmanInfo.ribbon1s[index], conditions.xmanInfo.ribbon2s[index]); + result = MathMax(result, conditions.xmanInfo.ribbon3s[index]); + result = MathMax(result, conditions.xmanInfo.ribbon4s[index]); + result = MathMax(result, conditions.xmanInfo.ribbon5s[index]); + result = MathMax(result, conditions.xmanInfo.ribbon6s[index]); + + // + return result; +} + +// +double GetRibbonMin( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + double result = 0; + + // + result = MathMin(conditions.xmanInfo.ribbon1s[index], conditions.xmanInfo.ribbon2s[index]); + result = MathMin(result, conditions.xmanInfo.ribbon3s[index]); + result = MathMin(result, conditions.xmanInfo.ribbon4s[index]); + result = MathMin(result, conditions.xmanInfo.ribbon5s[index]); + result = MathMin(result, conditions.xmanInfo.ribbon6s[index]); + + // + return result; +} + +// +// Check Ribbon States ... +// Working With Price and Ribbon Values ... +bool IsRibbonBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.candles[index].low > conditions.xmanInfo.ribbon1s[index] && + conditions.candles[index].low > conditions.xmanInfo.ribbon2s[index] && + conditions.candles[index].low > conditions.xmanInfo.ribbon3s[index] && + conditions.candles[index].low > conditions.xmanInfo.ribbon4s[index] && + conditions.candles[index].low > conditions.xmanInfo.ribbon5s[index] && + conditions.candles[index].low > conditions.xmanInfo.ribbon6s[index] + // + ; + + // + return result; +} + +// +// Check Ribbons Sequntial Statements ... +// Working with Price and Ribbon Values and also Ribbon Orders +bool IsRibbonOrderBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsRibbonBullish(conditions, index) + // + && + // + GetRibbonMax(conditions, index) == conditions.xmanInfo.ribbon1s[index] + // + && + // + GetRibbonMin(conditions, index) == conditions.xmanInfo.ribbon6s[index] + // + ; + + // + return result; +} + +// +bool IsRibbonSwitchedToBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsRibbonBullish(conditions, index) && + !IsRibbonBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// Check Ribbons Sequntial Statements ... +bool IsRibbonOrderSwitchedToBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsRibbonOrderBullish(conditions, index) && + !IsRibbonOrderBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// Check Ribbon States ... +// Working With Price and Ribbon Values ... +bool IsRibbonBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.candles[index].high < conditions.xmanInfo.ribbon1s[index] && + conditions.candles[index].high < conditions.xmanInfo.ribbon2s[index] && + conditions.candles[index].high < conditions.xmanInfo.ribbon3s[index] && + conditions.candles[index].high < conditions.xmanInfo.ribbon4s[index] && + conditions.candles[index].high < conditions.xmanInfo.ribbon5s[index] && + conditions.candles[index].high < conditions.xmanInfo.ribbon6s[index] + // + ; + + // + return result; +} + +// +// Check Ribbons Sequntial Statements ... +// Working with Price and Ribbon Values and also Ribbon Orders +bool IsRibbonOrderBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsRibbonBearish(conditions, index) + // + && + // + GetRibbonMax(conditions, index) == conditions.xmanInfo.ribbon1s[index] + // + && + // + GetRibbonMin(conditions, index) == conditions.xmanInfo.ribbon6s[index] + // + ; + + // + return result; +} + +// +bool IsRibbonSwitchedToBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsRibbonBearish(conditions, index) && + !IsRibbonBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// Check Ribbons Sequntial Statements ... +bool IsRibbonOrderSwitchedToBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsRibbonOrderBearish(conditions, index) && + !IsRibbonOrderBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// PEAKS and VALES and Levels ... +// + +// +// Check New Peaks Happens ... +bool IsNewPeak( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.peaks[index] != EMPTY_VALUE && + conditions.xmanInfo.peaks[index] != conditions.xmanInfo.peaks[index + 1] + // + ; + + // + return result; +} + +// +// Check New Peaks Happens Over Last ... +bool IsNewPeakOverLast( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsNewPeak(conditions, index) && + conditions.xmanInfo.peaks[index] > conditions.xmanInfo.peaks[index + 1] + // + ; + + // + return result; +} + +// +// Check New Peaks Happens Under Last ... +bool IsNewPeakUnderLast( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsNewPeak(conditions, index) && + conditions.xmanInfo.peaks[index] < conditions.xmanInfo.peaks[index + 1] + // + ; + + // + return result; +} + +// +// Check New Vales Happens ... +bool IsNewVale( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.vales[index] != EMPTY_VALUE && + conditions.xmanInfo.vales[index] != conditions.xmanInfo.vales[index + 1] + // + ; + + // + return result; +} + +// +// Check New Vales Happens Over Last ... +bool IsNewValeOverLast( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsNewVale(conditions, index) && + conditions.xmanInfo.vales[index] > conditions.xmanInfo.vales[index + 1] + // + ; + + // + return result; +} + +// +// Check New Vales Happens Under Last ... +bool IsNewValeUnderLast( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsNewVale(conditions, index) && + conditions.xmanInfo.vales[index] < conditions.xmanInfo.vales[index + 1] + // + ; + + // + return result; +} + +// +// Market Cycles ... + +// +// ALL Cycles ... + +// +bool IsCyclesBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCBullish(conditions, index) && + IsMCBullish(conditions, index) && + IsLCBullish(conditions, index) && + IsHCBullish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsCyclesSwitchedToBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsCyclesBullish(conditions, index) && + !IsCyclesBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsCyclesBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCBearish(conditions, index) && + IsMCBearish(conditions, index) && + IsLCBearish(conditions, index) && + IsHCBearish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsCyclesSwitchedToBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsCyclesBearish(conditions, index) && + !IsCyclesBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsCyclesLowBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCLowBullish(conditions, index) && + IsMCLowBullish(conditions, index) && + IsLCLowBullish(conditions, index) && + IsHCLowBullish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsCyclesLowSwitchedToBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsCyclesLowBullish(conditions, index) && + !IsCyclesLowBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsCyclesLowBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCLowBearish(conditions, index) && + IsMCLowBearish(conditions, index) && + IsLCLowBearish(conditions, index) && + IsHCLowBearish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsCyclesLowSwitchedToBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsCyclesLowBearish(conditions, index) && + !IsCyclesLowBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsCyclesHighBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCHighBullish(conditions, index) && + IsMCHighBullish(conditions, index) && + IsLCHighBullish(conditions, index) && + IsHCHighBullish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsCyclesHighSwitchedToBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsCyclesHighBullish(conditions, index) && + !IsCyclesHighBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsCyclesHighBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCHighBearish(conditions, index) && + IsMCHighBearish(conditions, index) && + IsLCHighBearish(conditions, index) && + IsHCHighBearish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsCyclesHighSwitchedToBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsCyclesHighBearish(conditions, index) && + !IsCyclesHighBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// INHIND Cycles ... + +// +bool IsInHindCyclesBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCBullish(conditions, index) && + IsMCBullish(conditions, index) && + IsLCBullish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsInHindCyclesSwitchedToBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsInHindCyclesBullish(conditions, index) && + !IsInHindCyclesBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsInHindCyclesBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCBearish(conditions, index) && + IsMCBearish(conditions, index) && + IsLCBearish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsInHindCyclesSwitchedToBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsInHindCyclesBearish(conditions, index) && + !IsInHindCyclesBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsInHindCyclesLowBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCLowBullish(conditions, index) && + IsMCLowBullish(conditions, index) && + IsLCLowBullish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsInHindCyclesLowSwitchedToBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsInHindCyclesLowBullish(conditions, index) && + !IsInHindCyclesLowBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsInHindCyclesHighBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCHighBullish(conditions, index) && + IsMCHighBullish(conditions, index) && + IsLCHighBullish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsInHindCyclesHighSwitchedToBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsInHindCyclesHighBullish(conditions, index) && + !IsInHindCyclesHighBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// INLONG Cycles ... + +// +bool IsInLongCyclesBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCBullish(conditions, index) && + IsMCBullish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsInLongCyclesSwitchedToBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsInLongCyclesBullish(conditions, index) && + !IsInLongCyclesBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsInLongCyclesBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCBearish(conditions, index) && + IsMCBearish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsInLongCyclesSwitchedToBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsInLongCyclesBearish(conditions, index) && + !IsInLongCyclesBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// SHORT ... + +// +bool IsSCBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCHighBullish(conditions, index) && + IsSCLowBullish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsSCSwitchedToBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCBullish(conditions, index) && + !IsSCBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsSCBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCHighBearish(conditions, index) && + IsSCLowBearish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsSCSwitchedToBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCBearish(conditions, index) && + !IsSCBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// SHORT HIGH ... + +// +bool IsSCHighBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.sHHs[index] > conditions.xmanInfo.sHHs[index + 1] + // + ; + + // + return result; +} + +// +bool IsSCHighSwitchedBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCHighBullish(conditions, index) && + !IsSCHighBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsSCHighBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.sHHs[index] < conditions.xmanInfo.sHHs[index + 1] + // + ; + + // + return result; +} + +// +bool IsSCHighSwitchedToBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCHighBearish(conditions, index) && + !IsSCHighBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// SHORT LOW ... + +// +bool IsSCLowBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.sLLs[index] > conditions.xmanInfo.sLLs[index + 1] + // + ; + + // + return result; +} + +// +bool IsSCLowSwitchedBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCLowBullish(conditions, index) && + !IsSCLowBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsSCLowBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.sLLs[index] < conditions.xmanInfo.sLLs[index + 1] + // + ; + + // + return result; +} + +// +bool IsSCLowSwitchedToBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsSCLowBearish(conditions, index) && + !IsSCLowBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// MEDIUM ... + +// +bool IsMCBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsMCHighBullish(conditions, index) && + IsMCLowBullish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsMCSwitchedToBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsMCBullish(conditions, index) && + !IsMCBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsMCBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsMCHighBearish(conditions, index) && + IsMCLowBearish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsMCSwitchedToBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsMCBearish(conditions, index) && + !IsMCBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// MEDIUM HIGH ... + +// +bool IsMCHighBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.mHHs[index] > conditions.xmanInfo.mHHs[index + 1] + // + ; + + // + return result; +} + +// +bool IsMCHighSwitchedBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsMCHighBullish(conditions, index) && + !IsMCHighBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsMCHighBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.mHHs[index] < conditions.xmanInfo.mHHs[index + 1] + // + ; + + // + return result; +} + +// +bool IsMCHighSwitchedToBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsMCHighBearish(conditions, index) && + !IsMCHighBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// MEDIUM LOW ... + +// +bool IsMCLowBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.mLLs[index] > conditions.xmanInfo.mLLs[index + 1] + // + ; + + // + return result; +} + +// +bool IsMCLowSwitchedBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsMCLowBullish(conditions, index) && + !IsMCLowBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsMCLowBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.mLLs[index] < conditions.xmanInfo.mLLs[index + 1] + // + ; + + // + return result; +} + +// +bool IsMCLowSwitchedToBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsMCLowBearish(conditions, index) && + !IsMCLowBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// LONG ... + +// +bool IsLCBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsLCHighBullish(conditions, index) && + IsLCLowBullish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsLCSwitchedToBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsLCBullish(conditions, index) && + !IsLCBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsLCBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsLCHighBearish(conditions, index) && + IsLCLowBearish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsLCSwitchedToBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsLCBearish(conditions, index) && + !IsLCBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// LONG HIGH ... + +// +bool IsLCHighBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.lHHs[index] > conditions.xmanInfo.lHHs[index + 1] + // + ; + + // + return result; +} + +// +bool IsLCHighSwitchedBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsLCHighBullish(conditions, index) && + !IsLCHighBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsLCHighBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.lHHs[index] < conditions.xmanInfo.lHHs[index + 1] + // + ; + + // + return result; +} + +// +bool IsLCHighSwitchedToBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsLCHighBearish(conditions, index) && + !IsLCHighBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// LONG LOW ... + +// +bool IsLCLowBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.lLLs[index] > conditions.xmanInfo.lLLs[index + 1] + // + ; + + // + return result; +} + +// +bool IsLCLowSwitchedBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsLCLowBullish(conditions, index) && + !IsLCLowBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsLCLowBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.lLLs[index] < conditions.xmanInfo.lLLs[index + 1] + // + ; + + // + return result; +} + +// +bool IsLCLowSwitchedToBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsLCLowBearish(conditions, index) && + !IsLCLowBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// HIND ... + +// +bool IsHCBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsHCHighBullish(conditions, index) && + IsHCLowBullish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsHCSwitchedToBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsHCBullish(conditions, index) && + !IsHCBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsHCBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsHCHighBearish(conditions, index) && + IsHCLowBearish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsHCSwitchedToBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsHCBearish(conditions, index) && + !IsHCBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// HIND HIGH ... + +// +bool IsHCHighBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.hHHs[index] > conditions.xmanInfo.hHHs[index + 1] + // + ; + + // + return result; +} + +// +bool IsHCHighSwitchedBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsHCHighBullish(conditions, index) && + !IsHCHighBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsHCHighBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.hHHs[index] < conditions.xmanInfo.hHHs[index + 1] + // + ; + + // + return result; +} + +// +bool IsHCHighSwitchedToBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsHCHighBearish(conditions, index) && + !IsHCHighBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// HIND LOW ... + +// +bool IsHCLowBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.hLLs[index] > conditions.xmanInfo.hLLs[index + 1] + // + ; + + // + return result; +} + +// +bool IsHCLowSwitchedBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsHCLowBullish(conditions, index) && + !IsHCLowBullish(conditions, index + 1) + // + ; + + // + return result; +} + +// +bool IsHCLowBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.hLLs[index] < conditions.xmanInfo.hLLs[index + 1] + // + ; + + // + return result; +} + +// +bool IsHCLowSwitchedToBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsHCLowBearish(conditions, index) && + !IsHCLowBearish(conditions, index + 1) + // + ; + + // + return result; +} + +// +// END Functions ... +// + +// +// START Combination .... +// + +// +bool IsMarketBullish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + IsHullBullish(conditions, index) && + IsSSLCBullish(conditions, index) && + IsTrendBullish(conditions, index) && + IsRibbonOrderBullish(conditions, index) + // + ; + + // + return result; +} + +// +bool IsMarketBearish( + X121MarketConditions &conditions, // Specified Conditions + int index = 0 // Array Index +) +{ + // + bool result = false; + + // + result = + // + false + // + ; + + // + return result; +} + +// +// END Combination .... +// diff --git a/MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.x121.draw.lib.ex5 b/MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.x121.draw.lib.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..405ae9610757d181c9a0466ec7f04c1da42190ad GIT binary patch literal 6864 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 0 || ArraySize(iSignal.supportAndResistance.res) > 0; + if (drawSupportAndResistances && isValidSupRes) + { + DrawSupportResistance(0, iSignal.supportAndResistance); + } + } +} + +// +// Draw Support and Resistance ... +void DrawSupportResistance( + int bar_index, + XOHCLSupRes &data, + string prefix = "", + color supportColor = clrOrange, + color resistanceColor = clrOrange) +{ + // + datetime barTime = GetCandleTime( + _Symbol, + _Period, + bar_index); + + // + datetime prevBarTime = GetCandleTime( + _Symbol, + _Period, + bar_index + 5); + + // + long chID = ChartID(); + int subWindiw = 0; + int lineWidth = 1; + + // + string mPrefix = prefix + "_" + (string)barTime + "_"; + + // + // SUPPORTS ... + + // + int supCount = ArraySize(data.sup); + if (supCount > 0) + { + // + for (int i = 0; i < supCount; i++) + { + // + double iSup = data.sup[i]; + + // + string supTlName = mPrefix + "SUP[" + (string)(i + 1) + "]_(" + (string)iSup + ")"; + + // + // Draw Support ... + DrawTrendLine( + chID, + supTlName, + subWindiw, + prevBarTime, + iSup, + barTime, + iSup, + supportColor, + STYLE_DOT, + lineWidth, + true); + } + } + + // + // RESISTANCES ... + + // + int resCount = ArraySize(data.res); + if (resCount > 0) + { + // + for (int i = 0; i < resCount; i++) + { + // + double iRes = data.res[i]; + + // + string resTlName = mPrefix + "RES[" + (string)(i + 1) + "]_(" + (string)iRes + ")"; + + // + // Draw Support ... + DrawTrendLine( + chID, + resTlName, + subWindiw, + prevBarTime, + iRes, + barTime, + iRes, + resistanceColor, + STYLE_DOT, + lineWidth, + true); + } + } +} + +// +// END Draw Functions ... +// diff --git a/MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.x121.signaller.lib.ex5 b/MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.x121.signaller.lib.ex5 new file mode 100644 index 0000000000000000000000000000000000000000..25845efb393c430302521a15e378d76dbb6d545a GIT binary patch literal 10570 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 literal 0 HcmV?d00001 diff --git a/MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.xman.parser.lib.mq5 b/MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.xman.parser.lib.mq5 new file mode 100644 index 0000000..bf6639e --- /dev/null +++ b/MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.xman.parser.lib.mq5 @@ -0,0 +1,1674 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XMAN Parser Library +// ----------------------------------------------- +// Name: XMANParser +// Description: Parsing XMAN Config ... +// +// +// 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 + +// +// Candle Timer Config ... +// candleTimerColor(clrGold)candleTimerCorner(2) +// +// Chrt Style ... +// upColor(clrLime) downColor(clrRed) lineColor(clrLime) bearishColor(clrRed) bullishColor(clrLime) volumesColor(clrGreen) chartMode(1) +// +// Market Cycles ... +// +// Short ... +// l1Method(1)l1Period(NULL) +// +// Medium ... +// l2Method(1)l2Period(NULL) +// +// Long ... +// l3Method(1)l3Period(NULL) +// +// Hind ... +// l4Method(1)l4Period(NULL) +// +// Fibonacci ... +// fiboLevel1(0.236)fiboLevel2(0.382)fiboLevel3(0.5)fiboLevel4(0.618)fiboLevel5(0.764) +// +// Boundary Detection Mode ... +// hhMode(2)llMode(1) +// +// Trend Detection ... +// trendMultiplier(3)trendPriceAppliedTo(4) +// +// Ribbon Detection ... +// ribbonMode(5) +// +// Hull Trend Detection ... +// hullDivisor(2.0)hullUpAppliedTo(3)hullDownAppliedTo(4) +// +// SSL Channel ... +// sslcMode(1)sslcUpAppliedTo(3)sslcDownAppliedTo(4) +// +// Style Presentation Config ... +// showCandleTimer(true)showCandles(true)showHKCandles(false)showSMHKCandles(false) +// +// +// PV Presentation Config ... +// showPeaksAndVales(true)showLevels(false)showConsolidations(false) +// +// +// Trend Presentation Config ... +// showHull(false)showTrends(false)fillTrends(false)showRibbons(false)showSSLChannel(false) +// +// +// Fibo Presentation Config ... +// showFibo1Levels(false)showFibo2Levels(false)showFibo3Levels(false)showFibo4Levels(false)showFibo5Levels(false) +// +#include "../Libraries/x-saherelm.models.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// XPERIOD Calculation Method ... +// USED For Multiple Time Frames ... +enum ENUM_X_PERIOD_METHOD +{ + // + X_PERIOD_NOTHING, // Nothing + X_PERIOD_AUTO, // Auto Select + X_PERIOD_MANUALLY // Manually +}; + +// +enum ENUM_X_MA_METHOD +{ + X_MA_NOTHING, // Nothing + X_MA_SMA, // Simple + X_MA_EMA, // Expotential + X_MA_SMMA, // Smoothed Simple + X_MA_LWMA, // Linear Weighted + X_MA_AMA // Adaptive +}; + +// +// PARSERS ... + +// +// CTIMER ... + +// +string candleTimerColorToken = "candleTimerColor"; +string candleTimerCornerToken = "candleTimerCorner"; + +// +struct XCTimerConfig +{ + color candleTimerColor; // Text Color + ENUM_BASE_CORNER candleTimerCorner; // Text Position +}; + +// +string GenerateCTimerConfig( + color mCandleTimerColor = clrGold, // Text Color + ENUM_BASE_CORNER mCandleTimerCorner = CORNER_RIGHT_UPPER // Text Position +) +{ + // + string result = + candleTimerColorToken + "(" + ToString(mCandleTimerColor) + ")" + + candleTimerCornerToken + "(" + ToString((int)mCandleTimerCorner) + ")"; + + // + return result; +} + +// +string ToString(XCTimerConfig &config) +{ + // + return GenerateCTimerConfig( + config.candleTimerColor, + config.candleTimerCorner); +} + +// +XCTimerConfig ParseCTimerConfig( + string config // Source Config +) +{ + // + XCTimerConfig result; + + // + // CandleTimerColor ... + string candleTimerColorStr = + // + ExtractString( + config, + candleTimerColorToken + "(", + ")"); + // + ; + if (StringLen(candleTimerColorStr) > 0) + { + // + color mCandleTimerColor = (color)candleTimerColorStr; + result.candleTimerColor = mCandleTimerColor; + } + + // + // CandleTimerCorner ... + string candleTimerCornerStr = + // + ExtractString( + config, + candleTimerCornerToken + "(", + ")"); + // + ; + if (StringLen(candleTimerCornerStr) > 0) + { + // + ENUM_BASE_CORNER mCandleTimerCorner = (ENUM_BASE_CORNER)((int)candleTimerCornerStr); + result.candleTimerCorner = mCandleTimerCorner; + } + + // + return result; +} + +// +// CHARTSTYLE ... + +// +string upColorToken = "upColor"; +string downColorToken = "downColor"; +string lineColorToken = "lineColor"; +string bearishColorToken = "bearishColor"; +string bullishColorToken = "bullishColor"; +string volumesColorToken = "volumesColor"; +string chartModeToken = "chartMode"; + +// +struct XChartStyleConfig +{ + color upColor; // Up Color + color downColor; // Down Color + color lineColor; // Line mode and Doji candlestick Color + color bearishColor; // Bullish Color + color bullishColor; // Bearish Color + color volumesColor; // Volumes Color + ENUM_CHART_MODE chartMode; // Chart Mode +}; + +// +string GenerateChartStyleConfig( + color mUpColor = clrLime, // Up Color + color mDownColor = clrRed, // Down Color + color mLineColor = clrLime, // Line mode and Doji candlestick Color + color mBearishColor = clrRed, // Bullish Color + color mBullishColor = clrLime, // Bearish Color + color mVolumesColor = clrGreen, // Volumes Color + ENUM_CHART_MODE mChartMode = CHART_CANDLES // Chart Mode +) +{ + // + string result = ""; + + // + result = + // + upColorToken + "(" + ToString(mUpColor) + ")" + + downColorToken + "(" + ToString(mDownColor) + ")" + + lineColorToken + "(" + ToString(mLineColor) + ")" + + bearishColorToken + "(" + ToString(mBearishColor) + ")" + + bullishColorToken + "(" + ToString(mBullishColor) + ")" + + volumesColorToken + "(" + ToString(mVolumesColor) + ")" + + chartModeToken + "(" + ToString((int)mChartMode) + ")" + // + ; + + // + return result; +} + +// +string ToString(XChartStyleConfig &config) +{ + return GenerateChartStyleConfig( + config.upColor, + config.downColor, + config.lineColor, + config.bearishColor, + config.bullishColor, + config.volumesColor, + config.chartMode); +} + +// +XChartStyleConfig ParseChartStyleConfig(string config) +{ + // + XChartStyleConfig result; + + // + string upColorStr = + // + ExtractString( + config, + upColorToken + "(", + ")") + // + ; + if (StringLen(upColorStr) > 0) + { + // + color mUpColor = (color)upColorStr; + result.upColor = mUpColor; + } + + // + string downColorStr = + // + ExtractString( + config, + downColorToken + "(", + ")") + // + ; + if (StringLen(downColorStr) > 0) + { + // + color mDownColor = (color)downColorStr; + result.downColor = mDownColor; + } + + // + string lineColorStr = + // + ExtractString( + config, + lineColorToken + "(", + ")") + // + ; + if (StringLen(lineColorStr) > 0) + { + // + color mLineColor = (color)lineColorStr; + result.lineColor = mLineColor; + } + + // + string bearishColorStr = + // + ExtractString( + config, + bearishColorToken + "(", + ")") + // + ; + if (StringLen(bearishColorStr) > 0) + { + // + color mBearishColor = (color)bearishColorStr; + result.bearishColor = mBearishColor; + } + + // + string bullishColorStr = + // + ExtractString( + config, + bullishColorToken + "(", + ")") + // + ; + if (StringLen(bullishColorStr) > 0) + { + // + color mBullishColor = (color)bullishColorStr; + result.bullishColor = mBullishColor; + } + + // + string volumesColorStr = + // + ExtractString( + config, + volumesColorToken + "(", + ")") + // + ; + if (StringLen(volumesColorStr) > 0) + { + // + color mVolumesColor = (color)volumesColorStr; + result.volumesColor = mVolumesColor; + } + + // + string chartModeStr = + // + ExtractString( + config, + chartModeToken + "(", + ")") + // + ; + if (StringLen(chartModeStr) > 0) + { + // + ENUM_CHART_MODE mChartMode = (ENUM_CHART_MODE)((int)chartModeStr); + result.chartMode = mChartMode; + } + + // + return result; +} + +// +// MARKETCYCLES ... + +// +// SHORT ... + +// +string l1MethodToken = "l1Method"; +string l1PeriodToken = "l1Period"; + +// +struct XSCConfig +{ + ENUM_X_PERIOD_METHOD l1Method; // How to Find Period + ENUM_TIMEFRAMES l1Period; // Time Period +}; + +// +string GenerateSCConfig( + ENUM_X_PERIOD_METHOD mML1Method = X_PERIOD_AUTO, // How to Find Period + ENUM_TIMEFRAMES mML1Period = NULL // Time Period +) +{ + // + string result = ""; + + // + result = + // + l1MethodToken + "(" + ToString(mML1Method) + ")" + + l1PeriodToken + "(" + ToString(mML1Period) + ")" + // + ; + + // + return result; +} + +// +string ToString(XSCConfig &config) +{ + return GenerateSCConfig( + config.l1Method, + config.l1Period); +} + +// +XSCConfig PrseSCConfig(string config) +{ + // + XSCConfig result; + + // + string l1MethodStr = ExtractString( + config, + l1MethodToken + "(", + ")"); + if (StringLen(l1MethodStr) > 0) + { + // + ENUM_X_PERIOD_METHOD mML1Method = (ENUM_X_PERIOD_METHOD)((int)l1MethodStr); + result.l1Method = mML1Method; + } + + // + string l1PeriodStr = ExtractString( + config, + l1PeriodToken + "(", + ")"); + if (StringLen(l1PeriodStr) > 0) + { + // + ENUM_TIMEFRAMES mML1Period = (ENUM_TIMEFRAMES)((int)l1PeriodStr); + result.l1Period = mML1Period; + } + + // + return result; +} + +// +// MEDIUM ... + +// +string l2MethodToken = "l2Method"; +string l2PeriodToken = "l2Period"; + +// +struct XMCConfig +{ + ENUM_X_PERIOD_METHOD l2Method; // How to Find Period + ENUM_TIMEFRAMES l2Period; // Time Period +}; + +// +string GenerateMCConfig( + ENUM_X_PERIOD_METHOD mML2Method = X_PERIOD_AUTO, // How to Find Period + ENUM_TIMEFRAMES mML2Period = NULL // Time Period +) +{ + // + string result = ""; + + // + result = + // + l2MethodToken + "(" + ToString(mML2Method) + ")" + + l2PeriodToken + "(" + ToString(mML2Period) + ")" + // + ; + + // + return result; +} + +// +string ToString(XMCConfig &config) +{ + return GenerateSCConfig( + config.l2Method, + config.l2Period); +} + +// +XMCConfig PrseMCConfig(string config) +{ + // + XMCConfig result; + + // + string l2MethodStr = ExtractString( + config, + l2MethodToken + "(", + ")"); + if (StringLen(l2MethodStr) > 0) + { + // + ENUM_X_PERIOD_METHOD mML2Method = (ENUM_X_PERIOD_METHOD)((int)l2MethodStr); + result.l2Method = mML2Method; + } + + // + string l2PeriodStr = ExtractString( + config, + l2PeriodToken + "(", + ")"); + if (StringLen(l2PeriodStr) > 0) + { + // + ENUM_TIMEFRAMES mML2Period = (ENUM_TIMEFRAMES)((int)l2PeriodStr); + result.l2Period = mML2Period; + } + + // + return result; +} + +// +// LONG ... + +// +string l3MethodToken = "l3Method"; +string l3PeriodToken = "l3Period"; + +// +struct XLCConfig +{ + ENUM_X_PERIOD_METHOD l3Method; // How to Find Period + ENUM_TIMEFRAMES l3Period; // Time Period +}; + +// +string GenerateLCConfig( + ENUM_X_PERIOD_METHOD mML3Method = X_PERIOD_AUTO, // How to Find Period + ENUM_TIMEFRAMES mML3Period = NULL // Time Period +) +{ + // + string result = ""; + + // + result = + // + l3MethodToken + "(" + ToString(mML3Method) + ")" + + l3PeriodToken + "(" + ToString(mML3Period) + ")" + // + ; + + // + return result; +} + +// +string ToString(XLCConfig &config) +{ + return GenerateSCConfig( + config.l3Method, + config.l3Period); +} + +// +XLCConfig PrseLCConfig(string config) +{ + // + XLCConfig result; + + // + string l3MethodStr = ExtractString( + config, + l3MethodToken + "(", + ")"); + if (StringLen(l3MethodStr) > 0) + { + // + ENUM_X_PERIOD_METHOD mML3Method = (ENUM_X_PERIOD_METHOD)((int)l3MethodStr); + result.l3Method = mML3Method; + } + + // + string l3PeriodStr = ExtractString( + config, + l3PeriodToken + "(", + ")"); + if (StringLen(l3PeriodStr) > 0) + { + // + ENUM_TIMEFRAMES mML3Period = (ENUM_TIMEFRAMES)((int)l3PeriodStr); + result.l3Period = mML3Period; + } + + // + return result; +} + +// +// HIND ... + +// +string l4MethodToken = "l4Method"; +string l4PeriodToken = "l4Period"; + +// +struct XHCConfig +{ + ENUM_X_PERIOD_METHOD l4Method; // How to Find Period + ENUM_TIMEFRAMES l4Period; // Time Period +}; + +// +string GenerateHCConfig( + ENUM_X_PERIOD_METHOD mML4Method = X_PERIOD_AUTO, // How to Find Period + ENUM_TIMEFRAMES mML4Period = NULL // Time Period +) +{ + // + string result = ""; + + // + result = + // + l4MethodToken + "(" + ToString(mML4Method) + ")" + + l4PeriodToken + "(" + ToString(mML4Period) + ")" + // + ; + + // + return result; +} + +// +string ToString(XHCConfig &config) +{ + return GenerateSCConfig( + config.l4Method, + config.l4Period); +} + +// +XHCConfig PrseHCConfig(string config) +{ + // + XHCConfig result; + + // + string l4MethodStr = ExtractString( + config, + l4MethodToken + "(", + ")"); + if (StringLen(l4MethodStr) > 0) + { + // + ENUM_X_PERIOD_METHOD mML4Method = (ENUM_X_PERIOD_METHOD)((int)l4MethodStr); + result.l4Method = mML4Method; + } + + // + string l4PeriodStr = ExtractString( + config, + l4PeriodToken + "(", + ")"); + if (StringLen(l4PeriodStr) > 0) + { + // + ENUM_TIMEFRAMES mML4Period = (ENUM_TIMEFRAMES)((int)l4PeriodStr); + result.l4Period = mML4Period; + } + + // + return result; +} + +// +// XFIBONACCI ... + +// +string fiboLevel1Token = "fiboLevel1"; +string fiboLevel2Token = "fiboLevel2"; +string fiboLevel3Token = "fiboLevel3"; +string fiboLevel4Token = "fiboLevel4"; +string fiboLevel5Token = "fiboLevel5"; + +// +struct XFiboConfig +{ + double fiboLevel1; // Fibio 1st Level + double fiboLevel2; // Fibio 2st Level + double fiboLevel3; // Fibio 3rd Level + double fiboLevel4; // Fibio 4th Level + double fiboLevel5; // Fibio 5th Level +}; + +// +string GenerateFibonacciConfig( + double mFiboLevel1 = 0.236, // Fibio 1st Level + double mFiboLevel2 = 0.382, // Fibio 2st Level + double mFiboLevel3 = 0.5, // Fibio 3rd Level + double mFiboLevel4 = 0.618, // Fibio 4th Level + double mFiboLevel5 = 0.764 // Fibio 5th Level +) +{ + // + string result = ""; + + // + result = + // + fiboLevel1Token + "(" + ToString(mFiboLevel1) + ")" + + fiboLevel2Token + "(" + ToString(mFiboLevel2) + ")" + + fiboLevel3Token + "(" + ToString(mFiboLevel3) + ")" + + fiboLevel4Token + "(" + ToString(mFiboLevel4) + ")" + + fiboLevel5Token + "(" + ToString(mFiboLevel5) + ")" + // + ; + + // + return result; +} + +// +string ToString(XFiboConfig &config) +{ + return GenerateFibonacciConfig( + config.fiboLevel1, + config.fiboLevel2, + config.fiboLevel3, + config.fiboLevel4, + config.fiboLevel5); +} + +// +XFiboConfig PrseFiboConfig(string config) +{ + // + XFiboConfig result; + + // + string fiboLevel1Str = ExtractString( + config, + fiboLevel1Token + "(", + ")"); + if (StringLen(fiboLevel1Str) > 0) + { + // + double mFiboLevel1 = (double)fiboLevel1Str; + result.fiboLevel1 = mFiboLevel1; + } + + // + string fiboLevel2Str = ExtractString( + config, + fiboLevel2Token + "(", + ")"); + if (StringLen(fiboLevel2Str) > 0) + { + // + double mFiboLevel2 = (double)fiboLevel2Str; + result.fiboLevel2 = mFiboLevel2; + } + + // + string fiboLevel3Str = ExtractString( + config, + fiboLevel3Token + "(", + ")"); + if (StringLen(fiboLevel3Str) > 0) + { + // + double mFiboLevel3 = (double)fiboLevel3Str; + result.fiboLevel3 = mFiboLevel3; + } + + // + string fiboLevel4Str = ExtractString( + config, + fiboLevel4Token + "(", + ")"); + if (StringLen(fiboLevel4Str) > 0) + { + // + double mFiboLevel4 = (double)fiboLevel4Str; + result.fiboLevel4 = mFiboLevel4; + } + + // + string fiboLevel5Str = ExtractString( + config, + fiboLevel5Token + "(", + ")"); + if (StringLen(fiboLevel5Str) > 0) + { + // + double mFiboLevel5 = (double)fiboLevel5Str; + result.fiboLevel5 = mFiboLevel5; + } + + // + return result; +} + +// +// BOUNDARYDETECTION ... + +// +string hhModeToken = "hhMode"; +string llModeToken = "llMode"; + +// +struct XBDConfig +{ + ENUM_SERIESMODE hhMode; // Highest High Calculation Method + ENUM_SERIESMODE llMode; // Lowest Low Calculation Method +}; + +// +string GenerateBDConfig( + ENUM_SERIESMODE mHhMode = MODE_HIGH, // Highest High Calculation Method + ENUM_SERIESMODE mLlMode = MODE_LOW // Lowest Low Calculation Method +) +{ + // + string result = ""; + + // + result = + // + hhModeToken + "(" + ToString((int)mHhMode) + ")" + + llModeToken + "(" + ToString((int)mLlMode) + ")" + // + ; + + // + return result; +} + +// +string ToString(XBDConfig &config) +{ + return GenerateBDConfig( + config.hhMode, + config.llMode); +} + +// +XBDConfig ParseBDConfig(string config) +{ + // + XBDConfig result; + + // + string hhModeStr = ExtractString( + config, + hhModeToken + "(", + ")"); + if (StringLen(hhModeStr) > 0) + { + // + ENUM_SERIESMODE mHhMode = (ENUM_SERIESMODE)((int)hhModeStr); + result.hhMode = mHhMode; + } + + // + string llModeStr = ExtractString( + config, + llModeToken + "(", + ")"); + if (StringLen(llModeStr) > 0) + { + // + ENUM_SERIESMODE mLlMode = (ENUM_SERIESMODE)((int)llModeStr); + result.llMode = mLlMode; + } + + // + return result; +} + +// +// TREND ... + +// +string trendMultiplierToken = "trendMultiplier"; +string trendPriceAppliedToToken = "trendPriceAppliedTo"; + +// +struct XTDConfig +{ + double trendMultiplier; // Multiplier + ENUM_APPLIED_PRICE trendPriceAppliedTo; // Applied To +}; + +// +string GenerateTDConfig( + double mTrendMultiplier = 3, // Multiplier + ENUM_APPLIED_PRICE mTrendPriceAppliedTo = PRICE_MEDIAN // Applied To +) +{ + // + string result = ""; + + // + result = + // + trendMultiplierToken + "(" + ToString(mTrendMultiplier) + ")" + + trendPriceAppliedToToken + "(" + ToString(mTrendPriceAppliedTo) + ")" + // + ; + + // + return result; +} + +// +string ToString(XTDConfig &config) +{ + return GenerateTDConfig( + config.trendMultiplier, + config.trendPriceAppliedTo); +} + +// +XTDConfig ParseTDConfig(string config) +{ + // + XTDConfig result; + + // + string trendMultiplierStr = ExtractString( + config, + trendMultiplierToken + "(", + ")"); + if (StringLen(trendMultiplierStr) > 0) + { + // + double mTrendMultiplier = (double)trendMultiplierStr; + result.trendMultiplier = mTrendMultiplier; + } + + // + string trendPriceAppliedToStr = ExtractString( + config, + trendPriceAppliedToToken + "(", + ")"); + if (StringLen(trendPriceAppliedToStr) > 0) + { + // + ENUM_APPLIED_PRICE mTrendPriceAppliedTo = (ENUM_APPLIED_PRICE)((int)trendPriceAppliedToStr); + // + result.trendPriceAppliedTo = mTrendPriceAppliedTo; + } + + // + return result; +} + +// +// RIBBON RB ... + +// +string ribbonModeToken = "ribbonMode"; + +// +struct XRBConfig +{ + ENUM_X_MA_METHOD ribbonMode; // How to Calculate +}; + +// +string GenerateRBConfig( + ENUM_X_MA_METHOD mRibbonMode = X_MA_AMA // How to Calculate +) +{ + // + string result = ""; + + // + result = + // + ribbonModeToken + "(" + ToString(mRibbonMode) + ")" + // + ; + + // + return result; +} + +// +string ToString(XRBConfig &config) +{ + // + return GenerateRBConfig( + config.ribbonMode); +} + +// +XRBConfig ParseRBConfig(string config) +{ + // + XRBConfig result; + + // + string ribbonModeStr = ExtractString( + config, + ribbonModeToken + "(", + ")"); + if (StringLen(ribbonModeStr) > 0) + { + // + ENUM_X_MA_METHOD mRibbonMode = (ENUM_X_MA_METHOD)((int)ribbonModeStr); + result.ribbonMode = mRibbonMode; + } + + // + return result; +} + +// +// HULL ... + +// +string hullDivisorToken = "hullDivisor"; +string hullUpAppliedToToken = "hullUpAppliedTo"; +string hullDownAppliedToToken = "hullDownAppliedTo"; + +// +struct XHullConfig +{ + double hullDivisor; // Divisor (Speed) + ENUM_APPLIED_PRICE hullUpAppliedTo; // Up Zone Applied to + ENUM_APPLIED_PRICE hullDownAppliedTo; // Down Zone Applied to +}; + +// +string GenerateHullConfig( + double mHullDivisor = 2.0, // Divisor (Speed) + ENUM_APPLIED_PRICE mHullUpAppliedTo = PRICE_HIGH, // Up Zone Applied to + ENUM_APPLIED_PRICE mHullDownAppliedTo = PRICE_LOW // Down Zone Applied to +) +{ + // + string result = ""; + + // + result = + // + hullDivisorToken + "(" + ToString(mHullDivisor) + ")" + + hullUpAppliedToToken + "(" + ToString(mHullUpAppliedTo) + ")" + + hullDownAppliedToToken + "(" + ToString(mHullDownAppliedTo) + ")" + // + ; + + // + return result; +} + +// +string ToString(XHullConfig &config) +{ + // + return GenerateHullConfig( + config.hullDivisor, + config.hullUpAppliedTo, + config.hullDownAppliedTo); +} + +// +XHullConfig ParseHullConfig(string config) +{ + // + XHullConfig result; + + // + string hullDivisorStr = ExtractString( + config, + hullDivisorToken + "(", + ")"); + if (StringLen(hullDivisorStr) > 0) + { + // + double mHullDivisor = (double)hullDivisorStr; + result.hullDivisor = mHullDivisor; + } + + // + string hullUpAppliedToStr = ExtractString( + config, + hullUpAppliedToToken + "(", + ")"); + if (StringLen(hullUpAppliedToStr) > 0) + { + // + ENUM_APPLIED_PRICE mHullUpAppliedTo = (ENUM_APPLIED_PRICE)((int)hullUpAppliedToStr); + result.hullUpAppliedTo = mHullUpAppliedTo; + } + + // + string hullDownAppliedToStr = ExtractString( + config, + hullDownAppliedToToken + "(", + ")"); + if (StringLen(hullDownAppliedToStr) > 0) + { + // + ENUM_APPLIED_PRICE mHullDownAppliedTo = (ENUM_APPLIED_PRICE)((int)hullDownAppliedToStr); + result.hullDownAppliedTo = mHullDownAppliedTo; + } + + // + return result; +} + +// +// SSLC ... + +// +string sslcModeToken = "sslcMode"; +string sslcUpAppliedToToken = "sslcUpAppliedTo"; +string sslcDownAppliedToToken = "sslcDownAppliedTo"; + +// +struct XSSLCConfig +{ + ENUM_X_MA_METHOD sslcMode; // How to Calculate + ENUM_APPLIED_PRICE sslcUpAppliedTo; // Up Applied To + ENUM_APPLIED_PRICE sslcDownAppliedTo; // Down Applied To +}; + +// +string GenerateSSLCConfig( + ENUM_X_MA_METHOD mSslcMode = X_MA_SMA, // How to Calculate + ENUM_APPLIED_PRICE mSslcUpAppliedTo = PRICE_HIGH, // Up Applied To + ENUM_APPLIED_PRICE mSslcDownAppliedTo = PRICE_LOW // Down Applied To +) +{ + // + string result; + + // + result = + // + sslcModeToken + "(" + ToString(mSslcMode) + ")" + + sslcUpAppliedToToken + "(" + ToString(mSslcUpAppliedTo) + ")" + + sslcDownAppliedToToken + "(" + ToString(mSslcDownAppliedTo) + ")" + // + ; + + // + return result; +} + +// +string ToString(XSSLCConfig &config) +{ + return GenerateSSLCConfig( + config.sslcMode, + config.sslcUpAppliedTo, + config.sslcDownAppliedTo); +} + +// +XSSLCConfig ParseSSLCConfig(string config) +{ + // + XSSLCConfig result; + + // + string sslcModeStr = ExtractString( + config, + sslcModeToken + "(", + ")"); + if (StringLen(sslcModeStr) > 0) + { + // + ENUM_X_MA_METHOD mSslcMode = (ENUM_X_MA_METHOD)((int)sslcModeStr); + result.sslcMode = mSslcMode; + } + + // + string sslcUpAppliedToStr = ExtractString( + config, + sslcUpAppliedToToken + "(", + ")"); + if (StringLen(sslcUpAppliedToStr) > 0) + { + // + ENUM_APPLIED_PRICE mSslcUpAppliedTo = (ENUM_APPLIED_PRICE)((int)sslcUpAppliedToStr); + result.sslcUpAppliedTo = mSslcUpAppliedTo; + } + + // + string sslcDownAppliedToStr = ExtractString( + config, + sslcDownAppliedToToken + "(", + ")"); + if (StringLen(sslcDownAppliedToStr) > 0) + { + // + ENUM_APPLIED_PRICE mSslcDownAppliedTo = (ENUM_APPLIED_PRICE)((int)sslcDownAppliedToStr); + result.sslcDownAppliedTo = mSslcDownAppliedTo; + } + + // + return result; +} + +// +// PRESENTATION ... + +// +string showCandleTimerToken = "showCandleTimer"; +string showCandlesToken = "showCandles"; +string showHKCandlesToken = "showHKCandles"; +string showSMHKCandlesToken = "showSMHKCandles"; +string showPeaksAndValesToken = "showPeaksAndVales"; +string showTrendsToken = "showTrends"; +string fillTrendsToken = "fillTrends"; +string showLevelsToken = "showLevels"; +string showConsolidationsToken = "showConsolidations"; +string showRibbonsToken = "showRibbons"; +string showHullToken = "showHull"; +string showSSLChannelToken = "showSSLChannel"; +string showFibo1LevelsToken = "showFibo1Levels"; +string showFibo2LevelsToken = "showFibo2Levels"; +string showFibo3LevelsToken = "showFibo3Levels"; +string showFibo4LevelsToken = "showFibo4Levels"; +string showFibo5LevelsToken = "showFibo5Levels"; + +// +struct XStylePresentationConfig +{ + bool showCandleTimer; // Show Candle Time + bool showCandles; // Show Candles + bool showHKCandles; // Draw Hiken Ashi Candle + bool showSMHKCandles; // Draw Smoothed Hiken Ashi Candle +}; + +// +string GenerateStylePresentationConfig( + bool mShowCandleTimer = true, // Show Candle Time + bool mShowCandles = true, // Show Candles + bool mShowHKCandles = false, // Draw Hiken Ashi Candle + bool mShowSMHKCandles = false // Draw Smoothed Hiken Ashi Candle +) +{ + // + string result = ""; + + // + result = + // + showCandleTimerToken + "(" + ToString(mShowCandleTimer) + ")" + + showCandlesToken + "(" + ToString(mShowCandles) + ")" + + showHKCandlesToken + "(" + ToString(mShowHKCandles) + ")" + + showSMHKCandlesToken + "(" + ToString(mShowSMHKCandles) + ")" + // + ; + + // + return result; +} + +// +XStylePresentationConfig ParseStylePresentationConfig(string config) +{ + // + XStylePresentationConfig result; + + // + string showCandleTimerStr = ExtractString( + config, + showCandleTimerToken + "(", + ")"); + if (StringLen(showCandleTimerStr) > 0) + { + // + bool mShowCandleTimer = ToBoolean(showCandleTimerStr); + result.showCandleTimer = mShowCandleTimer; + } + + // + string showCandlesStr = ExtractString( + config, + showCandlesToken + "(", + ")"); + if (StringLen(showCandlesStr) > 0) + { + // + bool mShowCandles = ToBoolean(showCandlesStr); + result.showCandles = mShowCandles; + } + + // + string showHKCandlesStr = ExtractString( + config, + showHKCandlesToken + "(", + ")"); + if (StringLen(showHKCandlesStr) > 0) + { + // + bool mShowHKCandles = ToBoolean(showHKCandlesStr); + result.showHKCandles = mShowHKCandles; + } + + // + string showSMHKCandlesStr = ExtractString( + config, + showSMHKCandlesToken + "(", + ")"); + if (StringLen(showSMHKCandlesStr) > 0) + { + // + bool mShowSMHKCandles = ToBoolean(showSMHKCandlesStr); + result.showSMHKCandles = mShowSMHKCandles; + } + + // + return result; +} + +// +string ToString(XStylePresentationConfig &config) +{ + // + return GenerateStylePresentationConfig( + config.showCandleTimer, + config.showCandles, + config.showHKCandles, + config.showSMHKCandles); +} + +// +struct XPVPresentationConfig +{ + bool showPeaksAndVales; // Show Peaks and Vales + bool showLevels; // Show Levels + bool showConsolidations; // Show Consolidations +}; + +// +string GeneratePVPresentationConfig( + bool mShowPeaksAndVales = true, // Show Peaks and Vales + bool mShowLevels = false, // Show Levels + bool mShowConsolidations = false // Show Consolidations +) +{ + // + string result; + + // + result = + // + showPeaksAndValesToken + "(" + ToString(mShowPeaksAndVales) + ")" + + showLevelsToken + "(" + ToString(mShowLevels) + ")" + + showConsolidationsToken + "(" + ToString(mShowConsolidations) + ")" + // + ; + + // + return result; +} + +// +string ToString(XPVPresentationConfig &config) +{ + // + return GeneratePVPresentationConfig( + config.showPeaksAndVales, + config.showLevels, + config.showConsolidations); +} + +// +XPVPresentationConfig ParsePVPresentationConfig(string config) +{ + // + XPVPresentationConfig result; + + // + string showPeaksAndValesStr = ExtractString( + config, + showPeaksAndValesToken + "(", + ")"); + if (StringLen(showPeaksAndValesStr) > 0) + { + // + bool mShowPeaksAndVales = ToBoolean(showPeaksAndValesStr); + result.showPeaksAndVales = mShowPeaksAndVales; + } + + // + string showLevelsStr = ExtractString( + config, + showLevelsToken + "(", + ")"); + if (StringLen(showLevelsStr) > 0) + { + // + bool mShowLevels = ToBoolean(showLevelsStr); + result.showLevels = mShowLevels; + } + + // + string showConsolidationsStr = ExtractString( + config, + showConsolidationsToken + "(", + ")"); + if (StringLen(showConsolidationsStr) > 0) + { + // + bool mShowConsolidations = ToBoolean(showConsolidationsStr); + result.showConsolidations = mShowConsolidations; + } + + // + return result; +} + +// +struct XTrendPresentationConfig +{ + bool showHull; // Show Hull + bool showTrends; // Show Trends + bool fillTrends; // Fill Trends + bool showRibbons; // Show Ribbons + bool showSSLChannel; // Show SSL Channel +}; + +// +string GenerateTrendPresentationConfig( + bool mShowTrends = true, // Show Trends + bool mFillTrends = false, // Fill Trends + bool mShowRibbons = false, // Show Ribbons + bool mShowHull = false, // Show Hull + bool mShowSSLChannel = false // Show SSL Channel +) +{ + // + string result; + + // + result = + // + showTrendsToken + "(" + ToString(mShowTrends) + ")" + + fillTrendsToken + "(" + ToString(mFillTrends) + ")" + + showRibbonsToken + "(" + ToString(mShowRibbons) + ")" + + showHullToken + "(" + ToString(mShowHull) + ")" + + showSSLChannelToken + "(" + ToString(mShowSSLChannel) + ")" + // + ; + + // + return result; +} + +// +string ToString(XTrendPresentationConfig &config) +{ + // + return GenerateTrendPresentationConfig( + config.showHull, + config.showTrends, + config.fillTrends, + config.showRibbons, + config.showSSLChannel); +} + +// +XTrendPresentationConfig ParseTrendPresentationConfig(string config) +{ + // + XTrendPresentationConfig result; + + // + string showTrendsStr = ExtractString( + config, + showTrendsToken + "(", + ")"); + if (StringLen(showTrendsStr) > 0) + { + // + bool mShowTrends = ToBoolean(showTrendsStr); + result.showTrends = mShowTrends; + } + + // + string fillTrendsStr = ExtractString( + config, + fillTrendsToken + "(", + ")"); + if (StringLen(fillTrendsStr) > 0) + { + // + bool mFillTrends = ToBoolean(fillTrendsStr); + result.fillTrends = mFillTrends; + } + + // + string showRibbonsStr = ExtractString( + config, + showRibbonsToken + "(", + ")"); + if (StringLen(showRibbonsStr) > 0) + { + // + bool mShowRibbons = ToBoolean(showRibbonsStr); + result.showRibbons = mShowRibbons; + } + + // + string showHullStr = ExtractString( + config, + showHullToken + "(", + ")"); + if (StringLen(showHullStr) > 0) + { + // + bool mShowHull = ToBoolean(showHullStr); + result.showHull = mShowHull; + } + + // + string showSSLChannelStr = ExtractString( + config, + showSSLChannelToken + "(", + ")"); + if (StringLen(showSSLChannelStr) > 0) + { + // + bool mShowSSLChannel = ToBoolean(showSSLChannelStr); + result.showSSLChannel = mShowSSLChannel; + } + + // + return result; +} + +// +struct XFiboPresentationConfig +{ + bool showFibo1Levels; // Show Fibo 1st Level + bool showFibo2Levels; // Show Fibo 2nd Level + bool showFibo3Levels; // Show Fibo 3rd Level + bool showFibo4Levels; // Show Fibo 4th Level + bool showFibo5Levels; // Show Fibo 5th Level +}; + +// +string GenerateFiboPresentationConfig( + bool mShowFibo1Levels = false, // Show Fibo 1st Level + bool mShowFibo2Levels = false, // Show Fibo 2nd Level + bool mShowFibo3Levels = false, // Show Fibo 3rd Level + bool mShowFibo4Levels = false, // Show Fibo 4th Level + bool mShowFibo5Levels = false // Show Fibo 5th Level +) +{ + // + string result = ""; + + // + result = + // + showFibo1LevelsToken + "(" + ToString(mShowFibo1Levels) + ")" + + showFibo2LevelsToken + "(" + ToString(mShowFibo2Levels) + ")" + + showFibo3LevelsToken + "(" + ToString(mShowFibo3Levels) + ")" + + showFibo4LevelsToken + "(" + ToString(mShowFibo4Levels) + ")" + + showFibo5LevelsToken + "(" + ToString(mShowFibo5Levels) + ")" + // + ; + + // + return result; +} + +// +string ToString(XFiboPresentationConfig &config) +{ + // + return GenerateFiboPresentationConfig( + config.showFibo1Levels, + config.showFibo2Levels, + config.showFibo3Levels, + config.showFibo4Levels, + config.showFibo5Levels); +} + +// +XFiboPresentationConfig ParePresentationConfig(string config) +{ + // + XFiboPresentationConfig result; + + // + string showFibo1LevelsStr = ExtractString( + config, + showFibo1LevelsToken + "(", + ")"); + if (StringLen(showFibo1LevelsStr) > 0) + { + // + bool mShowFibo1Levels = ToBoolean(showFibo1LevelsStr); + result.showFibo1Levels = mShowFibo1Levels; + } + + // + string showFibo2LevelsStr = ExtractString( + config, + showFibo2LevelsToken + "(", + ")"); + if (StringLen(showFibo2LevelsStr) > 0) + { + // + bool mShowFibo2Levels = ToBoolean(showFibo2LevelsStr); + result.showFibo2Levels = mShowFibo2Levels; + } + + // + string showFibo3LevelsStr = ExtractString( + config, + showFibo3LevelsToken + "(", + ")"); + if (StringLen(showFibo3LevelsStr) > 0) + { + // + bool mShowFibo3Levels = ToBoolean(showFibo3LevelsStr); + result.showFibo3Levels = mShowFibo3Levels; + } + + // + string showFibo4LevelsStr = ExtractString( + config, + showFibo4LevelsToken + "(", + ")"); + if (StringLen(showFibo4LevelsStr) > 0) + { + // + bool mShowFibo4Levels = ToBoolean(showFibo4LevelsStr); + result.showFibo4Levels = mShowFibo4Levels; + } + + // + string showFibo5LevelsStr = ExtractString( + config, + showFibo5LevelsToken + "(", + ")"); + if (StringLen(showFibo5LevelsStr) > 0) + { + // + bool mShowFibo5Levels = ToBoolean(showFibo5LevelsStr); + result.showFibo5Levels = mShowFibo5Levels; + } + + // + return result; +} + +// +// +//