From 1beebac2d2313f464cba425a60a7765b3b3d1b2e Mon Sep 17 00:00:00 2001 From: EarnForex <48102957+EarnForex@users.noreply.github.com> Date: Tue, 8 Feb 2022 20:16:26 +0200 Subject: [PATCH] 1.06 1. Added two conditions for current chart's spread. 2. Added two conditions for account's margin level. 3. Added six conditions for daily profit/loss triggering. 4. Added a filter based on whether a trade is in profit or in loss. 5. Instrument filter now can accept a list of trading instruments to analyze or to ignore. 6. Fixed compatibility with other panel-based indicators and EAs. 7. Improved performance when checking some particularly slow-to-check conditions. 8. Optimized filtering by magic numbers. 9. The Emergency Button will no correctly close open positions. In version 1.05, it only deleted pending orders. 10. The AP will now correctly check the respective checkbox when deciding whether to apply the "Breakeven extra profit value (points)". 11. "Pips" have been changed to "points" throughout the panel to avoid confusion. --- .../Account Protector/Account Protector.mq4 | 71 +- .../Account Protector/Account Protector.mqh | 1763 ++++++++++++----- MQL4/Experts/Account Protector/Defines.mqh | 45 +- .../Account Protector/Account Protector.mq5 | Bin 29122 -> 34058 bytes .../Account Protector/Account Protector.mqh | Bin 421238 -> 518522 bytes MQL5/Experts/Account Protector/Defines.mqh | Bin 10930 -> 13044 bytes README_Images/account-protector-example.png | Bin 47360 -> 26996 bytes 7 files changed, 1366 insertions(+), 513 deletions(-) diff --git a/MQL4/Experts/Account Protector/Account Protector.mq4 b/MQL4/Experts/Account Protector/Account Protector.mq4 index 702ece4..1fe220e 100644 --- a/MQL4/Experts/Account Protector/Account Protector.mq4 +++ b/MQL4/Experts/Account Protector/Account Protector.mq4 @@ -1,12 +1,12 @@ //+------------------------------------------------------------------+ //| Account Protector.mq4 | -//| Copyright © 2017-2021, EarnForex.com | +//| Copyright © 2017-2022, EarnForex.com | //| https://www.earnforex.com/ | //+------------------------------------------------------------------+ #property copyright "EarnForex.com" #property link "https://www.earnforex.com/metatrader-expert-advisors/Account-Protector/" -#property version "1.05" -string Version = "1.05"; +#property version "1.06" +string Version = "1.06"; #property strict #property description "Protects account balance by applying given actions when set conditions trigger." @@ -25,21 +25,32 @@ input bool DisableFloatLossRisePerc = false; // Disable floating loss rises % co input bool DisableFloatLossFallPerc = true; // Disable floating loss falls % condition. input bool DisableFloatLossRiseCurr = false; // Disable floating loss rises currency units condition. input bool DisableFloatLossFallCurr = true; // Disable floating loss falls currency units condition. -input bool DisableFloatLossRisePips = false; // Disable floating loss rises pips condition. -input bool DisableFloatLossFallPips = true; // Disable floating loss falls pips condition. +input bool DisableFloatLossRisePoints = false; // Disable floating loss rises points condition. +input bool DisableFloatLossFallPoints = true; // Disable floating loss falls points condition. input bool DisableFloatProfitRisePerc = false; // Disable floating profit rises % condition. input bool DisableFloatProfitFallPerc = true; // Disable floating profit falls % condition. input bool DisableFloatProfitRiseCurr = false; // Disable floating profit rises currency units condition. input bool DisableFloatProfitFallCurr = true; // Disable floating profit falls currency units condition. -input bool DisableFloatProfitRisePips = false; // Disable floating profit rises pips condition. -input bool DisableFloatProfitFallPips = true; // Disable floating profit falls pips condition. +input bool DisableFloatProfitRisePoints = false; // Disable floating profit rises points condition. +input bool DisableFloatProfitFallPoints = true; // Disable floating profit falls points condition. input bool DisableCurrentPriceGE = true; // Disable current price greater or equal condition. input bool DisableCurrentPriceLE = true; // Disable current price less or equal condition. input bool DisableEquityMinusSnapshot = true; // Disable (Equity - snapshot) greater or equal condition. input bool DisableSnapshotMinusEquity = true; // Disable (snapshot - Equity) greater or equal condition. +input bool DisableMarginLevelGE = true; // Disable margin level greater or equal condition. +input bool DisableMarginLevelLE = true; // Disable margin level less or equal condition. +input bool DisableSpreadGE = true; // Disable spread greater or equal condition. +input bool DisableSpreadLE = true; // Disable spread less or equal condition. +input bool DisableDailyProfitLossUnitsGE = true; // Disable daily profit/loss greater or equal units condition. +input bool DisableDailyProfitLossUnitsLE = true; // Disable daily profit/loss level less or equal units condition. +input bool DisableDailyProfitLossPointsGE = true; // Disable daily profit/loss greater or equal points condition. +input bool DisableDailyProfitLossPointsLE = true; // Disable daily profit/loss level less or equal points condition. +input bool DisableDailyProfitLossPercGE = true; // Disable daily profit/loss greater or equal percentage condition. +input bool DisableDailyProfitLossPercLE = true; // Disable daily profit/loss level less or equal percentage condition. input int DelayOrderClose = 0; // DelayOrderClose: Delay in milliseconds. input bool UseTotalVolume = false; // UseTotalVolume: enable if trading with many small trades and partial position closing. input double AdditionalFunds = 0; // AdditionalFunds: Added to balance, equity, and free margin. +input string Instruments = ""; // Instruments: Default list of trading instruments for order filtering. CAccountProtector ExtDialog; @@ -48,6 +59,8 @@ CAccountProtector ExtDialog; //+------------------------------------------------------------------+ int OnInit() { + MathSrand(GetTickCount() + 2202051901); // Used by CreateInstanceId() in Dialog.mqh (standard library). Keep the second number unique across other panel indicators/EAs. + if (!ExtDialog.LoadSettingsFromDisk()) { sets.CountCommSwaps = true; @@ -75,18 +88,21 @@ int OnInit() sets.MagicNumbers = ""; sets.boolExcludeMagics = false; sets.intInstrumentFilter = 0; + sets.Instruments = Instruments; + sets.boolIgnoreLossTrades = false; + sets.boolIgnoreProfitTrades = false; sets.boolLossPerBalance = false; sets.boolLossQuanUnits = false; - sets.boolLossPips = false; + sets.boolLossPoints = false; sets.boolProfPerBalance = false; sets.boolProfQuanUnits = false; - sets.boolProfPips = false; + sets.boolProfPoints = false; sets.boolLossPerBalanceReverse = false; sets.boolLossQuanUnitsReverse = false; - sets.boolLossPipsReverse = false; + sets.boolLossPointsReverse = false; sets.boolProfPerBalanceReverse = false; sets.boolProfQuanUnitsReverse = false; - sets.boolProfPipsReverse = false; + sets.boolProfPointsReverse = false; sets.boolEquityLessUnits = false; sets.boolEquityGrUnits = false; sets.boolEquityLessPerSnap = false; @@ -99,18 +115,28 @@ int OnInit() sets.boolMarginGrPerSnap = false; sets.boolPriceGE = false; sets.boolPriceLE = false; + sets.boolMarginLevelGE = false; + sets.boolMarginLevelLE = false; + sets.boolSpreadGE = false; + sets.boolSpreadLE = false; + sets.boolDailyProfitLossUnitsGE = false; + sets.boolDailyProfitLossUnitsLE = false; + sets.boolDailyProfitLossPointsGE = false; + sets.boolDailyProfitLossPointsLE = false; + sets.boolDailyProfitLossPercGE = false; + sets.boolDailyProfitLossPercLE = false; sets.doubleLossPerBalance = 0; sets.doubleLossQuanUnits = 0; - sets.intLossPips = 0; + sets.intLossPoints = 0; sets.doubleProfPerBalance = 0; sets.doubleProfQuanUnits = 0; - sets.intProfPips = 0; + sets.intProfPoints = 0; sets.doubleLossPerBalanceReverse = 0; sets.doubleLossQuanUnitsReverse = 0; - sets.intLossPipsReverse = 0; + sets.intLossPointsReverse = 0; sets.doubleProfPerBalanceReverse = 0; sets.doubleProfQuanUnitsReverse = 0; - sets.intProfPipsReverse = 0; + sets.intProfPointsReverse = 0; sets.doubleEquityLessUnits = 0; sets.doubleEquityGrUnits = 0; sets.doubleEquityLessPerSnap = 0; @@ -123,6 +149,16 @@ int OnInit() sets.doubleMarginGrPerSnap = 0; sets.doublePriceGE = 0; sets.doublePriceLE = 0; + sets.doubleMarginLevelGE = 0; + sets.doubleMarginLevelLE = 0; + sets.intSpreadGE = 0; + sets.intSpreadLE = 0; + sets.doubleDailyProfitLossUnitsGE= 0; + sets.doubleDailyProfitLossUnitsLE = 0; + sets.intDailyProfitLossPointsGE= 0; + sets.intDailyProfitLossPointsLE = 0; + sets.doubleDailyProfitLossPercGE= 0; + sets.doubleDailyProfitLossPercLE = 0; sets.ClosePos = true; sets.doubleClosePercentage = 100; sets.CloseWhichPositions = All; @@ -218,6 +254,7 @@ void OnDeinit(const int reason) } else { + if (reason == REASON_PARAMETERS) GlobalVariableSet("AP-" + IntegerToString(ChartID()) + "-Parameters", 1); ExtDialog.SaveSettingsOnDisk(); ExtDialog.IniFileSave(); } @@ -233,14 +270,14 @@ void OnChartEvent(const int id, const double &dparam, const string &sparam) { -// Remember the panel's location to have the same location for minimized and maximized states. + // Remember the panel's location to have the same location for minimized and maximized states. if ((id == CHARTEVENT_CUSTOM + ON_DRAG_END) && (lparam == -1)) { ExtDialog.remember_top = ExtDialog.Top(); ExtDialog.remember_left = ExtDialog.Left(); } -// Call Panel's event handler only if it is not a CHARTEVENT_CHART_CHANGE - workaround for minimization bug on chart switch. + // Call Panel's event handler only if it is not a CHARTEVENT_CHART_CHANGE - workaround for minimization bug on chart switch. if (id != CHARTEVENT_CHART_CHANGE) ExtDialog.OnEvent(id, lparam, dparam, sparam); if (ExtDialog.Top() < 0) ExtDialog.Move(ExtDialog.Left(), 0); diff --git a/MQL4/Experts/Account Protector/Account Protector.mqh b/MQL4/Experts/Account Protector/Account Protector.mqh index c79dc80..67d246e 100644 --- a/MQL4/Experts/Account Protector/Account Protector.mqh +++ b/MQL4/Experts/Account Protector/Account Protector.mqh @@ -1,6 +1,6 @@ //+------------------------------------------------------------------+ //| Account Protector.mqh | -//| Copyright © 2017-2021, EarnForex.com | +//| Copyright © 2017-2022, EarnForex.com | //| https://www.earnforex.com/ | //+------------------------------------------------------------------+ #include "Defines.mqh" @@ -32,11 +32,11 @@ private: CButton m_BtnNewSnapEquity, m_BtnResetEquityStopLoss, m_BtnNewSnapMargin, m_BtnEmergency, m_BtnDayOfWeek; // Filters Tab - Labels - CLabel m_LblMagics, m_LblOrderCommentary; + CLabel m_LblMagics, m_LblOrderCommentary, m_LblInstruments; // Filters Tab - CheckBoxes - CCheckBox m_ChkExcludeMagics; + CCheckBox m_ChkExcludeMagics, m_ChkIgnoreLossTrades, m_ChkIgnoreProfitTrades; // Filters Tab - Edits - CEdit m_EdtMagics, m_EdtOrderCommentary; + CEdit m_EdtMagics, m_EdtOrderCommentary, m_EdtInstruments; // Filters Tab - Buttons CButton m_BtnResetFilters; // Filters Tab - Radio Group @@ -45,17 +45,19 @@ private: CComboBox m_CbxOrderCommentaryCondition; // Conditions Tab - CheckBoxes - CCheckBox m_ChkLossPerBalance, m_ChkLossQuanUnits, m_ChkLossPips, m_ChkProfPerBalance, m_ChkProfQuanUnits, m_ChkProfPips; - CCheckBox m_ChkLossPerBalanceReverse, m_ChkLossQuanUnitsReverse, m_ChkLossPipsReverse, m_ChkProfPerBalanceReverse, m_ChkProfQuanUnitsReverse, m_ChkProfPipsReverse; + CCheckBox m_ChkLossPerBalance, m_ChkLossQuanUnits, m_ChkLossPoints, m_ChkProfPerBalance, m_ChkProfQuanUnits, m_ChkProfPoints; + CCheckBox m_ChkLossPerBalanceReverse, m_ChkLossQuanUnitsReverse, m_ChkLossPointsReverse, m_ChkProfPerBalanceReverse, m_ChkProfQuanUnitsReverse, m_ChkProfPointsReverse; CCheckBox m_ChkEquityLessUnits, m_ChkEquityGrUnits, m_ChkEquityLessPerSnap, m_ChkEquityGrPerSnap, m_ChkEquityMinusSnapshot, m_ChkSnapshotMinusEquity; CCheckBox m_ChkMarginLessUnits, m_ChkMarginGrUnits, m_ChkMarginLessPerSnap, m_ChkMarginGrPerSnap; - CCheckBox m_ChkPriceGE, m_ChkPriceLE; + CCheckBox m_ChkPriceGE, m_ChkPriceLE, m_ChkMarginLevelGE, m_ChkMarginLevelLE, m_ChkSpreadGE, m_ChkSpreadLE; + CCheckBox m_ChkDailyProfitLossUnitsGE, m_ChkDailyProfitLossUnitsLE, m_ChkDailyProfitLossPointsGE, m_ChkDailyProfitLossPointsLE, m_ChkDailyProfitLossPercGE, m_ChkDailyProfitLossPercLE; // Conditions Tab - Edits - CEdit m_EdtLossPerBalance, m_EdtLossQuanUnits, m_EdtLossPips, m_EdtProfPerBalance, m_EdtProfQuanUnits, m_EdtProfPips; - CEdit m_EdtLossPerBalanceReverse, m_EdtLossQuanUnitsReverse, m_EdtLossPipsReverse, m_EdtProfPerBalanceReverse, m_EdtProfQuanUnitsReverse, m_EdtProfPipsReverse; + CEdit m_EdtLossPerBalance, m_EdtLossQuanUnits, m_EdtLossPoints, m_EdtProfPerBalance, m_EdtProfQuanUnits, m_EdtProfPoints; + CEdit m_EdtLossPerBalanceReverse, m_EdtLossQuanUnitsReverse, m_EdtLossPointsReverse, m_EdtProfPerBalanceReverse, m_EdtProfQuanUnitsReverse, m_EdtProfPointsReverse; CEdit m_EdtEquityLessUnits, m_EdtEquityGrUnits, m_EdtEquityLessPerSnap, m_EdtEquityGrPerSnap, m_EdtEquityMinusSnapshot, m_EdtSnapshotMinusEquity; CEdit m_EdtMarginLessUnits, m_EdtMarginGrUnits, m_EdtMarginLessPerSnap, m_EdtMarginGrPerSnap; - CEdit m_EdtPriceGE, m_EdtPriceLE; + CEdit m_EdtPriceGE, m_EdtPriceLE, m_EdtMarginLevelGE, m_EdtMarginLevelLE, m_EdtSpreadGE, m_EdtSpreadLE; + CEdit m_EdtDailyProfitLossUnitsGE, m_EdtDailyProfitLossUnitsLE, m_EdtDailyProfitLossPointsGE, m_EdtDailyProfitLossPointsLE, m_EdtDailyProfitLossPercGE, m_EdtDailyProfitLossPercLE; // Actions Tab - Labels CLabel m_LblClosePosSuffix, m_LblClosePosPostfix; @@ -67,7 +69,8 @@ private: CButton m_BtnPositionStatus; string m_FileName; - int LogFile, QuantityClosedMarketOrders, QuantityDeletedPendingOrders, magic_array_counter, MagicNumbers_array[]; + int LogFile, QuantityClosedMarketOrders, QuantityDeletedPendingOrders, magic_array_counter, MagicNumbers_array[], instruments_array_counter; + string Instruments_array[]; bool IsANeedToContinueClosingOrders, IsANeedToContinueDeletingPendingOrders; bool WasAutoTradingDisabled, WasMailSent, WasNotificationSent, WasPlatformClosed, WasAutoTradingEnabled, WasRecapturedSnapshots; double m_DPIScale; @@ -88,56 +91,57 @@ public: virtual bool Create(const long chart, const string name, const int subwin, const int x1, const int y1); virtual void Destroy(); void ShowSelectedTab(); - virtual bool SaveSettingsOnDisk(); - virtual bool LoadSettingsFromDisk(); - virtual bool DeleteSettingsFile(); + bool SaveSettingsOnDisk(); + bool LoadSettingsFromDisk(); + bool DeleteSettingsFile(); virtual bool OnEvent(const int id, const long& lparam, const double& dparam, const string& sparam); - virtual bool RefreshValues(); - virtual void RefreshPanelControls(); + bool RefreshValues(); + void RefreshPanelControls(); void CheckAllConditions(); void Trailing(); void EquityTrailing(); void MoveToBreakEven(); - virtual void Logging(const string message); + void Logging(const string message); bool SilentLogging; void Logging_Current_Settings(); - virtual void HideShowMaximize(bool max); + void HideShowMaximize(bool max); // Remember the panel's location to have the same location for minimized and maximized states. int remember_top, remember_left; private: - virtual bool CreateObjects(); - virtual bool InitObjects(); - virtual void MoveAndResize(); - virtual bool ButtonCreate (CButton& Btn, const int X1, const int Y1, const int X2, const int Y2, const string Name, const string Text); - virtual bool CheckBoxCreate (CCheckBox& Chk, const int X1, const int Y1, const int X2, const int Y2, const string Name, const string Text); - virtual bool EditCreate (CEdit& Edt, const int X1, const int Y1, const int X2, const int Y2, const string Name, const string Text); - virtual bool LabelCreate (CLabel& Lbl, const int X1, const int Y1, const int X2, const int Y2, const string Name, const string Text); - virtual bool RadioGroupCreate (CRadioGroup& Rgp, const int X1, const int Y1, const int X2, const int Y2, const string Name, const string &Text[]); - virtual bool ComboBoxCreate (CComboBox& Cbx, const int X1, const int Y1, const int X2, const int Y2, const string Name, const string &Text[]); - virtual void ShowMain(); - virtual void ShowFilters(); - virtual void ShowConditions(); - virtual void ShowActions(); - virtual void HideMain(); - virtual void HideFilters(); - virtual void HideConditions(); - virtual void HideActions(); + bool CreateObjects(); + bool InitObjects(); + void MoveAndResize(); + bool ButtonCreate (CButton& Btn, const int X1, const int Y1, const int X2, const int Y2, const string Name, const string Text); + bool CheckBoxCreate (CCheckBox& Chk, const int X1, const int Y1, const int X2, const int Y2, const string Name, const string Text); + bool EditCreate (CEdit& Edt, const int X1, const int Y1, const int X2, const int Y2, const string Name, const string Text); + bool LabelCreate (CLabel& Lbl, const int X1, const int Y1, const int X2, const int Y2, const string Name, const string Text); + bool RadioGroupCreate (CRadioGroup& Rgp, const int X1, const int Y1, const int X2, const int Y2, const string Name, const string &Text[]); + bool ComboBoxCreate (CComboBox& Cbx, const int X1, const int Y1, const int X2, const int Y2, const string Name, const string &Text[]); + void ShowMain(); + void ShowFilters(); + void ShowConditions(); + void ShowActions(); + void HideMain(); + void HideFilters(); + void HideConditions(); + void HideActions(); virtual void Maximize(); virtual void Minimize(); - virtual void SeekAndDestroyDuplicatePanels(); + void SeekAndDestroyDuplicatePanels(); - virtual void Check_Status(); - virtual bool No_Condition(); - virtual bool No_Action(); + void Check_Status(); + bool No_Condition(); + bool No_Action(); string NewTime(); bool CheckFilterSymbol(const string order_symbol); bool CheckFilterComment(const string order_comment); bool CheckFilterMagic(const int order_magic, const int j); - virtual void Close_All_Positions(); - virtual void Delete_All_Pending_Orders(); - virtual int Eliminate_Current_Order(const int ticket); + bool CheckFilterLossProfit(const double order_profit); + void Close_All_Positions(); + void Delete_All_Pending_Orders(); + int Eliminate_Current_Order(const int ticket); void Trigger_Actions(const string title); void Logging_Condition_Is_Met(); void PrepareSubjectBody(string &subject, string &body, const string title, const datetime timestamp, const int pos_closed, const int pend_deleted, const bool autotrade_dis, const bool push_sent, const bool mail_sent, const bool platf_closed, const bool autotrade_enabled, const bool snapshots_recaptured, const bool short_body = false); @@ -145,7 +149,8 @@ private: void SendNotificationFunction(string subject, string body); template void CheckOneCondition(T &SettingsEditValue, bool &SettingsCheckboxValue, const string EventDescription, const ENUM_CONDITIONS triggered_condition = Other_condition); - virtual void ProcessMagicNumbers(); + void ProcessMagicNumbers(); + void ProcessInstruments(); bool IsDouble(const string value); bool IsInteger(const string value); double CalculateOrderLots(const double lots, const string symbol); @@ -177,19 +182,22 @@ private: void OnEndEditMagics(); void OnChangeChkExcludeMagics(); void OnChangeRgpInstrumentFilter(); + void OnEndEditInstruments(); + void OnChangeChkIgnoreLossTrades(); + void OnChangeChkIgnoreProfitTrades(); void OnClickBtnResetFilters(); void OnChangeChkLossPerBalance(); void OnChangeChkLossPerBalanceReverse(); void OnChangeChkLossQuanUnits(); void OnChangeChkLossQuanUnitsReverse(); - void OnChangeChkLossPips(); - void OnChangeChkLossPipsReverse(); + void OnChangeChkLossPoints(); + void OnChangeChkLossPointsReverse(); void OnChangeChkProfPerBalance(); void OnChangeChkProfPerBalanceReverse(); void OnChangeChkProfQuanUnits(); void OnChangeChkProfQuanUnitsReverse(); - void OnChangeChkProfPips(); - void OnChangeChkProfPipsReverse(); + void OnChangeChkProfPoints(); + void OnChangeChkProfPointsReverse(); void OnChangeChkEquityLessUnits(); void OnChangeChkEquityGrUnits(); void OnChangeChkEquityLessPerSnap(); @@ -202,6 +210,16 @@ private: void OnChangeChkMarginGrPerSnap(); void OnChangeChkPriceGE(); void OnChangeChkPriceLE(); + void OnChangeChkMarginLevelGE(); + void OnChangeChkMarginLevelLE(); + void OnChangeChkSpreadGE(); + void OnChangeChkSpreadLE(); + void OnChangeChkDailyProfitLossUnitsGE(); + void OnChangeChkDailyProfitLossUnitsLE(); + void OnChangeChkDailyProfitLossPointsGE(); + void OnChangeChkDailyProfitLossPointsLE(); + void OnChangeChkDailyProfitLossPercGE(); + void OnChangeChkDailyProfitLossPercLE(); void OnChangeChkClosePos(); void OnChangeChkDeletePend(); void OnChangeChkDisAuto(); @@ -214,14 +232,14 @@ private: void OnEndEditLossPerBalanceReverse(); void OnEndEditLossQuanUnits(); void OnEndEditLossQuanUnitsReverse(); - void OnEndEditLossPips(); - void OnEndEditLossPipsReverse(); + void OnEndEditLossPoints(); + void OnEndEditLossPointsReverse(); void OnEndEditProfPerBalance(); void OnEndEditProfPerBalanceReverse(); void OnEndEditProfQuanUnits(); void OnEndEditProfQuanUnitsReverse(); - void OnEndEditProfPips(); - void OnEndEditProfPipsReverse(); + void OnEndEditProfPoints(); + void OnEndEditProfPointsReverse(); void OnEndEditEquityLessUnits(); void OnEndEditEquityGrUnits(); void OnEndEditEquityLessPerSnap(); @@ -234,6 +252,16 @@ private: void OnEndEditMarginGrPerSnap(); void OnEndEditPriceGE(); void OnEndEditPriceLE(); + void OnEndEditMarginLevelGE(); + void OnEndEditMarginLevelLE(); + void OnEndEditSpreadGE(); + void OnEndEditSpreadLE(); + void OnEndEditDailyProfitLossUnitsGE(); + void OnEndEditDailyProfitLossUnitsLE(); + void OnEndEditDailyProfitLossPointsGE(); + void OnEndEditDailyProfitLossPointsLE(); + void OnEndEditDailyProfitLossPercGE(); + void OnEndEditDailyProfitLossPercLE(); void OnEndEditClosePercentage(); void OnClickBtnEmergency(); void OnClickBtnDayOfWeek(); @@ -280,19 +308,22 @@ ON_EVENT(ON_END_EDIT, m_EdtOrderCommentary, OnEndEditOrderCommentary) ON_EVENT(ON_END_EDIT, m_EdtMagics, OnEndEditMagics) ON_EVENT(ON_CHANGE, m_ChkExcludeMagics, OnChangeChkExcludeMagics) ON_EVENT(ON_CHANGE, m_RgpInstrumentFilter, OnChangeRgpInstrumentFilter) +ON_EVENT(ON_END_EDIT, m_EdtInstruments, OnEndEditInstruments) +ON_EVENT(ON_CHANGE, m_ChkIgnoreLossTrades, OnChangeChkIgnoreLossTrades) +ON_EVENT(ON_CHANGE, m_ChkIgnoreProfitTrades, OnChangeChkIgnoreProfitTrades) ON_EVENT(ON_CLICK, m_BtnResetFilters, OnClickBtnResetFilters) ON_EVENT(ON_CHANGE, m_ChkLossPerBalance, OnChangeChkLossPerBalance) ON_EVENT(ON_CHANGE, m_ChkLossPerBalanceReverse, OnChangeChkLossPerBalanceReverse) ON_EVENT(ON_CHANGE, m_ChkLossQuanUnits, OnChangeChkLossQuanUnits) ON_EVENT(ON_CHANGE, m_ChkLossQuanUnitsReverse, OnChangeChkLossQuanUnitsReverse) -ON_EVENT(ON_CHANGE, m_ChkLossPips, OnChangeChkLossPips) -ON_EVENT(ON_CHANGE, m_ChkLossPipsReverse, OnChangeChkLossPipsReverse) +ON_EVENT(ON_CHANGE, m_ChkLossPoints, OnChangeChkLossPoints) +ON_EVENT(ON_CHANGE, m_ChkLossPointsReverse, OnChangeChkLossPointsReverse) ON_EVENT(ON_CHANGE, m_ChkProfPerBalance, OnChangeChkProfPerBalance) ON_EVENT(ON_CHANGE, m_ChkProfPerBalanceReverse, OnChangeChkProfPerBalanceReverse) ON_EVENT(ON_CHANGE, m_ChkProfQuanUnits, OnChangeChkProfQuanUnits) ON_EVENT(ON_CHANGE, m_ChkProfQuanUnitsReverse, OnChangeChkProfQuanUnitsReverse) -ON_EVENT(ON_CHANGE, m_ChkProfPips, OnChangeChkProfPips) -ON_EVENT(ON_CHANGE, m_ChkProfPipsReverse, OnChangeChkProfPipsReverse) +ON_EVENT(ON_CHANGE, m_ChkProfPoints, OnChangeChkProfPoints) +ON_EVENT(ON_CHANGE, m_ChkProfPointsReverse, OnChangeChkProfPointsReverse) ON_EVENT(ON_CHANGE, m_ChkEquityLessUnits, OnChangeChkEquityLessUnits) ON_EVENT(ON_CHANGE, m_ChkEquityGrUnits, OnChangeChkEquityGrUnits) ON_EVENT(ON_CHANGE, m_ChkEquityLessPerSnap, OnChangeChkEquityLessPerSnap) @@ -305,6 +336,16 @@ ON_EVENT(ON_CHANGE, m_ChkMarginLessPerSnap, OnChangeChkMarginLessPerSnap) ON_EVENT(ON_CHANGE, m_ChkMarginGrPerSnap, OnChangeChkMarginGrPerSnap) ON_EVENT(ON_CHANGE, m_ChkPriceGE, OnChangeChkPriceGE) ON_EVENT(ON_CHANGE, m_ChkPriceLE, OnChangeChkPriceLE) +ON_EVENT(ON_CHANGE, m_ChkMarginLevelGE, OnChangeChkMarginLevelGE) +ON_EVENT(ON_CHANGE, m_ChkMarginLevelLE, OnChangeChkMarginLevelLE) +ON_EVENT(ON_CHANGE, m_ChkSpreadGE, OnChangeChkSpreadGE) +ON_EVENT(ON_CHANGE, m_ChkSpreadLE, OnChangeChkSpreadLE) +ON_EVENT(ON_CHANGE, m_ChkDailyProfitLossUnitsGE, OnChangeChkDailyProfitLossUnitsGE) +ON_EVENT(ON_CHANGE, m_ChkDailyProfitLossUnitsLE, OnChangeChkDailyProfitLossUnitsLE) +ON_EVENT(ON_CHANGE, m_ChkDailyProfitLossPointsGE, OnChangeChkDailyProfitLossPointsGE) +ON_EVENT(ON_CHANGE, m_ChkDailyProfitLossPointsLE, OnChangeChkDailyProfitLossPointsLE) +ON_EVENT(ON_CHANGE, m_ChkDailyProfitLossPercGE, OnChangeChkDailyProfitLossPercGE) +ON_EVENT(ON_CHANGE, m_ChkDailyProfitLossPercLE, OnChangeChkDailyProfitLossPercLE) ON_EVENT(ON_CHANGE, m_ChkClosePos, OnChangeChkClosePos) ON_EVENT(ON_CLICK, m_BtnPositionStatus, OnClickBtnPositionStatus) ON_EVENT(ON_CHANGE, m_ChkDeletePend, OnChangeChkDeletePend) @@ -318,14 +359,14 @@ ON_EVENT(ON_END_EDIT, m_EdtLossPerBalance, OnEndEditLossPerBalance) ON_EVENT(ON_END_EDIT, m_EdtLossPerBalanceReverse, OnEndEditLossPerBalanceReverse) ON_EVENT(ON_END_EDIT, m_EdtLossQuanUnits, OnEndEditLossQuanUnits) ON_EVENT(ON_END_EDIT, m_EdtLossQuanUnitsReverse, OnEndEditLossQuanUnitsReverse) -ON_EVENT(ON_END_EDIT, m_EdtLossPips, OnEndEditLossPips) -ON_EVENT(ON_END_EDIT, m_EdtLossPipsReverse, OnEndEditLossPipsReverse) +ON_EVENT(ON_END_EDIT, m_EdtLossPoints, OnEndEditLossPoints) +ON_EVENT(ON_END_EDIT, m_EdtLossPointsReverse, OnEndEditLossPointsReverse) ON_EVENT(ON_END_EDIT, m_EdtProfPerBalance, OnEndEditProfPerBalance) ON_EVENT(ON_END_EDIT, m_EdtProfPerBalanceReverse, OnEndEditProfPerBalanceReverse) ON_EVENT(ON_END_EDIT, m_EdtProfQuanUnits, OnEndEditProfQuanUnits) ON_EVENT(ON_END_EDIT, m_EdtProfQuanUnitsReverse, OnEndEditProfQuanUnitsReverse) -ON_EVENT(ON_END_EDIT, m_EdtProfPips, OnEndEditProfPips) -ON_EVENT(ON_END_EDIT, m_EdtProfPipsReverse, OnEndEditProfPipsReverse) +ON_EVENT(ON_END_EDIT, m_EdtProfPoints, OnEndEditProfPoints) +ON_EVENT(ON_END_EDIT, m_EdtProfPointsReverse, OnEndEditProfPointsReverse) ON_EVENT(ON_END_EDIT, m_EdtEquityLessUnits, OnEndEditEquityLessUnits) ON_EVENT(ON_END_EDIT, m_EdtEquityGrUnits, OnEndEditEquityGrUnits) ON_EVENT(ON_END_EDIT, m_EdtEquityLessPerSnap, OnEndEditEquityLessPerSnap) @@ -338,6 +379,16 @@ ON_EVENT(ON_END_EDIT, m_EdtMarginLessPerSnap, OnEndEditMarginLessPerSnap) ON_EVENT(ON_END_EDIT, m_EdtMarginGrPerSnap, OnEndEditMarginGrPerSnap) ON_EVENT(ON_END_EDIT, m_EdtPriceGE, OnEndEditPriceGE) ON_EVENT(ON_END_EDIT, m_EdtPriceLE, OnEndEditPriceLE) +ON_EVENT(ON_END_EDIT, m_EdtMarginLevelGE, OnEndEditMarginLevelGE) +ON_EVENT(ON_END_EDIT, m_EdtMarginLevelLE, OnEndEditMarginLevelLE) +ON_EVENT(ON_END_EDIT, m_EdtSpreadGE, OnEndEditSpreadGE) +ON_EVENT(ON_END_EDIT, m_EdtSpreadLE, OnEndEditSpreadLE) +ON_EVENT(ON_END_EDIT, m_EdtDailyProfitLossUnitsGE, OnEndEditDailyProfitLossUnitsGE) +ON_EVENT(ON_END_EDIT, m_EdtDailyProfitLossUnitsLE, OnEndEditDailyProfitLossUnitsLE) +ON_EVENT(ON_END_EDIT, m_EdtDailyProfitLossPointsGE, OnEndEditDailyProfitLossPointsGE) +ON_EVENT(ON_END_EDIT, m_EdtDailyProfitLossPointsLE, OnEndEditDailyProfitLossPointsLE) +ON_EVENT(ON_END_EDIT, m_EdtDailyProfitLossPercGE, OnEndEditDailyProfitLossPercGE) +ON_EVENT(ON_END_EDIT, m_EdtDailyProfitLossPercLE, OnEndEditDailyProfitLossPercLE) ON_EVENT(ON_END_EDIT, m_EdtClosePercentage, OnEndEditClosePercentage) ON_EVENT(ON_CLICK, m_BtnEmergency, OnClickBtnEmergency) EVENT_MAP_END(CAppDialog) @@ -372,11 +423,11 @@ CAccountProtector::CAccountProtector() //+--------+ bool CAccountProtector::ButtonCreate(CButton &Btn, int X1, int Y1, int X2, int Y2, string Name, string Text) { - if (!Btn.Create(m_chart_id, m_name + Name, m_subwin, X1, Y1, X2, Y2)) return(false); - if (!Add(Btn)) return(false); - if (!Btn.Text(Text)) return(false); + if (!Btn.Create(m_chart_id, m_name + Name, m_subwin, X1, Y1, X2, Y2)) return false; + if (!Add(Btn)) return false; + if (!Btn.Text(Text)) return false; - return(true); + return true; } //+----------+ @@ -384,11 +435,11 @@ bool CAccountProtector::ButtonCreate(CButton &Btn, int X1, int Y1, int X2, int Y //+----------+ bool CAccountProtector::CheckBoxCreate(CCheckBox &Chk, int X1, int Y1, int X2, int Y2, string Name, string Text) { - if (!Chk.Create(m_chart_id, m_name + Name, m_subwin, X1, Y1, X2, Y2)) return(false); - if (!Add(Chk)) return(false); - if (!Chk.Text(Text)) return(false); + if (!Chk.Create(m_chart_id, m_name + Name, m_subwin, X1, Y1, X2, Y2)) return false; + if (!Add(Chk)) return false; + if (!Chk.Text(Text)) return false; - return(true); + return true; } //+------+ @@ -396,11 +447,11 @@ bool CAccountProtector::CheckBoxCreate(CCheckBox &Chk, int X1, int Y1, int X2, i //+------+ bool CAccountProtector::EditCreate(CEdit &Edt, int X1, int Y1, int X2, int Y2, string Name, string Text) { - if (!Edt.Create(m_chart_id, m_name + Name, m_subwin, X1, Y1, X2, Y2)) return(false); - if (!Add(Edt)) return(false); - if (!Edt.Text(Text)) return(false); + if (!Edt.Create(m_chart_id, m_name + Name, m_subwin, X1, Y1, X2, Y2)) return false; + if (!Add(Edt)) return false; + if (!Edt.Text(Text)) return false; - return(true); + return true; } //+-------+ @@ -408,11 +459,11 @@ bool CAccountProtector::EditCreate(CEdit &Edt, int X1, int Y1, int X2, int Y2, s //+-------+ bool CAccountProtector::LabelCreate(CLabel &Lbl, int X1, int Y1, int X2, int Y2, string Name, string Text) { - if (!Lbl.Create(m_chart_id, m_name + Name, m_subwin, X1, Y1, X2, Y2)) return(false); - if (!Add(Lbl)) return(false); - if (!Lbl.Text(Text)) return(false); + if (!Lbl.Create(m_chart_id, m_name + Name, m_subwin, X1, Y1, X2, Y2)) return false; + if (!Add(Lbl)) return false; + if (!Lbl.Text(Text)) return false; - return(true); + return true; } //+------------+ @@ -420,16 +471,16 @@ bool CAccountProtector::LabelCreate(CLabel &Lbl, int X1, int Y1, int X2, int Y2, //+------------+ bool CAccountProtector::RadioGroupCreate(CRadioGroup &Rgp, int X1, int Y1, int X2, int Y2, string Name, const string &Text[]) { - if (!Rgp.Create(m_chart_id, m_name + Name, m_subwin, X1, Y1, X2, Y2)) return(false); - if (!Add(Rgp)) return(false); + if (!Rgp.Create(m_chart_id, m_name + Name, m_subwin, X1, Y1, X2, Y2)) return false; + if (!Add(Rgp)) return false; int size = ArraySize(Text); for (int i = 0; i < size; i++) { - if (!Rgp.AddItem(Text[i], i)) return(false); + if (!Rgp.AddItem(Text[i], i)) return false; } - return(true); + return true; } //+----------+ @@ -437,17 +488,17 @@ bool CAccountProtector::RadioGroupCreate(CRadioGroup &Rgp, int X1, int Y1, int X //+----------+ bool CAccountProtector::ComboBoxCreate(CComboBox &Cbx, int X1, int Y1, int X2, int Y2, string Name, const string &Text[]) { - if (!Cbx.Create(m_chart_id, m_name + Name, m_subwin, X1, Y1, X2, Y2)) return(false); - if (!Add(Cbx)) return(false); + if (!Cbx.Create(m_chart_id, m_name + Name, m_subwin, X1, Y1, X2, Y2)) return false; + if (!Add(Cbx)) return false; int size = ArraySize(Text); Cbx.ListViewItems(size); for (int i = 0; i < size; i++) { - if (!Cbx.AddItem(Text[i], i)) return(false); + if (!Cbx.AddItem(Text[i], i)) return false; } - return(true); + return true; } //+-----------------------+ @@ -461,9 +512,9 @@ bool CAccountProtector::Create(const long chart, const string name, const int su int x2 = x1 + (int)MathRound(390 * m_DPIScale); int y2 = y1 + (int)MathRound(300 * m_DPIScale); - if (!CAppDialog::Create(chart, name, subwin, x1, y1, x2, y2)) return(false); - if (!CreateObjects()) return(false); - return(true); + if (!CAppDialog::Create(chart, name, subwin, x1, y1, x2, y2)) return false; + if (!CreateObjects()) return false; + return true; } //+------------------------------------------------------------------+ @@ -518,291 +569,370 @@ bool CAccountProtector::CreateObjects() // Start int y = row_start; - if (!LabelCreate(m_LblStatus, first_column_start, y, first_column_start + normal_label_width, y + element_height, "m_LblStatus", "Status:")) return(false); + if (!LabelCreate(m_LblStatus, first_column_start, y, first_column_start + normal_label_width, y + element_height, "m_LblStatus", "Status:")) return false; // Tab Buttons y += element_height + v_spacing; - if (!ButtonCreate(m_BtnTabMain, first_column_start, y, first_column_start + tab_button_width, y + element_height, "m_BtnTabMain", "Main")) return(false); - if (!ButtonCreate(m_BtnTabFilters, first_column_start + tab_button_width + tab_button_spacing, y, first_column_start + tab_button_width * 2 + tab_button_spacing, y + element_height, "m_BtnTabFilters", "Filters")) return(false); - if (!ButtonCreate(m_BtnTabConditions, first_column_start + tab_button_width * 2 + tab_button_spacing * 2, y, first_column_start + tab_button_width * 3 + tab_button_spacing * 2, y + element_height, "m_BtnTabConditions", "Conditions")) return(false); - if (!ButtonCreate(m_BtnTabActions, first_column_start + tab_button_width * 3 + tab_button_spacing * 3, y, first_column_start + tab_button_width * 4 + tab_button_spacing * 3, y + element_height, "m_BtnTabActions", "Actions")) return(false); + if (!ButtonCreate(m_BtnTabMain, first_column_start, y, first_column_start + tab_button_width, y + element_height, "m_BtnTabMain", "Main")) return false; + if (!ButtonCreate(m_BtnTabFilters, first_column_start + tab_button_width + tab_button_spacing, y, first_column_start + tab_button_width * 2 + tab_button_spacing, y + element_height, "m_BtnTabFilters", "Filters")) return false; + if (!ButtonCreate(m_BtnTabConditions, first_column_start + tab_button_width * 2 + tab_button_spacing * 2, y, first_column_start + tab_button_width * 3 + tab_button_spacing * 2, y + element_height, "m_BtnTabConditions", "Conditions")) return false; + if (!ButtonCreate(m_BtnTabActions, first_column_start + tab_button_width * 3 + tab_button_spacing * 3, y, first_column_start + tab_button_width * 4 + tab_button_spacing * 3, y + element_height, "m_BtnTabActions", "Actions")) return false; // Main Tab Objects y += element_height + 3 * v_spacing; - if (!LabelCreate(m_LblSpread, first_column_start, y, first_column_start + normal_label_width, y + element_height, "m_LblSpread", "Spread: " + DoubleToString((double)SymbolInfoInteger(Symbol(), SYMBOL_SPREAD) * SymbolInfoDouble(Symbol(), SYMBOL_POINT), (int)SymbolInfoInteger(Symbol(), SYMBOL_DIGITS)))) return(false); - if (!CheckBoxCreate(m_ChkCountCommSwaps, second_column_main_start, y, panel_farther_end, y + element_height, "m_ChkCountCommSwaps", "Count commission/swaps")) return(false); + if (!LabelCreate(m_LblSpread, first_column_start, y, first_column_start + normal_label_width, y + element_height, "m_LblSpread", "Spread: " + DoubleToString((double)SymbolInfoInteger(Symbol(), SYMBOL_SPREAD) * SymbolInfoDouble(Symbol(), SYMBOL_POINT), (int)SymbolInfoInteger(Symbol(), SYMBOL_DIGITS)))) return false; + if (!CheckBoxCreate(m_ChkCountCommSwaps, second_column_main_start, y, panel_farther_end, y + element_height, "m_ChkCountCommSwaps", "Count commission/swaps")) return false; y += element_height + v_spacing; - if (!CheckBoxCreate(m_ChkUseTimer, first_column_start, y, second_column_magic_start, y + element_height, "m_ChkUseTimer", "Use timer:")) return(false); - if (!EditCreate(m_EdtTimer, second_column_magic_start, y, second_column_magic_start + timer_width, y + element_height, "m_EdtTimer", "00:00")) return(false); + if (!CheckBoxCreate(m_ChkUseTimer, first_column_start, y, second_column_magic_start, y + element_height, "m_ChkUseTimer", "Use timer:")) return false; + if (!EditCreate(m_EdtTimer, second_column_magic_start, y, second_column_magic_start + timer_width, y + element_height, "m_EdtTimer", "00:00")) return false; string m_RgpTimeType_Text[2] = {"Server time", "Local time"}; - if (!RadioGroupCreate(m_RgpTimeType, second_column_main_start, y, second_column_main_start + timer_radio_width, y + element_height * 2, "m_RgpTimeType", m_RgpTimeType_Text)) return(false); - if (!LabelCreate(m_LblTimeLeft, timer_label_start, y, timer_label_start + timer_width, y + element_height, "m_LblTimeLeft", "Time left:")) return(false); + if (!RadioGroupCreate(m_RgpTimeType, second_column_main_start, y, second_column_main_start + timer_radio_width, y + element_height * 2, "m_RgpTimeType", m_RgpTimeType_Text)) return false; + if (!LabelCreate(m_LblTimeLeft, timer_label_start, y, timer_label_start + timer_width, y + element_height, "m_LblTimeLeft", "Time left:")) return false; y += element_height + v_spacing; - if (!LabelCreate(m_LblDayOfWeek, first_column_start, y, first_column_start + timer_width, y + element_height, "m_LblDayOfWeek", "Day: ")) return(false); - if (!ButtonCreate(m_BtnDayOfWeek, first_column_start + timer_width, y, second_column_magic_start + timer_width, y + element_height, "m_BtnDayOfWeek", "Any")) return(false); + if (!LabelCreate(m_LblDayOfWeek, first_column_start, y, first_column_start + timer_width, y + element_height, "m_LblDayOfWeek", "Day: ")) return false; + if (!ButtonCreate(m_BtnDayOfWeek, first_column_start + timer_width, y, second_column_magic_start + timer_width, y + element_height, "m_BtnDayOfWeek", "Any")) return false; y += element_height + v_spacing; - if (!CheckBoxCreate(m_ChkTrailingStart, first_column_start, y, panel_end, y + element_height, "m_ChkTrailingStart", "Profit value (pips) to start trailing SL:")) return(false); - if (!EditCreate(m_EdtTrailingStart, last_input_start, y, last_input_end, y + element_height, "m_EdtTrailingStart", "0")) return(false); + if (!CheckBoxCreate(m_ChkTrailingStart, first_column_start, y, panel_end, y + element_height, "m_ChkTrailingStart", "Profit value (points) to start trailing SL:")) return false; + if (!EditCreate(m_EdtTrailingStart, last_input_start, y, last_input_end, y + element_height, "m_EdtTrailingStart", "0")) return false; y += element_height + v_spacing; - if (!CheckBoxCreate(m_ChkTrailingStep, first_column_start, y, panel_end, y + element_height, "m_ChkTrailingStep", "Trailing SL value (pips):")) return(false); - if (!EditCreate(m_EdtTrailingStep, last_input_start, y, last_input_end, y + element_height, "m_EdtTrailingStep", "0")) return(false); + if (!CheckBoxCreate(m_ChkTrailingStep, first_column_start, y, panel_end, y + element_height, "m_ChkTrailingStep", "Trailing SL value (points):")) return false; + if (!EditCreate(m_EdtTrailingStep, last_input_start, y, last_input_end, y + element_height, "m_EdtTrailingStep", "0")) return false; y += element_height + v_spacing; - if (!CheckBoxCreate(m_ChkBreakEven, first_column_start, y, panel_end, y + element_height, "m_ChkBreakEven", "Profit value (pips) to move SL to breakeven:")) return(false); - if (!EditCreate(m_EdtBreakEven, last_input_start, y, last_input_end, y + element_height, "m_EdtBreakEven", "0")) return(false); + if (!CheckBoxCreate(m_ChkBreakEven, first_column_start, y, panel_end, y + element_height, "m_ChkBreakEven", "Profit value (points) to set SL to breakeven:")) return false; + if (!EditCreate(m_EdtBreakEven, last_input_start, y, last_input_end, y + element_height, "m_EdtBreakEven", "0")) return false; y += element_height + v_spacing; - if (!CheckBoxCreate(m_ChkBreakEvenExtra, first_column_start, y, panel_end, y + element_height, "m_ChkBreakEvenExtra", "Breakeven extra profit value (pips):")) return(false); - if (!EditCreate(m_EdtBreakEvenExtra, last_input_start, y, last_input_end, y + element_height, "m_EdtBreakEvenExtra", "0")) return(false); + if (!CheckBoxCreate(m_ChkBreakEvenExtra, first_column_start, y, panel_end, y + element_height, "m_ChkBreakEvenExtra", "Breakeven extra profit value (points):")) return false; + if (!EditCreate(m_EdtBreakEvenExtra, last_input_start, y, last_input_end, y + element_height, "m_EdtBreakEvenExtra", "0")) return false; y += element_height + v_spacing; - if (!CheckBoxCreate(m_ChkEquityTrailingStop, first_column_start, y, panel_end, y + element_height, "m_ChkEquityTrailingStop", "Equity trailing stop (hidden), USD:")) return(false); - if (!EditCreate(m_EdtEquityTrailingStop, last_input_start, y, last_input_end, y + element_height, "m_EdtEquityTrailingStop", "0")) return(false); + if (!CheckBoxCreate(m_ChkEquityTrailingStop, first_column_start, y, panel_end, y + element_height, "m_ChkEquityTrailingStop", "Equity trailing stop (hidden), USD:")) return false; + if (!EditCreate(m_EdtEquityTrailingStop, last_input_start, y, last_input_end, y + element_height, "m_EdtEquityTrailingStop", "0")) return false; y += element_height + v_spacing; - if (!LabelCreate(m_LblCurrentEquityStopLoss, first_column_start, y, first_column_start + normal_label_width, y + element_height, "m_LblCurrentEquityStopLoss", "Current equity stop-loss, USD: ")) return(false); - if (!ButtonCreate(m_BtnResetEquityStopLoss, last_input_start, y, last_input_end, y + element_height, "m_BtnResetEquityStopLoss", "Reset SL")) return(false); + if (!LabelCreate(m_LblCurrentEquityStopLoss, first_column_start, y, first_column_start + normal_label_width, y + element_height, "m_LblCurrentEquityStopLoss", "Current equity stop-loss, USD: ")) return false; + if (!ButtonCreate(m_BtnResetEquityStopLoss, last_input_start, y, last_input_end, y + element_height, "m_BtnResetEquityStopLoss", "Reset SL")) return false; y += element_height + v_spacing; - if (!LabelCreate(m_LblSnapEquity, first_column_start, y, first_column_start + normal_label_width, y + element_height, "m_LblSnapEquity", "Snapshot of equity: ")) return(false); + if (!LabelCreate(m_LblSnapEquity, first_column_start, y, first_column_start + normal_label_width, y + element_height, "m_LblSnapEquity", "Snapshot of equity: ")) return false; y += element_height + v_spacing; - if (!LabelCreate(m_LblSnapMargin, first_column_start, y, first_column_start + normal_label_width, y + element_height, "m_LblSnapMargin", "Snapshot of free margin: ")) return(false); + if (!LabelCreate(m_LblSnapMargin, first_column_start, y, first_column_start + normal_label_width, y + element_height, "m_LblSnapMargin", "Snapshot of free margin: ")) return false; y += element_height + v_spacing; - if (!ButtonCreate(m_BtnNewSnapEquity, first_column_start, y, first_column_start + snap_button_width, y + element_height, "m_BtnNewSnapEquity", "New snapshot of equity")) return(false); - if (!ButtonCreate(m_BtnNewSnapMargin, first_column_start + snap_button_width + h_spacing, y, panel_farther_end, y + element_height, "m_BtnNewSnapMargin", "New snapshot of free margin")) return(false); + if (!ButtonCreate(m_BtnNewSnapEquity, first_column_start, y, first_column_start + snap_button_width, y + element_height, "m_BtnNewSnapEquity", "New snapshot of equity")) return false; + if (!ButtonCreate(m_BtnNewSnapMargin, first_column_start + snap_button_width + h_spacing, y, panel_farther_end, y + element_height, "m_BtnNewSnapMargin", "New snapshot of free margin")) return false; if (EnableEmergencyButton == Yes) { y += element_height + 3 * v_spacing; - if (!ButtonCreate(m_BtnEmergency, first_column_start, y, panel_farther_end, y + (int)(element_height * 2.5), "m_BtnEmergency", "Emergency button")) return(false); + if (!ButtonCreate(m_BtnEmergency, first_column_start, y, panel_farther_end, y + (int)(element_height * 2.5), "m_BtnEmergency", "Emergency button")) return false; m_BtnEmergency.ColorBackground(clrRed); m_BtnEmergency.Color(clrWhite); y += (int)(element_height * 2.5) + v_spacing; } else y += element_height + v_spacing; - if (!LabelCreate(m_LblURL, first_column_start, y, first_column_start + normal_label_width, y + element_height, "m_LblURL", "www.earnforex.com")) return(false); - if (!m_LblURL.FontSize(8)) return(false); - if (!m_LblURL.Color(C'0,115,66')) return(false); // Green + if (!LabelCreate(m_LblURL, first_column_start, y, first_column_start + normal_label_width, y + element_height, "m_LblURL", "www.earnforex.com")) return false; + if (!m_LblURL.FontSize(8)) return false; + if (!m_LblURL.Color(C'0,115,66')) return false; // Green m_LblURL.Show(); // Filters Tab Objects y = row_start + 2 * element_height + 4 * v_spacing; - if (!LabelCreate(m_LblMagics, first_column_start, y, first_column_start + normal_label_width, y + element_height, "m_LblMagics", "Magic numbers:")) return(false); - if (!EditCreate(m_EdtMagics, second_column_magic_start, y, second_column_magic_end, y + element_height, "m_EdtMagics", "")) return(false); - if (!CheckBoxCreate(m_ChkExcludeMagics, third_column_magic_start, y, panel_farther_end, y + element_height, "m_ChkExcludeMagics", "Exclude")) return(false); + if (!LabelCreate(m_LblMagics, first_column_start, y, first_column_start + normal_label_width, y + element_height, "m_LblMagics", "Magic numbers:")) return false; + if (!EditCreate(m_EdtMagics, second_column_magic_start, y, second_column_magic_end, y + element_height, "m_EdtMagics", "")) return false; + if (!CheckBoxCreate(m_ChkExcludeMagics, third_column_magic_start, y, panel_farther_end, y + element_height, "m_ChkExcludeMagics", "Exclude")) return false; y += element_height + v_spacing; - string m_RgpInstrumentFilter_Text[3] = {"Do not filter by trading instrument", "Use only with current trading instrument", "Exclude current trading instrument"}; - if (!RadioGroupCreate(m_RgpInstrumentFilter, first_column_start, y, second_column_magic_end, y + element_height * 3, "m_RgpInstrumentFilter", m_RgpInstrumentFilter_Text)) return(false); - y += element_height * 3 + v_spacing; - if (!LabelCreate(m_LblOrderCommentary, first_column_start, y, first_column_start + normal_label_width, y + element_height, "m_LblOrderCommentary", "Order commentary")) return(false); + string m_RgpInstrumentFilter_Text[5] = {"Do not filter by trading instrument", "Use only with current trading instrument", "Exclude current trading instrument", "Include listed trading instruments only", "Exclude listed trading instruments"}; + if (!RadioGroupCreate(m_RgpInstrumentFilter, first_column_start, y, second_column_magic_end, y + element_height * 5, "m_RgpInstrumentFilter", m_RgpInstrumentFilter_Text)) return false; + y += element_height * 5 + v_spacing; + if (!LabelCreate(m_LblInstruments, first_column_start, y, panel_farther_end, y + element_height, "m_LblInstruments", "List of included/excluded trading instruments:")) return false; + y += element_height + v_spacing; + if (!EditCreate(m_EdtInstruments, first_column_start, y, panel_farther_end, y + element_height, "m_EdtInstruments", "")) return false; + y += element_height + v_spacing; + if (!LabelCreate(m_LblOrderCommentary, first_column_start, y, first_column_start + normal_label_width, y + element_height, "m_LblOrderCommentary", "Order commentary")) return false; string m_CbxOrderCommentaryCondition_Text[4] = {"contains", "equals", "excludes", "not equal"}; - if (!ComboBoxCreate(m_CbxOrderCommentaryCondition, second_column_start, y, second_column_start + narrow_edit_width, y + element_height, "m_CbxOrderCommentaryCondition", m_CbxOrderCommentaryCondition_Text)) return(false); - if (!EditCreate(m_EdtOrderCommentary, order_commentary_start, y, panel_farther_end, y + element_height, "m_EdtOrderCommentary", "")) return(false); + if (!ComboBoxCreate(m_CbxOrderCommentaryCondition, second_column_start, y, second_column_start + narrow_edit_width, y + element_height, "m_CbxOrderCommentaryCondition", m_CbxOrderCommentaryCondition_Text)) return false; + if (!EditCreate(m_EdtOrderCommentary, order_commentary_start, y, panel_farther_end, y + element_height, "m_EdtOrderCommentary", "")) return false; + y += element_height + v_spacing; + if (!CheckBoxCreate(m_ChkIgnoreLossTrades, first_column_start, y, second_column_start + narrow_edit_width, y + element_height, "m_ChkIgnoreLossTrades", "Ignore losing trades")) return false; + if (!CheckBoxCreate(m_ChkIgnoreProfitTrades, order_commentary_start, y, panel_farther_end, y + element_height, "m_ChkIgnoreProfitTrades", "Ignore profitable trades")) return false; y += element_height + v_spacing; - if (!ButtonCreate(m_BtnResetFilters, first_column_start, y, first_column_start + normal_label_width, y + element_height, "m_BtnResetFilters", "Reset filters")) return(false); + if (!ButtonCreate(m_BtnResetFilters, first_column_start, y, first_column_start + normal_label_width, y + element_height, "m_BtnResetFilters", "Reset filters")) return false; // Conditions Tab Objects y = row_start + 2 * element_height + 2 * v_spacing; if (!DisableFloatLossRisePerc) { - if (!CheckBoxCreate(m_ChkLossPerBalance, first_column_start, y, panel_end, y + element_height, "m_ChkLossPerBalance", "Floating loss rises to % of balance:")) return(false); - if (!EditCreate(m_EdtLossPerBalance, last_input_start, y, last_input_end, y + element_height, "m_EdtLossPerBalance", "0")) return(false); + if (!CheckBoxCreate(m_ChkLossPerBalance, first_column_start, y, panel_end, y + element_height, "m_ChkLossPerBalance", "Floating loss rises to % of balance:")) return false; + if (!EditCreate(m_EdtLossPerBalance, last_input_start, y, last_input_end, y + element_height, "m_EdtLossPerBalance", "0")) return false; y += element_height + v_spacing; } if (!DisableFloatLossFallPerc) { - if (!CheckBoxCreate(m_ChkLossPerBalanceReverse, first_column_start, y, panel_end, y + element_height, "m_ChkLossPerBalanceReverse", "Floating loss falls to % of balance:")) return(false); - if (!EditCreate(m_EdtLossPerBalanceReverse, last_input_start, y, last_input_end, y + element_height, "m_EdtLossPerBalanceReverse", "0")) return(false); + if (!CheckBoxCreate(m_ChkLossPerBalanceReverse, first_column_start, y, panel_end, y + element_height, "m_ChkLossPerBalanceReverse", "Floating loss falls to % of balance:")) return false; + if (!EditCreate(m_EdtLossPerBalanceReverse, last_input_start, y, last_input_end, y + element_height, "m_EdtLossPerBalanceReverse", "0")) return false; y += element_height + v_spacing; } if (!DisableFloatLossRiseCurr) { - if (!CheckBoxCreate(m_ChkLossQuanUnits, first_column_start, y, panel_end, y + element_height, "m_ChkLossQuanUnits", "Floating loss rises to currency units:")) return(false); - if (!EditCreate(m_EdtLossQuanUnits, last_big_input_start, y, last_input_end, y + element_height, "m_EdtLossQuanUnits", "0")) return(false); + if (!CheckBoxCreate(m_ChkLossQuanUnits, first_column_start, y, panel_end, y + element_height, "m_ChkLossQuanUnits", "Floating loss rises to currency units:")) return false; + if (!EditCreate(m_EdtLossQuanUnits, last_big_input_start, y, last_input_end, y + element_height, "m_EdtLossQuanUnits", "0")) return false; y += element_height + v_spacing; } if (!DisableFloatLossFallCurr) { - if (!CheckBoxCreate(m_ChkLossQuanUnitsReverse, first_column_start, y, panel_end, y + element_height, "m_ChkLossQuanUnitsReverse", "Floating loss falls to currency units:")) return(false); - if (!EditCreate(m_EdtLossQuanUnitsReverse, last_big_input_start, y, last_input_end, y + element_height, "m_EdtLossQuanUnitsReverse", "0")) return(false); + if (!CheckBoxCreate(m_ChkLossQuanUnitsReverse, first_column_start, y, panel_end, y + element_height, "m_ChkLossQuanUnitsReverse", "Floating loss falls to currency units:")) return false; + if (!EditCreate(m_EdtLossQuanUnitsReverse, last_big_input_start, y, last_input_end, y + element_height, "m_EdtLossQuanUnitsReverse", "0")) return false; y += element_height + v_spacing; } - if (!DisableFloatLossRisePips) + if (!DisableFloatLossRisePoints) { - if (!CheckBoxCreate(m_ChkLossPips, first_column_start, y, panel_end, y + element_height, "m_ChkLossPips", "Floating loss rises to pips:")) return(false); - if (!EditCreate(m_EdtLossPips, last_input_start, y, last_input_end, y + element_height, "m_EdtLossPips", "0")) return(false); + if (!CheckBoxCreate(m_ChkLossPoints, first_column_start, y, panel_end, y + element_height, "m_ChkLossPoints", "Floating loss rises to points:")) return false; + if (!EditCreate(m_EdtLossPoints, last_input_start, y, last_input_end, y + element_height, "m_EdtLossPoints", "0")) return false; y += element_height + v_spacing; } - if (!DisableFloatLossFallPips) + if (!DisableFloatLossFallPoints) { - if (!CheckBoxCreate(m_ChkLossPipsReverse, first_column_start, y, panel_end, y + element_height, "m_ChkLossPipsReverse", "Floating loss falls to pips:")) return(false); - if (!EditCreate(m_EdtLossPipsReverse, last_input_start, y, last_input_end, y + element_height, "m_EdtLossPipsReverse", "0")) return(false); + if (!CheckBoxCreate(m_ChkLossPointsReverse, first_column_start, y, panel_end, y + element_height, "m_ChkLossPointsReverse", "Floating loss falls to points:")) return false; + if (!EditCreate(m_EdtLossPointsReverse, last_input_start, y, last_input_end, y + element_height, "m_EdtLossPointsReverse", "0")) return false; y += element_height + v_spacing; } if (!DisableFloatProfitRisePerc) { - if (!CheckBoxCreate(m_ChkProfPerBalance, first_column_start, y, panel_end, y + element_height, "m_ChkProfPerBalance", "Floating profit rises % of balance:")) return(false); - if (!EditCreate(m_EdtProfPerBalance, last_input_start, y, last_input_end, y + element_height, "m_EdtProfPerBalance", "0")) return(false); + if (!CheckBoxCreate(m_ChkProfPerBalance, first_column_start, y, panel_end, y + element_height, "m_ChkProfPerBalance", "Floating profit rises % of balance:")) return false; + if (!EditCreate(m_EdtProfPerBalance, last_input_start, y, last_input_end, y + element_height, "m_EdtProfPerBalance", "0")) return false; y += element_height + v_spacing; } if (!DisableFloatProfitFallPerc) { - if (!CheckBoxCreate(m_ChkProfPerBalanceReverse, first_column_start, y, panel_end, y + element_height, "m_ChkProfPerBalanceReverse", "Floating profit falls % of balance:")) return(false); - if (!EditCreate(m_EdtProfPerBalanceReverse, last_input_start, y, last_input_end, y + element_height, "m_EdtProfPerBalanceReverse", "0")) return(false); + if (!CheckBoxCreate(m_ChkProfPerBalanceReverse, first_column_start, y, panel_end, y + element_height, "m_ChkProfPerBalanceReverse", "Floating profit falls % of balance:")) return false; + if (!EditCreate(m_EdtProfPerBalanceReverse, last_input_start, y, last_input_end, y + element_height, "m_EdtProfPerBalanceReverse", "0")) return false; y += element_height + v_spacing; } if (!DisableFloatProfitRiseCurr) { - if (!CheckBoxCreate(m_ChkProfQuanUnits, first_column_start, y, panel_end, y + element_height, "m_ChkProfQuanUnits", "Floating profit rises to currency units:")) return(false); - if (!EditCreate(m_EdtProfQuanUnits, last_big_input_start, y, last_input_end, y + element_height, "m_EdtProfQuanUnits", "0")) return(false); + if (!CheckBoxCreate(m_ChkProfQuanUnits, first_column_start, y, panel_end, y + element_height, "m_ChkProfQuanUnits", "Floating profit rises to currency units:")) return false; + if (!EditCreate(m_EdtProfQuanUnits, last_big_input_start, y, last_input_end, y + element_height, "m_EdtProfQuanUnits", "0")) return false; y += element_height + v_spacing; } if (!DisableFloatProfitFallCurr) { - if (!CheckBoxCreate(m_ChkProfQuanUnitsReverse, first_column_start, y, panel_end, y + element_height, "m_ChkProfQuanUnitsReverse", "Floating profit falls to currency units:")) return(false); - if (!EditCreate(m_EdtProfQuanUnitsReverse, last_big_input_start, y, last_input_end, y + element_height, "m_EdtProfQuanUnitsReverse", "0")) return(false); + if (!CheckBoxCreate(m_ChkProfQuanUnitsReverse, first_column_start, y, panel_end, y + element_height, "m_ChkProfQuanUnitsReverse", "Floating profit falls to currency units:")) return false; + if (!EditCreate(m_EdtProfQuanUnitsReverse, last_big_input_start, y, last_input_end, y + element_height, "m_EdtProfQuanUnitsReverse", "0")) return false; y += element_height + v_spacing; } - if (!DisableFloatProfitRisePips) + if (!DisableFloatProfitRisePoints) { - if (!CheckBoxCreate(m_ChkProfPips, first_column_start, y, panel_end, y + element_height, "m_ChkProfPips", "Floating profit rises to pips:")) return(false); - if (!EditCreate(m_EdtProfPips, last_input_start, y, last_input_end, y + element_height, "m_EdtProfPips", "0")) return(false); + if (!CheckBoxCreate(m_ChkProfPoints, first_column_start, y, panel_end, y + element_height, "m_ChkProfPoints", "Floating profit rises to points:")) return false; + if (!EditCreate(m_EdtProfPoints, last_input_start, y, last_input_end, y + element_height, "m_EdtProfPoints", "0")) return false; y += element_height + v_spacing; } - if (!DisableFloatProfitFallPips) + if (!DisableFloatProfitFallPoints) { - if (!CheckBoxCreate(m_ChkProfPipsReverse, first_column_start, y, panel_end, y + element_height, "m_ChkProfPipsReverse", "Floating profit falls to pips:")) return(false); - if (!EditCreate(m_EdtProfPipsReverse, last_input_start, y, last_input_end, y + element_height, "m_EdtProfPipsReverse", "0")) return(false); + if (!CheckBoxCreate(m_ChkProfPointsReverse, first_column_start, y, panel_end, y + element_height, "m_ChkProfPointsReverse", "Floating profit falls to points:")) return false; + if (!EditCreate(m_EdtProfPointsReverse, last_input_start, y, last_input_end, y + element_height, "m_EdtProfPointsReverse", "0")) return false; y += element_height + v_spacing; } - if (!CheckBoxCreate(m_ChkEquityLessUnits, first_column_start, y, panel_end, y + element_height, "m_ChkEquityLessUnits", "Equity <= currency units:")) return(false); - if (!EditCreate(m_EdtEquityLessUnits, last_big_input_start, y, last_input_end, y + element_height, "m_EdtEquityLessUnits", "0")) return(false); + if (!CheckBoxCreate(m_ChkEquityLessUnits, first_column_start, y, panel_end, y + element_height, "m_ChkEquityLessUnits", "Equity <= currency units:")) return false; + if (!EditCreate(m_EdtEquityLessUnits, last_big_input_start, y, last_input_end, y + element_height, "m_EdtEquityLessUnits", "0")) return false; y += element_height + v_spacing; - if (!CheckBoxCreate(m_ChkEquityGrUnits, first_column_start, y, panel_end, y + element_height, "m_ChkEquityGrUnits", "Equity >= currency units:")) return(false); - if (!EditCreate(m_EdtEquityGrUnits, last_big_input_start, y, last_input_end, y + element_height, "m_EdtEquityGrUnits", "0")) return(false); + if (!CheckBoxCreate(m_ChkEquityGrUnits, first_column_start, y, panel_end, y + element_height, "m_ChkEquityGrUnits", "Equity >= currency units:")) return false; + if (!EditCreate(m_EdtEquityGrUnits, last_big_input_start, y, last_input_end, y + element_height, "m_EdtEquityGrUnits", "0")) return false; y += element_height + v_spacing; - if (!CheckBoxCreate(m_ChkEquityLessPerSnap, first_column_start, y, panel_end, y + element_height, "m_ChkEquityLessPerSnap", "Equity <= % of snapshot:")) return(false); - if (!EditCreate(m_EdtEquityLessPerSnap, last_input_start, y, last_input_end, y + element_height, "m_EdtEquityLessPerSnap", "0")) return(false); + if (!CheckBoxCreate(m_ChkEquityLessPerSnap, first_column_start, y, panel_end, y + element_height, "m_ChkEquityLessPerSnap", "Equity <= % of snapshot:")) return false; + if (!EditCreate(m_EdtEquityLessPerSnap, last_input_start, y, last_input_end, y + element_height, "m_EdtEquityLessPerSnap", "0")) return false; y += element_height + v_spacing; - if (!CheckBoxCreate(m_ChkEquityGrPerSnap, first_column_start, y, panel_end, y + element_height, "m_ChkEquityGrPerSnap", "Equity >= % of snapshot:")) return(false); - if (!EditCreate(m_EdtEquityGrPerSnap, last_input_start, y, last_input_end, y + element_height, "m_EdtEquityGrPerSnap", "0")) return(false); + if (!CheckBoxCreate(m_ChkEquityGrPerSnap, first_column_start, y, panel_end, y + element_height, "m_ChkEquityGrPerSnap", "Equity >= % of snapshot:")) return false; + if (!EditCreate(m_EdtEquityGrPerSnap, last_input_start, y, last_input_end, y + element_height, "m_EdtEquityGrPerSnap", "0")) return false; y += element_height + v_spacing; if (!DisableEquityMinusSnapshot) { - if (!CheckBoxCreate(m_ChkEquityMinusSnapshot, first_column_start, y, panel_end, y + element_height, "m_ChkEquityMinusSnapshot", "Equity - snapshot >= currency units:")) return(false); - if (!EditCreate(m_EdtEquityMinusSnapshot, last_big_input_start, y, last_input_end, y + element_height, "m_EdtEquityMinusSnapshot", "0")) return(false); + if (!CheckBoxCreate(m_ChkEquityMinusSnapshot, first_column_start, y, panel_end, y + element_height, "m_ChkEquityMinusSnapshot", "Equity - snapshot >= currency units:")) return false; + if (!EditCreate(m_EdtEquityMinusSnapshot, last_big_input_start, y, last_input_end, y + element_height, "m_EdtEquityMinusSnapshot", "0")) return false; y += element_height + v_spacing; } if (!DisableSnapshotMinusEquity) { - if (!CheckBoxCreate(m_ChkSnapshotMinusEquity, first_column_start, y, panel_end, y + element_height, "m_ChkSnapshotMinusEquity", "Snapshot - Equity >= currency units:")) return(false); - if (!EditCreate(m_EdtSnapshotMinusEquity, last_big_input_start, y, last_input_end, y + element_height, "m_EdtSnapshotMinusEquity", "0")) return(false); + if (!CheckBoxCreate(m_ChkSnapshotMinusEquity, first_column_start, y, panel_end, y + element_height, "m_ChkSnapshotMinusEquity", "Snapshot - Equity >= currency units:")) return false; + if (!EditCreate(m_EdtSnapshotMinusEquity, last_big_input_start, y, last_input_end, y + element_height, "m_EdtSnapshotMinusEquity", "0")) return false; y += element_height + v_spacing; } - if (!CheckBoxCreate(m_ChkMarginLessUnits, first_column_start, y, panel_end, y + element_height, "m_ChkMarginLessUnits", "Free margin <= currency units:")) return(false); - if (!EditCreate(m_EdtMarginLessUnits, last_big_input_start, y, last_input_end, y + element_height, "m_EdtMarginLessUnits", "0")) return(false); + if (!CheckBoxCreate(m_ChkMarginLessUnits, first_column_start, y, panel_end, y + element_height, "m_ChkMarginLessUnits", "Free margin <= currency units:")) return false; + if (!EditCreate(m_EdtMarginLessUnits, last_big_input_start, y, last_input_end, y + element_height, "m_EdtMarginLessUnits", "0")) return false; y += element_height + v_spacing; - if (!CheckBoxCreate(m_ChkMarginGrUnits, first_column_start, y, panel_end, y + element_height, "m_ChkMarginGrUnits", "Free margin >= currency units:")) return(false); - if (!EditCreate(m_EdtMarginGrUnits, last_big_input_start, y, last_input_end, y + element_height, "m_EdtMarginGrUnits", "0")) return(false); + if (!CheckBoxCreate(m_ChkMarginGrUnits, first_column_start, y, panel_end, y + element_height, "m_ChkMarginGrUnits", "Free margin >= currency units:")) return false; + if (!EditCreate(m_EdtMarginGrUnits, last_big_input_start, y, last_input_end, y + element_height, "m_EdtMarginGrUnits", "0")) return false; y += element_height + v_spacing; - if (!CheckBoxCreate(m_ChkMarginLessPerSnap, first_column_start, y, panel_end, y + element_height, "m_ChkMarginLessPerSnap", "Free margin <= % of snapshot:")) return(false); - if (!EditCreate(m_EdtMarginLessPerSnap, last_input_start, y, last_input_end, y + element_height, "m_EdtMarginLessPerSnap", "0")) return(false); + if (!CheckBoxCreate(m_ChkMarginLessPerSnap, first_column_start, y, panel_end, y + element_height, "m_ChkMarginLessPerSnap", "Free margin <= % of snapshot:")) return false; + if (!EditCreate(m_EdtMarginLessPerSnap, last_input_start, y, last_input_end, y + element_height, "m_EdtMarginLessPerSnap", "0")) return false; y += element_height + v_spacing; - if (!CheckBoxCreate(m_ChkMarginGrPerSnap, first_column_start, y, panel_end, y + element_height, "m_ChkMarginGrPerSnap", "Free margin >= % of snapshot:")) return(false); - if (!EditCreate(m_EdtMarginGrPerSnap, last_input_start, y, last_input_end, y + element_height, "m_EdtMarginGrPerSnap", "0")) return(false); + if (!CheckBoxCreate(m_ChkMarginGrPerSnap, first_column_start, y, panel_end, y + element_height, "m_ChkMarginGrPerSnap", "Free margin >= % of snapshot:")) return false; + if (!EditCreate(m_EdtMarginGrPerSnap, last_input_start, y, last_input_end, y + element_height, "m_EdtMarginGrPerSnap", "0")) return false; if (!DisableCurrentPriceGE) { - if (!CheckBoxCreate(m_ChkPriceGE, first_column_start, y, panel_end, y + element_height, "m_ChkPriceGE", "Current price >=")) return(false); - if (!EditCreate(m_EdtPriceGE, last_big_input_start, y, last_input_end, y + element_height, "m_EdtPriceGE", "0")) return(false); + if (!CheckBoxCreate(m_ChkPriceGE, first_column_start, y, panel_end, y + element_height, "m_ChkPriceGE", "Current price >=")) return false; + if (!EditCreate(m_EdtPriceGE, last_big_input_start, y, last_input_end, y + element_height, "m_EdtPriceGE", "0")) return false; y += element_height + v_spacing; } if (!DisableCurrentPriceLE) { - if (!CheckBoxCreate(m_ChkPriceLE, first_column_start, y, panel_end, y + element_height, "m_ChkPriceLE", "Current price <=")) return(false); - if (!EditCreate(m_EdtPriceLE, last_big_input_start, y, last_input_end, y + element_height, "m_EdtPriceLE", "0")) return(false); + if (!CheckBoxCreate(m_ChkPriceLE, first_column_start, y, panel_end, y + element_height, "m_ChkPriceLE", "Current price <=")) return false; + if (!EditCreate(m_EdtPriceLE, last_big_input_start, y, last_input_end, y + element_height, "m_EdtPriceLE", "0")) return false; + y += element_height + v_spacing; + } + + if (!DisableMarginLevelGE) + { + if (!CheckBoxCreate(m_ChkMarginLevelGE, first_column_start, y, panel_end, y + element_height, "m_ChkMarginLevelGE", "Margin level >= %")) return false; + if (!EditCreate(m_EdtMarginLevelGE, last_big_input_start, y, last_input_end, y + element_height, "m_EdtMarginLevelGE", "0")) return false; + y += element_height + v_spacing; + } + if (!DisableMarginLevelLE) + { + if (!CheckBoxCreate(m_ChkMarginLevelLE, first_column_start, y, panel_end, y + element_height, "m_ChkMarginLevelLE", "Margin level <= %")) return false; + if (!EditCreate(m_EdtMarginLevelLE, last_big_input_start, y, last_input_end, y + element_height, "m_EdtMarginLevelLE", "0")) return false; + y += element_height + v_spacing; + } + + if (!DisableSpreadGE) + { + if (!CheckBoxCreate(m_ChkSpreadGE, first_column_start, y, panel_end, y + element_height, "m_ChkSpreadGE", "Spread >= points")) return false; + if (!EditCreate(m_EdtSpreadGE, last_big_input_start, y, last_input_end, y + element_height, "m_EdtSpreadGE", "0")) return false; + y += element_height + v_spacing; + } + if (!DisableSpreadLE) + { + if (!CheckBoxCreate(m_ChkSpreadLE, first_column_start, y, panel_end, y + element_height, "m_ChkSpreadLE", "Spread <= points")) return false; + if (!EditCreate(m_EdtSpreadLE, last_big_input_start, y, last_input_end, y + element_height, "m_EdtSpreadLE", "0")) return false; + y += element_height + v_spacing; + } + + if (!DisableDailyProfitLossUnitsGE) + { + if (!CheckBoxCreate(m_ChkDailyProfitLossUnitsGE, first_column_start, y, panel_end, y + element_height, "m_ChkDailyProfitLossUnitsGE", "Daily profit/loss >= currency units")) return false; + if (!EditCreate(m_EdtDailyProfitLossUnitsGE, last_big_input_start, y, last_input_end, y + element_height, "m_EdtDailyProfitLossUnitsGE", "0")) return false; + y += element_height + v_spacing; + } + if (!DisableDailyProfitLossUnitsLE) + { + if (!CheckBoxCreate(m_ChkDailyProfitLossUnitsLE, first_column_start, y, panel_end, y + element_height, "m_ChkDailyProfitLossUnitsLE", "Daily profit/loss <= currency units")) return false; + if (!EditCreate(m_EdtDailyProfitLossUnitsLE, last_big_input_start, y, last_input_end, y + element_height, "m_EdtDailyProfitLossUnitsLE", "0")) return false; + y += element_height + v_spacing; + } + + if (!DisableDailyProfitLossPointsGE) + { + if (!CheckBoxCreate(m_ChkDailyProfitLossPointsGE, first_column_start, y, panel_end, y + element_height, "m_ChkDailyProfitLossPointsGE", "Daily profit/loss >= points")) return false; + if (!EditCreate(m_EdtDailyProfitLossPointsGE, last_big_input_start, y, last_input_end, y + element_height, "m_EdtDailyProfitLossPointsGE", "0")) return false; + y += element_height + v_spacing; + } + if (!DisableDailyProfitLossPointsLE) + { + if (!CheckBoxCreate(m_ChkDailyProfitLossPointsLE, first_column_start, y, panel_end, y + element_height, "m_ChkDailyProfitLossPointsLE", "Daily profit/loss <= points")) return false; + if (!EditCreate(m_EdtDailyProfitLossPointsLE, last_big_input_start, y, last_input_end, y + element_height, "m_EdtDailyProfitLossPointsLE", "0")) return false; + y += element_height + v_spacing; + } + + if (!DisableDailyProfitLossPercGE) + { + if (!CheckBoxCreate(m_ChkDailyProfitLossPercGE, first_column_start, y, panel_end, y + element_height, "m_ChkDailyProfitLossPercGE", "Daily profit/loss >= %")) return false; + if (!EditCreate(m_EdtDailyProfitLossPercGE, last_big_input_start, y, last_input_end, y + element_height, "m_EdtDailyProfitLossPercGE", "0")) return false; + y += element_height + v_spacing; + } + if (!DisableDailyProfitLossPercLE) + { + if (!CheckBoxCreate(m_ChkDailyProfitLossPercLE, first_column_start, y, panel_end, y + element_height, "m_ChkDailyProfitLossPercLE", "Daily profit/loss <= %")) return false; + if (!EditCreate(m_EdtDailyProfitLossPercLE, last_big_input_start, y, last_input_end, y + element_height, "m_EdtDailyProfitLossPercLE", "0")) return false; y += element_height + v_spacing; } // Actions Tab Objects y = row_start + 2 * element_height + 4 * v_spacing; - if (!CheckBoxCreate(m_ChkClosePos, first_column_start, y, first_column_start + narrowest_edit_width, y + element_height, "m_ChkClosePos", "Close ")) return(false); - if (!EditCreate(m_EdtClosePercentage, first_column_start + narrowest_edit_width + v_spacing, y, first_column_start + narrowest_edit_width + v_spacing + narrowest_edit_width, y + element_height, "m_EdtClosePercentage", "100")) return(false); - if (!LabelCreate(m_LblClosePosSuffix, first_column_start + narrowest_edit_width + v_spacing + narrowest_edit_width + v_spacing, y, first_column_start + narrowest_edit_width + v_spacing + narrowest_edit_width + shortest_edit_width, y + element_height, "m_LblClosePosSuffix", "% of ")) return(false); - if (!ButtonCreate(m_BtnPositionStatus, first_column_start + narrowest_edit_width + v_spacing + narrowest_edit_width + shortest_edit_width, y, first_column_start + narrowest_edit_width + v_spacing + narrowest_edit_width + shortest_edit_width + narrow_edit_width, y + element_height, "m_BtnPositionStatus", "All")) return(false); - if (!LabelCreate(m_LblClosePosPostfix, first_column_start + narrowest_edit_width + v_spacing + narrowest_edit_width + shortest_edit_width + narrow_edit_width, y, panel_end, y + element_height, "m_LblClosePosPostfix", " positions' volume.")) return(false); + if (!CheckBoxCreate(m_ChkClosePos, first_column_start, y, first_column_start + narrowest_edit_width, y + element_height, "m_ChkClosePos", "Close ")) return false; + if (!EditCreate(m_EdtClosePercentage, first_column_start + narrowest_edit_width + v_spacing, y, first_column_start + narrowest_edit_width + v_spacing + narrowest_edit_width, y + element_height, "m_EdtClosePercentage", "100")) return false; + if (!LabelCreate(m_LblClosePosSuffix, first_column_start + narrowest_edit_width + v_spacing + narrowest_edit_width + v_spacing, y, first_column_start + narrowest_edit_width + v_spacing + narrowest_edit_width + shortest_edit_width, y + element_height, "m_LblClosePosSuffix", "% of ")) return false; + if (!ButtonCreate(m_BtnPositionStatus, first_column_start + narrowest_edit_width + v_spacing + narrowest_edit_width + shortest_edit_width, y, first_column_start + narrowest_edit_width + v_spacing + narrowest_edit_width + shortest_edit_width + narrow_edit_width, y + element_height, "m_BtnPositionStatus", "All")) return false; + if (!LabelCreate(m_LblClosePosPostfix, first_column_start + narrowest_edit_width + v_spacing + narrowest_edit_width + shortest_edit_width + narrow_edit_width, y, panel_end, y + element_height, "m_LblClosePosPostfix", " positions' volume.")) return false; y += element_height + v_spacing; - if (!CheckBoxCreate(m_ChkDeletePend, first_column_start, y, panel_end, y + element_height, "m_ChkDeletePend", "Delete all pending orders")) return(false); + if (!CheckBoxCreate(m_ChkDeletePend, first_column_start, y, panel_end, y + element_height, "m_ChkDeletePend", "Delete all pending orders")) return false; y += element_height + v_spacing; - if (!CheckBoxCreate(m_ChkDisAuto, first_column_start, y, panel_end, y + element_height, "m_ChkDisAuto", "Disable autotrading")) return(false); + if (!CheckBoxCreate(m_ChkDisAuto, first_column_start, y, panel_end, y + element_height, "m_ChkDisAuto", "Disable autotrading")) return false; y += element_height + v_spacing; - if (!CheckBoxCreate(m_ChkSendMails, first_column_start, y, panel_end, y + element_height, "m_ChkSendMails", "Send e-mail")) return(false); + if (!CheckBoxCreate(m_ChkSendMails, first_column_start, y, panel_end, y + element_height, "m_ChkSendMails", "Send e-mail")) return false; y += element_height + v_spacing; - if (!CheckBoxCreate(m_ChkSendNotif, first_column_start, y, panel_end, y + element_height, "m_ChkSendNotif", "Send push notification")) return(false); + if (!CheckBoxCreate(m_ChkSendNotif, first_column_start, y, panel_end, y + element_height, "m_ChkSendNotif", "Send push notification")) return false; y += element_height + v_spacing; - if (!CheckBoxCreate(m_ChkClosePlatform, first_column_start, y, panel_end, y + element_height, "m_ChkClosePlatform", "Close platform")) return(false); + if (!CheckBoxCreate(m_ChkClosePlatform, first_column_start, y, panel_end, y + element_height, "m_ChkClosePlatform", "Close platform")) return false; y += element_height + v_spacing; - if (!CheckBoxCreate(m_ChkEnableAuto, first_column_start, y, panel_end, y + element_height, "m_ChkEnableAuto", "Enable autotrading")) return(false); + if (!CheckBoxCreate(m_ChkEnableAuto, first_column_start, y, panel_end, y + element_height, "m_ChkEnableAuto", "Enable autotrading")) return false; y += element_height + v_spacing; - if (!CheckBoxCreate(m_ChkRecaptureSnapshots, first_column_start, y, panel_end, y + element_height, "m_ChkRecaptureSnapshots", "Recapture snapshots")) return(false); + if (!CheckBoxCreate(m_ChkRecaptureSnapshots, first_column_start, y, panel_end, y + element_height, "m_ChkRecaptureSnapshots", "Recapture snapshots")) return false; InitObjects(); - return(true); + return true; } // Initializes all panel objects after they are created. bool CAccountProtector::InitObjects() { -//+-------------------------------------+ -//| Align text from objects all objects | -//+-------------------------------------+ + //+-------------------------------------+ + //| Align text from objects all objects | + //+-------------------------------------+ ENUM_ALIGN_MODE align = ALIGN_RIGHT; - if (!m_EdtTimer.TextAlign(align)) return(false); - if (!DisableFloatLossRisePerc) if (!m_EdtLossPerBalance.TextAlign(align)) return(false); - if (!DisableFloatLossFallPerc) if (!m_EdtLossPerBalanceReverse.TextAlign(align)) return(false); - if (!DisableFloatLossRiseCurr) if (!m_EdtLossQuanUnits.TextAlign(align)) return(false); - if (!DisableFloatLossFallCurr) if (!m_EdtLossQuanUnitsReverse.TextAlign(align)) return(false); - if (!DisableFloatLossRisePips) if (!m_EdtLossPips.TextAlign(align)) return(false); - if (!DisableFloatLossFallPips) if (!m_EdtLossPipsReverse.TextAlign(align)) return(false); - if (!DisableFloatProfitRisePerc) if (!m_EdtProfPerBalance.TextAlign(align)) return(false); - if (!DisableFloatProfitFallPerc) if (!m_EdtProfPerBalanceReverse.TextAlign(align)) return(false); - if (!DisableFloatProfitRiseCurr) if (!m_EdtProfQuanUnits.TextAlign(align)) return(false); - if (!DisableFloatProfitFallCurr) if (!m_EdtProfQuanUnitsReverse.TextAlign(align)) return(false); - if (!DisableFloatProfitRisePips) if (!m_EdtProfPips.TextAlign(align)) return(false); - if (!DisableFloatProfitFallPips) if (!m_EdtProfPipsReverse.TextAlign(align)) return(false); - if (!m_EdtEquityLessUnits.TextAlign(align)) return(false); - if (!m_EdtEquityGrUnits.TextAlign(align)) return(false); - if (!m_EdtEquityLessPerSnap.TextAlign(align)) return(false); - if (!m_EdtEquityGrPerSnap.TextAlign(align)) return(false); - if (!DisableEquityMinusSnapshot) if (!m_EdtEquityMinusSnapshot.TextAlign(align)) return(false); - if (!DisableSnapshotMinusEquity) if (!m_EdtSnapshotMinusEquity.TextAlign(align)) return(false); - if (!m_EdtMarginLessUnits.TextAlign(align)) return(false); - if (!m_EdtMarginLessPerSnap.TextAlign(align)) return(false); - if (!m_EdtMarginGrUnits.TextAlign(align)) return(false); - if (!m_EdtMarginGrPerSnap.TextAlign(align)) return(false); - if (!DisableCurrentPriceGE) if (!m_EdtPriceGE.TextAlign(align)) return(false); - if (!DisableCurrentPriceLE) if (!m_EdtPriceLE.TextAlign(align)) return(false); - if (!m_EdtTrailingStart.TextAlign(align)) return(false); - if (!m_EdtTrailingStep.TextAlign(align)) return(false); - if (!m_EdtBreakEven.TextAlign(align)) return(false); - if (!m_EdtBreakEvenExtra.TextAlign(align)) return(false); - if (!m_EdtEquityTrailingStop.TextAlign(align)) return(false); - if (!m_EdtClosePercentage.TextAlign(align)) return(false); + if (!m_EdtTimer.TextAlign(align)) return false; + if (!DisableFloatLossRisePerc) if (!m_EdtLossPerBalance.TextAlign(align)) return false; + if (!DisableFloatLossFallPerc) if (!m_EdtLossPerBalanceReverse.TextAlign(align)) return false; + if (!DisableFloatLossRiseCurr) if (!m_EdtLossQuanUnits.TextAlign(align)) return false; + if (!DisableFloatLossFallCurr) if (!m_EdtLossQuanUnitsReverse.TextAlign(align)) return false; + if (!DisableFloatLossRisePoints) if (!m_EdtLossPoints.TextAlign(align)) return false; + if (!DisableFloatLossFallPoints) if (!m_EdtLossPointsReverse.TextAlign(align)) return false; + if (!DisableFloatProfitRisePerc) if (!m_EdtProfPerBalance.TextAlign(align)) return false; + if (!DisableFloatProfitFallPerc) if (!m_EdtProfPerBalanceReverse.TextAlign(align)) return false; + if (!DisableFloatProfitRiseCurr) if (!m_EdtProfQuanUnits.TextAlign(align)) return false; + if (!DisableFloatProfitFallCurr) if (!m_EdtProfQuanUnitsReverse.TextAlign(align)) return false; + if (!DisableFloatProfitRisePoints) if (!m_EdtProfPoints.TextAlign(align)) return false; + if (!DisableFloatProfitFallPoints) if (!m_EdtProfPointsReverse.TextAlign(align)) return false; + if (!m_EdtEquityLessUnits.TextAlign(align)) return false; + if (!m_EdtEquityGrUnits.TextAlign(align)) return false; + if (!m_EdtEquityLessPerSnap.TextAlign(align)) return false; + if (!m_EdtEquityGrPerSnap.TextAlign(align)) return false; + if (!DisableEquityMinusSnapshot) if (!m_EdtEquityMinusSnapshot.TextAlign(align)) return false; + if (!DisableSnapshotMinusEquity) if (!m_EdtSnapshotMinusEquity.TextAlign(align)) return false; + if (!m_EdtMarginLessUnits.TextAlign(align)) return false; + if (!m_EdtMarginLessPerSnap.TextAlign(align)) return false; + if (!m_EdtMarginGrUnits.TextAlign(align)) return false; + if (!m_EdtMarginGrPerSnap.TextAlign(align)) return false; + if (!DisableCurrentPriceGE) if (!m_EdtPriceGE.TextAlign(align)) return false; + if (!DisableCurrentPriceLE) if (!m_EdtPriceLE.TextAlign(align)) return false; + if (!DisableMarginLevelGE) if (!m_EdtMarginLevelGE.TextAlign(align)) return false; + if (!DisableMarginLevelLE) if (!m_EdtMarginLevelLE.TextAlign(align)) return false; + if (!DisableSpreadGE) if (!m_EdtSpreadGE.TextAlign(align)) return false; + if (!DisableSpreadLE) if (!m_EdtSpreadLE.TextAlign(align)) return false; + if (!DisableDailyProfitLossUnitsGE) if (!m_EdtDailyProfitLossUnitsGE.TextAlign(align)) return false; + if (!DisableDailyProfitLossUnitsLE) if (!m_EdtDailyProfitLossUnitsLE.TextAlign(align)) return false; + if (!DisableDailyProfitLossPointsGE) if (!m_EdtDailyProfitLossPointsGE.TextAlign(align)) return false; + if (!DisableDailyProfitLossPointsLE) if (!m_EdtDailyProfitLossPointsLE.TextAlign(align)) return false; + if (!DisableDailyProfitLossPercGE) if (!m_EdtDailyProfitLossPercGE.TextAlign(align)) return false; + if (!DisableDailyProfitLossPercLE) if (!m_EdtDailyProfitLossPercLE.TextAlign(align)) return false; + if (!m_EdtTrailingStart.TextAlign(align)) return false; + if (!m_EdtTrailingStep.TextAlign(align)) return false; + if (!m_EdtBreakEven.TextAlign(align)) return false; + if (!m_EdtBreakEvenExtra.TextAlign(align)) return false; + if (!m_EdtEquityTrailingStop.TextAlign(align)) return false; + if (!m_EdtClosePercentage.TextAlign(align)) return false; ShowSelectedTab(); -// Show/hide current equity stop-loss + // Show/hide current equity stop-loss if (sets.doubleCurrentEquityStopLoss != 0) { - if (!m_LblCurrentEquityStopLoss.Hide()) return(false); - if (!m_BtnResetEquityStopLoss.Hide()) return(false); + if (!m_LblCurrentEquityStopLoss.Hide()) return false; + if (!m_BtnResetEquityStopLoss.Hide()) return false; } SeekAndDestroyDuplicatePanels(); - return(true); + return true; } -//+------------------------------------------------------------------+ -//| | -//+------------------------------------------------------------------+ void CAccountProtector::ShowSelectedTab() { HideMain(); @@ -860,11 +990,50 @@ void CAccountProtector::MoveAndResize() } else if (sets.SelectedTab == FiltersTab) { + // Move stuff below the radiogroup based on the radigroup option. + // The last two options add two lines between the radiogroup and the "Order commentary" fields - they and everything below has to be moved. + if ((sets.intInstrumentFilter == 3) || (sets.intInstrumentFilter == 4)) + { + m_LblInstruments.Show(); + m_EdtInstruments.Show(); + ref_point = m_EdtInstruments.Top(); + m_LblOrderCommentary.Move(m_LblOrderCommentary.Left(), ref_point + col_height * 1); + m_CbxOrderCommentaryCondition.Move(m_CbxOrderCommentaryCondition.Left(), ref_point + col_height * 1); + m_EdtOrderCommentary.Move(m_EdtOrderCommentary.Left(), ref_point + col_height * 1); + m_ChkIgnoreLossTrades.Move(m_ChkIgnoreLossTrades.Left(), ref_point + col_height * 2); + m_ChkIgnoreProfitTrades.Move(m_ChkIgnoreProfitTrades.Left(), ref_point + col_height * 2); + m_BtnResetFilters.Move(m_BtnResetFilters.Left(), ref_point + col_height * 3); + m_LblURL.Move(m_LblURL.Left(), ref_point + col_height * 4); + } + else + { + ref_point = m_RgpInstrumentFilter.Top(); + m_LblInstruments.Hide(); + m_EdtInstruments.Hide(); + m_LblOrderCommentary.Move(m_LblOrderCommentary.Left(), ref_point + (int)MathRound(col_height * 4.5)); + m_CbxOrderCommentaryCondition.Move(m_CbxOrderCommentaryCondition.Left(), ref_point + (int)MathRound(col_height * 4.5)); + m_EdtOrderCommentary.Move(m_EdtOrderCommentary.Left(), ref_point + (int)MathRound(col_height * 4.5)); + m_ChkIgnoreLossTrades.Move(m_ChkIgnoreLossTrades.Left(), ref_point + (int)MathRound(col_height * 5.5)); + m_ChkIgnoreProfitTrades.Move(m_ChkIgnoreProfitTrades.Left(), ref_point + (int)MathRound(col_height * 5.5)); + m_BtnResetFilters.Move(m_BtnResetFilters.Left(), ref_point + (int)MathRound(col_height * 6.5)); + m_LblURL.Move(m_LblURL.Left(), ref_point + (int)MathRound(col_height * 7.5)); + } + ref_point = m_BtnResetFilters.Top(); } else if (sets.SelectedTab == ConditionsTab) { - if (!DisableCurrentPriceLE) ref_point = m_EdtPriceLE.Top(); + if (!DisableDailyProfitLossPercLE) ref_point = m_EdtDailyProfitLossPercLE.Top(); + else if (!DisableDailyProfitLossPercGE) ref_point = m_EdtDailyProfitLossPercGE.Top(); + else if (!DisableDailyProfitLossPointsLE) ref_point = m_EdtDailyProfitLossPointsLE.Top(); + else if (!DisableDailyProfitLossPointsGE) ref_point = m_EdtDailyProfitLossPointsGE.Top(); + else if (!DisableDailyProfitLossUnitsLE) ref_point = m_EdtDailyProfitLossUnitsLE.Top(); + else if (!DisableDailyProfitLossUnitsGE) ref_point = m_EdtDailyProfitLossUnitsGE.Top(); + else if (!DisableSpreadLE) ref_point = m_EdtSpreadLE.Top(); + else if (!DisableSpreadGE) ref_point = m_EdtSpreadGE.Top(); + else if (!DisableMarginLevelLE) ref_point = m_EdtMarginLevelLE.Top(); + else if (!DisableMarginLevelGE) ref_point = m_EdtMarginLevelGE.Top(); + else if (!DisableCurrentPriceLE) ref_point = m_EdtPriceLE.Top(); else if (!DisableCurrentPriceGE) ref_point = m_EdtPriceGE.Top(); else ref_point = m_EdtMarginGrPerSnap.Top(); } @@ -910,7 +1079,7 @@ void CAccountProtector::Maximize() bool CAccountProtector::RefreshValues() { Check_Status(); - if (!m_LblSpread.Text("Spread: " + DoubleToString((double)SymbolInfoInteger(Symbol(), SYMBOL_SPREAD) * SymbolInfoDouble(Symbol(), SYMBOL_POINT), (int)SymbolInfoInteger(Symbol(), SYMBOL_DIGITS)))) return(false); + if (!m_LblSpread.Text("Spread: " + DoubleToString((double)SymbolInfoInteger(Symbol(), SYMBOL_SPREAD) * SymbolInfoDouble(Symbol(), SYMBOL_POINT), (int)SymbolInfoInteger(Symbol(), SYMBOL_DIGITS)))) return false; if (m_ChkUseTimer.Checked()) { sets.TimeLeft = NewTime(); @@ -923,18 +1092,18 @@ bool CAccountProtector::RefreshValues() if (IsANeedToContinueClosingOrders) Close_All_Positions(); if (IsANeedToContinueDeletingPendingOrders) Delete_All_Pending_Orders(); - return(true); + return true; } // Updates all panel controls depending on the settings in sets struct. void CAccountProtector::RefreshPanelControls() { -// Main tab + // Main tab -// Refresh "Count commission/swaps". + // Refresh "Count commission/swaps". m_ChkCountCommSwaps.Checked(sets.CountCommSwaps); -// Refresh timer fields. + // Refresh timer fields. if (sets.UseTimer) { m_ChkUseTimer.Checked(true); @@ -947,106 +1116,113 @@ void CAccountProtector::RefreshPanelControls() m_EdtTimer.Text(sets.Timer); m_BtnDayOfWeek.Text(EnumToString(sets.TimerDayOfWeek)); -// Refresh time type radio group. + // Refresh time type radio group. m_RgpTimeType.Value(sets.intTimeType); -// Refresh trailing stop start fields. + // Refresh trailing stop start fields. RefreshConditions(sets.boolTrailingStart, sets.intTrailingStart, m_ChkTrailingStart, m_EdtTrailingStart, 0); -// Refresh trailing stop step fields. + // Refresh trailing stop step fields. RefreshConditions(sets.boolTrailingStep, sets.intTrailingStep, m_ChkTrailingStep, m_EdtTrailingStep, 0); -// Refresh breakeven fields. + // Refresh breakeven fields. RefreshConditions(sets.boolBreakEven, sets.intBreakEven, m_ChkBreakEven, m_EdtBreakEven, 0); -// Refresh breakeven extra fields. + // Refresh breakeven extra fields. RefreshConditions(sets.boolBreakEvenExtra, sets.intBreakEvenExtra, m_ChkBreakEvenExtra, m_EdtBreakEvenExtra, 0); -// Refresh equity trailing stop fields. + // Refresh equity trailing stop fields. RefreshConditions(sets.boolEquityTrailingStop, sets.doubleEquityTrailingStop, m_ChkEquityTrailingStop, m_EdtEquityTrailingStop, 2); string AdditionalFunds_Asterisk = ""; if (AdditionalFunds != 0) AdditionalFunds_Asterisk = "*"; -// Refresh snapshot of equity. + // Refresh snapshot of equity. if (sets.SnapEquityTime != "") m_LblSnapEquity.Text("Snapshot of equity: " + DoubleToString(sets.SnapEquity, 2) + " (" + sets.SnapEquityTime + ")" + AdditionalFunds_Asterisk); else m_LblSnapEquity.Text("Snapshot of equity: "); -// Refresh snapshot of margin. + // Refresh snapshot of margin. if (sets.SnapMarginTime != "") m_LblSnapMargin.Text("Snapshot of free margin: " + DoubleToString(sets.SnapMargin, 2) + " (" + sets.SnapMarginTime + ")" + AdditionalFunds_Asterisk); else m_LblSnapMargin.Text("Snapshot of free margin: "); -// Filters tab + // Filters tab -// Refresh order commentary condition list view. + // Refresh order commentary condition list view. m_CbxOrderCommentaryCondition.Select(sets.intOrderCommentaryCondition); -// Refresh order commentary edit. + // Refresh order commentary edit. m_EdtOrderCommentary.Text(sets.OrderCommentary); -// Refresh magic numbers. + // Refresh magic numbers. m_EdtMagics.Text(sets.MagicNumbers); ProcessMagicNumbers(); -// Refresh "Exclude" checkbox for magic numbers. + // Refresh "Exclude" checkbox for magic numbers. m_ChkExcludeMagics.Checked(sets.boolExcludeMagics); -// Refresh trading instrument radio group. + // Refresh trading instrument radio group. m_RgpInstrumentFilter.Value(sets.intInstrumentFilter); + // Refresh trading instrument list. + m_EdtInstruments.Text(sets.Instruments); + ProcessInstruments(); -// Conditions tab + // Refresh "Ignore" checkboxes. + m_ChkIgnoreLossTrades.Checked(sets.boolIgnoreLossTrades); + m_ChkIgnoreProfitTrades.Checked(sets.boolIgnoreProfitTrades); -// Refresh "Floating loss rises to % of balance" fields. + // Conditions tab + + // Refresh "Floating loss rises to % of balance" fields. if (!DisableFloatLossRisePerc) RefreshConditions(sets.boolLossPerBalance, sets.doubleLossPerBalance, m_ChkLossPerBalance, m_EdtLossPerBalance); -// Refresh "Floating loss falls to % of balance" fields. + // Refresh "Floating loss falls to % of balance" fields. if (!DisableFloatLossFallPerc) RefreshConditions(sets.boolLossPerBalanceReverse, sets.doubleLossPerBalanceReverse, m_ChkLossPerBalanceReverse, m_EdtLossPerBalanceReverse); -// Refresh "Floating loss rises to currency units" fields. + // Refresh "Floating loss rises to currency units" fields. if (!DisableFloatLossRiseCurr) RefreshConditions(sets.boolLossQuanUnits, sets.doubleLossQuanUnits, m_ChkLossQuanUnits, m_EdtLossQuanUnits); -// Refresh "Floating loss falls to currency units" fields. + // Refresh "Floating loss falls to currency units" fields. if (!DisableFloatLossFallCurr) RefreshConditions(sets.boolLossQuanUnitsReverse, sets.doubleLossQuanUnitsReverse, m_ChkLossQuanUnitsReverse, m_EdtLossQuanUnitsReverse); -// Refresh "Floating loss rises to pips" fields. - if (!DisableFloatLossRisePips) RefreshConditions(sets.boolLossPips, sets.intLossPips, m_ChkLossPips, m_EdtLossPips, 0); + // Refresh "Floating loss rises to points" fields. + if (!DisableFloatLossRisePoints) RefreshConditions(sets.boolLossPoints, sets.intLossPoints, m_ChkLossPoints, m_EdtLossPoints, 0); -// Refresh "Floating loss falls to pips" fields. - if (!DisableFloatLossFallPips) RefreshConditions(sets.boolLossPipsReverse, sets.intLossPipsReverse, m_ChkLossPipsReverse, m_EdtLossPipsReverse, 0); + // Refresh "Floating loss falls to points" fields. + if (!DisableFloatLossFallPoints) RefreshConditions(sets.boolLossPointsReverse, sets.intLossPointsReverse, m_ChkLossPointsReverse, m_EdtLossPointsReverse, 0); -// Refresh "Floating profit rises to % of balance" fields. + // Refresh "Floating profit rises to % of balance" fields. if (!DisableFloatProfitRisePerc) RefreshConditions(sets.boolProfPerBalance, sets.doubleProfPerBalance, m_ChkProfPerBalance, m_EdtProfPerBalance); -// Refresh "Floating profit falls to % of balance" fields. + // Refresh "Floating profit falls to % of balance" fields. if (!DisableFloatProfitFallPerc) RefreshConditions(sets.boolProfPerBalanceReverse, sets.doubleProfPerBalanceReverse, m_ChkProfPerBalanceReverse, m_EdtProfPerBalanceReverse); -// Refresh "Floating profit rises to currency units" fields. + // Refresh "Floating profit rises to currency units" fields. if (!DisableFloatProfitRiseCurr) RefreshConditions(sets.boolProfQuanUnits, sets.doubleProfQuanUnits, m_ChkProfQuanUnits, m_EdtProfQuanUnits); -// Refresh "Floating profit falls to currency units" fields. + // Refresh "Floating profit falls to currency units" fields. if (!DisableFloatProfitFallCurr) RefreshConditions(sets.boolProfQuanUnitsReverse, sets.doubleProfQuanUnitsReverse, m_ChkProfQuanUnitsReverse, m_EdtProfQuanUnitsReverse); -// Refresh "Floating profit rises to pips" fields. - if (!DisableFloatProfitRisePips) RefreshConditions(sets.boolProfPips, sets.intProfPips, m_ChkProfPips, m_EdtProfPips, 0); + // Refresh "Floating profit rises to points" fields. + if (!DisableFloatProfitRisePoints) RefreshConditions(sets.boolProfPoints, sets.intProfPoints, m_ChkProfPoints, m_EdtProfPoints, 0); -// Refresh "Floating profit falls to pips" fields. - if (!DisableFloatProfitFallPips) RefreshConditions(sets.boolProfPipsReverse, sets.intProfPipsReverse, m_ChkProfPipsReverse, m_EdtProfPipsReverse, 0); + // Refresh "Floating profit falls to points" fields. + if (!DisableFloatProfitFallPoints) RefreshConditions(sets.boolProfPointsReverse, sets.intProfPointsReverse, m_ChkProfPointsReverse, m_EdtProfPointsReverse, 0); -// Refresh "Equity <= currency units" fields. + // Refresh "Equity <= currency units" fields. RefreshConditions(sets.boolEquityLessUnits, sets.doubleEquityLessUnits, m_ChkEquityLessUnits, m_EdtEquityLessUnits); -// Refresh "Equity >= currency units" fields. + // Refresh "Equity >= currency units" fields. RefreshConditions(sets.boolEquityGrUnits, sets.doubleEquityGrUnits, m_ChkEquityGrUnits, m_EdtEquityGrUnits); -// Refresh "Equity <= % of snapshot" fields. + // Refresh "Equity <= % of snapshot" fields. RefreshConditions(sets.boolEquityLessPerSnap, sets.doubleEquityLessPerSnap, m_ChkEquityLessPerSnap, m_EdtEquityLessPerSnap); if (sets.SnapEquityTime != "") m_ChkEquityLessPerSnap.Text("Equity <= % of snapshot (" + DoubleToString(sets.SnapEquity, 2) + ")" + AdditionalFunds_Asterisk + ":"); else m_ChkEquityLessPerSnap.Text("Equity <= % of snapshot:"); -// Refresh "Equity >= % of snapshot" fields. + // Refresh "Equity >= % of snapshot" fields. RefreshConditions(sets.boolEquityGrPerSnap, sets.doubleEquityGrPerSnap, m_ChkEquityGrPerSnap, m_EdtEquityGrPerSnap); if (sets.SnapEquityTime != "") m_ChkEquityGrPerSnap.Text("Equity >= % of snapshot (" + DoubleToString(sets.SnapEquity, 2) + ")" + AdditionalFunds_Asterisk + ":"); else m_ChkEquityGrPerSnap.Text("Equity >= % of snapshot:"); -// Refresh "Equity - Snapshot >= currency units" fields. + // Refresh "Equity - Snapshot >= currency units" fields. if (!DisableEquityMinusSnapshot) { RefreshConditions(sets.boolEquityMinusSnapshot, sets.doubleEquityMinusSnapshot, m_ChkEquityMinusSnapshot, m_EdtEquityMinusSnapshot); @@ -1054,7 +1230,7 @@ void CAccountProtector::RefreshPanelControls() else m_ChkEquityMinusSnapshot.Text("Equity - snapshot >= currency units:"); } -// Refresh "Snapshot - Equity >= currency units" fields. + // Refresh "Snapshot - Equity >= currency units" fields. if (!DisableSnapshotMinusEquity) { RefreshConditions(sets.boolSnapshotMinusEquity, sets.doubleSnapshotMinusEquity, m_ChkSnapshotMinusEquity, m_EdtSnapshotMinusEquity); @@ -1062,59 +1238,89 @@ void CAccountProtector::RefreshPanelControls() else m_ChkSnapshotMinusEquity.Text("Snapshot - Equity >= currency units:"); } -// Refresh "Free margin <= currency units" fields. + // Refresh "Free margin <= currency units" fields. RefreshConditions(sets.boolMarginLessUnits, sets.doubleMarginLessUnits, m_ChkMarginLessUnits, m_EdtMarginLessUnits); -// Refresh "Free margin >= currency units" fields. + // Refresh "Free margin >= currency units" fields. RefreshConditions(sets.boolMarginGrUnits, sets.doubleMarginGrUnits, m_ChkMarginGrUnits, m_EdtMarginGrUnits); -// Refresh "Free margin <= % of snapshot" fields. + // Refresh "Free margin <= % of snapshot" fields. RefreshConditions(sets.boolMarginLessPerSnap, sets.doubleMarginLessPerSnap, m_ChkMarginLessPerSnap, m_EdtMarginLessPerSnap); if (sets.SnapMarginTime != "") m_ChkMarginLessPerSnap.Text("Free margin <= % of snapshot (" + DoubleToString(sets.SnapMargin, 2) + ")" + AdditionalFunds_Asterisk + ":"); else m_ChkMarginLessPerSnap.Text("Free margin <= % of snapshot:"); -// Refresh "Free margin >= % of snapshot" fields. + // Refresh "Free margin >= % of snapshot" fields. RefreshConditions(sets.boolMarginGrPerSnap, sets.doubleMarginGrPerSnap, m_ChkMarginGrPerSnap, m_EdtMarginGrPerSnap); if (sets.SnapMarginTime != "") m_ChkMarginGrPerSnap.Text("Free margin >= % of snapshot (" + DoubleToString(sets.SnapMargin, 2) + ")" + AdditionalFunds_Asterisk + ":"); else m_ChkMarginGrPerSnap.Text("Free margin >= % of snapshot:"); -// Refresh "Current price greater or equal" fields. + // Refresh "Current price greater or equal" fields. if (!DisableCurrentPriceGE) RefreshConditions(sets.boolPriceGE, sets.doublePriceGE, m_ChkPriceGE, m_EdtPriceGE, _Digits); -// Refresh "Current price less or equal" fields. + // Refresh "Current price less or equal" fields. if (!DisableCurrentPriceLE) RefreshConditions(sets.boolPriceLE, sets.doublePriceLE, m_ChkPriceLE, m_EdtPriceLE, _Digits); -// Actions tab + // Refresh "Margin level greater or equal" fields. + if (!DisableMarginLevelGE) RefreshConditions(sets.boolMarginLevelGE, sets.doubleMarginLevelGE, m_ChkMarginLevelGE, m_EdtMarginLevelGE, 2); + + // Refresh "Margin level less or equal" fields. + if (!DisableMarginLevelLE) RefreshConditions(sets.boolMarginLevelLE, sets.doubleMarginLevelLE, m_ChkMarginLevelLE, m_EdtMarginLevelLE, 2); + + // Refresh "Spread greater or equal" fields. + if (!DisableSpreadGE) RefreshConditions(sets.boolSpreadGE, sets.intSpreadGE, m_ChkSpreadGE, m_EdtSpreadGE, 0); + + // Refresh "Spread less or equal" fields. + if (!DisableSpreadLE) RefreshConditions(sets.boolSpreadLE, sets.intSpreadLE, m_ChkSpreadLE, m_EdtSpreadLE, 0); -// Refresh "Close all positions" checkbox. + // Refresh "Daily profit/loss greater or equal currency units" fields. + if (!DisableDailyProfitLossUnitsGE) RefreshConditions(sets.boolDailyProfitLossUnitsGE, sets.doubleDailyProfitLossUnitsGE, m_ChkDailyProfitLossUnitsGE, m_EdtDailyProfitLossUnitsGE); + + // Refresh "Daily profit/loss less or equal currency units" fields. + if (!DisableDailyProfitLossUnitsLE) RefreshConditions(sets.boolDailyProfitLossUnitsLE, sets.doubleDailyProfitLossUnitsLE, m_ChkDailyProfitLossUnitsLE, m_EdtDailyProfitLossUnitsLE); + + // Refresh "Daily profit/loss greater or equal points" fields. + if (!DisableDailyProfitLossPointsGE) RefreshConditions(sets.boolDailyProfitLossPointsGE, sets.intDailyProfitLossPointsGE, m_ChkDailyProfitLossPointsGE, m_EdtDailyProfitLossPointsGE, 0); + + // Refresh "Daily profit/loss less or equal points" fields. + if (!DisableDailyProfitLossPointsLE) RefreshConditions(sets.boolDailyProfitLossPointsLE, sets.intDailyProfitLossPointsLE, m_ChkDailyProfitLossPointsLE, m_EdtDailyProfitLossPointsLE, 0); + + // Refresh "Daily profit/loss greater or equal percentage" fields. + if (!DisableDailyProfitLossPercGE) RefreshConditions(sets.boolDailyProfitLossPercGE, sets.doubleDailyProfitLossPercGE, m_ChkDailyProfitLossPercGE, m_EdtDailyProfitLossPercGE, 2); + + // Refresh "Daily profit/loss less or equal percentage" fields. + if (!DisableDailyProfitLossPercLE) RefreshConditions(sets.boolDailyProfitLossPercLE, sets.doubleDailyProfitLossPercLE, m_ChkDailyProfitLossPercLE, m_EdtDailyProfitLossPercLE, 2); + + // Actions tab + + // Refresh "Close all positions" checkbox. m_ChkClosePos.Checked(sets.ClosePos); -// Refresh "Close Percentage" field. Not a condition, but works with the same funciton. + // Refresh "Close Percentage" field. Not a condition, but works with the same funciton. RefreshConditions(sets.ClosePos, sets.doubleClosePercentage, m_ChkClosePos, m_EdtClosePercentage, 2); -// Refresh button status (All, Losing, or Profitable). + // Refresh button status (All, Losing, or Profitable). m_BtnPositionStatus.Text(EnumToString(sets.CloseWhichPositions)); -// Refresh "Delete all pending orders" checkbox. + // Refresh "Delete all pending orders" checkbox. m_ChkDeletePend.Checked(sets.DeletePend); -// Refresh "Disable AutoTrading" checkbox. + // Refresh "Disable AutoTrading" checkbox. m_ChkDisAuto.Checked(sets.DisAuto); -// Refresh "Send e-mail" checkbox. + // Refresh "Send e-mail" checkbox. m_ChkSendMails.Checked(sets.SendMails); -// Refresh "Send push notification" checkbox. + // Refresh "Send push notification" checkbox. m_ChkSendNotif.Checked(sets.SendNotif); -// Refresh "Close platform" checkbox. + // Refresh "Close platform" checkbox. m_ChkClosePlatform.Checked(sets.ClosePlatform); -// Refresh "Enable AutoTrading" checkbox. + // Refresh "Enable AutoTrading" checkbox. m_ChkEnableAuto.Checked(sets.EnableAuto); -// Refresh "Recapture snapshots" checkbox. + // Refresh "Recapture snapshots" checkbox. m_ChkRecaptureSnapshots.Checked(sets.RecaptureSnapshots); -// Refresh status label. + // Refresh status label. if (sets.Triggered) m_LblStatus.Text("Status: Triggered at " + sets.TriggeredTime); } @@ -1191,6 +1397,10 @@ void CAccountProtector::HideFilters() m_EdtMagics.Hide(); m_ChkExcludeMagics.Hide(); m_RgpInstrumentFilter.Hide(); + m_LblInstruments.Hide(); + m_EdtInstruments.Hide(); + m_ChkIgnoreLossTrades.Hide(); + m_ChkIgnoreProfitTrades.Hide(); m_BtnResetFilters.Hide(); } @@ -1205,6 +1415,13 @@ void CAccountProtector::ShowFilters() m_EdtMagics.Show(); m_ChkExcludeMagics.Show(); m_RgpInstrumentFilter.Show(); + if ((sets.intInstrumentFilter == 3) || (sets.intInstrumentFilter == 4)) + { + m_LblInstruments.Show(); + m_EdtInstruments.Show(); + } + m_ChkIgnoreLossTrades.Show(); + m_ChkIgnoreProfitTrades.Show(); m_BtnResetFilters.Show(); } @@ -1216,14 +1433,14 @@ void CAccountProtector::HideConditions() m_ChkLossPerBalanceReverse.Hide(); m_ChkLossQuanUnits.Hide(); m_ChkLossQuanUnitsReverse.Hide(); - m_ChkLossPips.Hide(); - m_ChkLossPipsReverse.Hide(); + m_ChkLossPoints.Hide(); + m_ChkLossPointsReverse.Hide(); m_ChkProfPerBalance.Hide(); m_ChkProfPerBalanceReverse.Hide(); m_ChkProfQuanUnits.Hide(); m_ChkProfQuanUnitsReverse.Hide(); - m_ChkProfPips.Hide(); - m_ChkProfPipsReverse.Hide(); + m_ChkProfPoints.Hide(); + m_ChkProfPointsReverse.Hide(); m_ChkEquityLessUnits.Hide(); m_ChkEquityLessPerSnap.Hide(); m_ChkEquityGrUnits.Hide(); @@ -1236,18 +1453,28 @@ void CAccountProtector::HideConditions() m_ChkMarginGrPerSnap.Hide(); m_ChkPriceGE.Hide(); m_ChkPriceLE.Hide(); + m_ChkMarginLevelGE.Hide(); + m_ChkMarginLevelLE.Hide(); + m_ChkDailyProfitLossUnitsGE.Hide(); + m_ChkDailyProfitLossUnitsLE.Hide(); + m_ChkDailyProfitLossPointsGE.Hide(); + m_ChkDailyProfitLossPointsLE.Hide(); + m_ChkDailyProfitLossPercGE.Hide(); + m_ChkDailyProfitLossPercLE.Hide(); + m_ChkSpreadGE.Hide(); + m_ChkSpreadLE.Hide(); m_EdtLossPerBalance.Hide(); m_EdtLossPerBalanceReverse.Hide(); m_EdtLossQuanUnits.Hide(); m_EdtLossQuanUnitsReverse.Hide(); - m_EdtLossPips.Hide(); - m_EdtLossPipsReverse.Hide(); + m_EdtLossPoints.Hide(); + m_EdtLossPointsReverse.Hide(); m_EdtProfPerBalance.Hide(); m_EdtProfPerBalanceReverse.Hide(); m_EdtProfQuanUnits.Hide(); m_EdtProfQuanUnitsReverse.Hide(); - m_EdtProfPips.Hide(); - m_EdtProfPipsReverse.Hide(); + m_EdtProfPoints.Hide(); + m_EdtProfPointsReverse.Hide(); m_EdtEquityLessUnits.Hide(); m_EdtEquityLessPerSnap.Hide(); m_EdtEquityGrUnits.Hide(); @@ -1260,6 +1487,16 @@ void CAccountProtector::HideConditions() m_EdtMarginGrPerSnap.Hide(); m_EdtPriceGE.Hide(); m_EdtPriceLE.Hide(); + m_EdtMarginLevelGE.Hide(); + m_EdtMarginLevelLE.Hide(); + m_EdtDailyProfitLossUnitsGE.Hide(); + m_EdtDailyProfitLossUnitsLE.Hide(); + m_EdtDailyProfitLossPointsGE.Hide(); + m_EdtDailyProfitLossPointsLE.Hide(); + m_EdtDailyProfitLossPercGE.Hide(); + m_EdtDailyProfitLossPercLE.Hide(); + m_EdtSpreadGE.Hide(); + m_EdtSpreadLE.Hide(); } // Shows design-elements of TabButton "Conditions". @@ -1270,14 +1507,14 @@ void CAccountProtector::ShowConditions() m_ChkLossPerBalanceReverse.Show(); m_ChkLossQuanUnits.Show(); m_ChkLossQuanUnitsReverse.Show(); - m_ChkLossPips.Show(); - m_ChkLossPipsReverse.Show(); + m_ChkLossPoints.Show(); + m_ChkLossPointsReverse.Show(); m_ChkProfPerBalance.Show(); m_ChkProfPerBalanceReverse.Show(); m_ChkProfQuanUnits.Show(); m_ChkProfQuanUnitsReverse.Show(); - m_ChkProfPips.Show(); - m_ChkProfPipsReverse.Show(); + m_ChkProfPoints.Show(); + m_ChkProfPointsReverse.Show(); m_ChkEquityLessUnits.Show(); m_ChkEquityLessPerSnap.Show(); m_ChkEquityGrUnits.Show(); @@ -1290,18 +1527,28 @@ void CAccountProtector::ShowConditions() m_ChkMarginGrPerSnap.Show(); m_ChkPriceGE.Show(); m_ChkPriceLE.Show(); + m_ChkMarginLevelGE.Show(); + m_ChkMarginLevelLE.Show(); + m_ChkSpreadGE.Show(); + m_ChkSpreadLE.Show(); + m_ChkDailyProfitLossUnitsGE.Show(); + m_ChkDailyProfitLossUnitsLE.Show(); + m_ChkDailyProfitLossPointsGE.Show(); + m_ChkDailyProfitLossPointsLE.Show(); + m_ChkDailyProfitLossPercGE.Show(); + m_ChkDailyProfitLossPercLE.Show(); m_EdtLossPerBalance.Show(); m_EdtLossPerBalanceReverse.Show(); m_EdtLossQuanUnits.Show(); m_EdtLossQuanUnitsReverse.Show(); - m_EdtLossPips.Show(); - m_EdtLossPipsReverse.Show(); + m_EdtLossPoints.Show(); + m_EdtLossPointsReverse.Show(); m_EdtProfPerBalance.Show(); m_EdtProfPerBalanceReverse.Show(); m_EdtProfQuanUnits.Show(); m_EdtProfQuanUnitsReverse.Show(); - m_EdtProfPips.Show(); - m_EdtProfPipsReverse.Show(); + m_EdtProfPoints.Show(); + m_EdtProfPointsReverse.Show(); m_EdtEquityLessUnits.Show(); m_EdtEquityLessPerSnap.Show(); m_EdtEquityGrUnits.Show(); @@ -1314,6 +1561,16 @@ void CAccountProtector::ShowConditions() m_EdtMarginGrPerSnap.Show(); m_EdtPriceGE.Show(); m_EdtPriceLE.Show(); + m_EdtMarginLevelGE.Show(); + m_EdtMarginLevelLE.Show(); + m_EdtSpreadGE.Show(); + m_EdtSpreadLE.Show(); + m_EdtDailyProfitLossUnitsGE.Show(); + m_EdtDailyProfitLossUnitsLE.Show(); + m_EdtDailyProfitLossPointsGE.Show(); + m_EdtDailyProfitLossPointsLE.Show(); + m_EdtDailyProfitLossPercGE.Show(); + m_EdtDailyProfitLossPercLE.Show(); } // Hides design-elements of TabButton "Actions". @@ -1481,19 +1738,19 @@ void CAccountProtector::OnEndEditTimer() if (StringLen(time) == 4) time = "0" + time; if ( -// Wrong length. + // Wrong length. (StringLen(time) != 5) || -// Wrong separator. + // Wrong separator. (time[2] != ':') || -// Wrong first number (only 24 hours in a day). + // Wrong first number (only 24 hours in a day). ((time[0] < '0') || (time[0] > '2')) || -// 00 to 09 and 10 to 19. + // 00 to 09 and 10 to 19. (((time[0] == '0') || (time[0] == '1')) && ((time[1] < '0') || (time[1] > '9'))) || -// 20 to 23. + // 20 to 23. ((time[0] == '2') && ((time[1] < '0') || (time[1] > '3'))) || -// 0M to 5M. + // 0M to 5M. ((time[3] < '0') || (time[3] > '5')) || -// M0 to M9. + // M0 to M9. ((time[4] < '0') || (time[4] > '9')) ) { @@ -1532,25 +1789,25 @@ void CAccountProtector::CheckboxChangeMain(bool& SettingsCheckboxValue, CCheckBo } } -// Changes Checkbox "Profit value (pips) to start Trailing SL". +// Changes Checkbox "Profit value (points) to start Trailing SL". void CAccountProtector::OnChangeChkTrailingStart() { CheckboxChangeMain(sets.boolTrailingStart, m_ChkTrailingStart); } -// Changes Checkbox "Trailing SL value (pips)". +// Changes Checkbox "Trailing SL value (points)". void CAccountProtector::OnChangeChkTrailingStep() { CheckboxChangeMain(sets.boolTrailingStep, m_ChkTrailingStep); } -// Changes Checkbox "Profit value (pips) to move SL to Breakeven". +// Changes Checkbox "Profit value (points) to move SL to Breakeven". void CAccountProtector::OnChangeChkBreakEven() { CheckboxChangeMain(sets.boolBreakEven, m_ChkBreakEven); } -// Changes Checkbox "Breakeven extra profit value (pips)". +// Changes Checkbox "Breakeven extra profit value (points)". void CAccountProtector::OnChangeChkBreakEvenExtra() { CheckboxChangeMain(sets.boolBreakEvenExtra, m_ChkBreakEvenExtra); @@ -1688,7 +1945,43 @@ void CAccountProtector::OnChangeRgpInstrumentFilter() { if (sets.intInstrumentFilter != m_RgpInstrumentFilter.Value()) { + int prev_intInstrumentFilter = sets.intInstrumentFilter; sets.intInstrumentFilter = (int)m_RgpInstrumentFilter.Value(); + if (((sets.intInstrumentFilter < 3) && (prev_intInstrumentFilter >= 3)) || ((sets.intInstrumentFilter >= 3) && (prev_intInstrumentFilter < 3))) MoveAndResize(); + SaveSettingsOnDisk(); + } +} + +// Processes edit of input field of Instruments. +void CAccountProtector::OnEndEditInstruments() +{ + string instruments = m_EdtInstruments.Text(); + + if (StringCompare(sets.Instruments, instruments) != 0) + { + sets.Instruments = instruments; + SaveSettingsOnDisk(); + } + + ProcessInstruments(); +} + +// Saves input from Checkbox "Ignore losing trades". +void CAccountProtector::OnChangeChkIgnoreLossTrades() +{ + if (sets.boolIgnoreLossTrades != m_ChkIgnoreLossTrades.Checked()) + { + sets.boolIgnoreLossTrades = m_ChkIgnoreLossTrades.Checked(); + SaveSettingsOnDisk(); + } +} + +// Saves input from Checkbox "Ignore profitable trades". +void CAccountProtector::OnChangeChkIgnoreProfitTrades() +{ + if (sets.boolIgnoreProfitTrades != m_ChkIgnoreProfitTrades.Checked()) + { + sets.boolIgnoreProfitTrades = m_ChkIgnoreProfitTrades.Checked(); SaveSettingsOnDisk(); } } @@ -1713,6 +2006,16 @@ void CAccountProtector::OnClickBtnResetFilters() if (sets.intInstrumentFilter != 0) need_to_save_to_disk = true; sets.intInstrumentFilter = 0; m_RgpInstrumentFilter.Value(0); + if (StringCompare(sets.Instruments, "") != 0) need_to_save_to_disk = true; + sets.Instruments = ""; + ProcessInstruments(); + m_EdtInstruments.Text(""); + if (sets.boolIgnoreLossTrades != false) need_to_save_to_disk = true; + sets.boolIgnoreLossTrades = false; + m_ChkIgnoreLossTrades.Checked(false); + if (sets.boolIgnoreProfitTrades != false) need_to_save_to_disk = true; + sets.boolIgnoreProfitTrades = false; + m_ChkIgnoreProfitTrades.Checked(false); if (need_to_save_to_disk) SaveSettingsOnDisk(); } @@ -1752,16 +2055,16 @@ void CAccountProtector::OnChangeChkLossQuanUnitsReverse() CheckboxChangeConditions(sets.boolLossQuanUnitsReverse, m_ChkLossQuanUnitsReverse); } -// Changes Checkbox of Condition "Floating loss rises to pips". -void CAccountProtector::OnChangeChkLossPips() +// Changes Checkbox of Condition "Floating loss rises to points". +void CAccountProtector::OnChangeChkLossPoints() { - CheckboxChangeConditions(sets.boolLossPips, m_ChkLossPips); + CheckboxChangeConditions(sets.boolLossPoints, m_ChkLossPoints); } -// Changes Checkbox of Condition "Floating loss falls to pips". -void CAccountProtector::OnChangeChkLossPipsReverse() +// Changes Checkbox of Condition "Floating loss falls to points". +void CAccountProtector::OnChangeChkLossPointsReverse() { - CheckboxChangeConditions(sets.boolLossPipsReverse, m_ChkLossPipsReverse); + CheckboxChangeConditions(sets.boolLossPointsReverse, m_ChkLossPointsReverse); } // Changes Checkbox of Condition "Floating profit rises to % of balance". @@ -1788,16 +2091,16 @@ void CAccountProtector::OnChangeChkProfQuanUnitsReverse() CheckboxChangeConditions(sets.boolProfQuanUnitsReverse, m_ChkProfQuanUnitsReverse); } -// Changes Checkbox of Condition "Floating profit rises to pips". -void CAccountProtector::OnChangeChkProfPips() +// Changes Checkbox of Condition "Floating profit rises to points". +void CAccountProtector::OnChangeChkProfPoints() { - CheckboxChangeConditions(sets.boolProfPips, m_ChkProfPips); + CheckboxChangeConditions(sets.boolProfPoints, m_ChkProfPoints); } -// Changes Checkbox of Condition "Floating profit falls to pips". -void CAccountProtector::OnChangeChkProfPipsReverse() +// Changes Checkbox of Condition "Floating profit falls to points". +void CAccountProtector::OnChangeChkProfPointsReverse() { - CheckboxChangeConditions(sets.boolProfPipsReverse, m_ChkProfPipsReverse); + CheckboxChangeConditions(sets.boolProfPointsReverse, m_ChkProfPointsReverse); } // Changes Checkbox of Condition "Equity <= currency units". @@ -1872,6 +2175,66 @@ void CAccountProtector::OnChangeChkPriceLE() CheckboxChangeConditions(sets.boolPriceLE, m_ChkPriceLE); } +// Changes Checkbox of Condition "Margin level >= % value". +void CAccountProtector::OnChangeChkMarginLevelGE() +{ + CheckboxChangeConditions(sets.boolMarginLevelGE, m_ChkMarginLevelGE); +} + +// Changes Checkbox of Condition "Margin level <= % value". +void CAccountProtector::OnChangeChkMarginLevelLE() +{ + CheckboxChangeConditions(sets.boolMarginLevelLE, m_ChkMarginLevelLE); +} + +// Changes Checkbox of Condition "Spread >= points". +void CAccountProtector::OnChangeChkSpreadGE() +{ + CheckboxChangeConditions(sets.boolSpreadGE, m_ChkSpreadGE); +} + +// Changes Checkbox of Condition "Spread <= points". +void CAccountProtector::OnChangeChkSpreadLE() +{ + CheckboxChangeConditions(sets.boolSpreadLE, m_ChkSpreadLE); +} + +// Changes Checkbox of Condition "Daily profit/loss >= units". +void CAccountProtector::OnChangeChkDailyProfitLossUnitsGE() +{ + CheckboxChangeConditions(sets.boolDailyProfitLossUnitsGE, m_ChkDailyProfitLossUnitsGE); +} + +// Changes Checkbox of Condition "Daily profit/loss <= units". +void CAccountProtector::OnChangeChkDailyProfitLossUnitsLE() +{ + CheckboxChangeConditions(sets.boolDailyProfitLossUnitsLE, m_ChkDailyProfitLossUnitsLE); +} + +// Changes Checkbox of Condition "Daily profit/loss >= points". +void CAccountProtector::OnChangeChkDailyProfitLossPointsGE() +{ + CheckboxChangeConditions(sets.boolDailyProfitLossPointsGE, m_ChkDailyProfitLossPointsGE); +} + +// Changes Checkbox of Condition "Daily profit/loss <= points". +void CAccountProtector::OnChangeChkDailyProfitLossPointsLE() +{ + CheckboxChangeConditions(sets.boolDailyProfitLossPointsLE, m_ChkDailyProfitLossPointsLE); +} + +// Changes Checkbox of Condition "Daily profit/loss >= %". +void CAccountProtector::OnChangeChkDailyProfitLossPercGE() +{ + CheckboxChangeConditions(sets.boolDailyProfitLossPercGE, m_ChkDailyProfitLossPercGE); +} + +// Changes Checkbox of Condition "Daily profit/loss <= %". +void CAccountProtector::OnChangeChkDailyProfitLossPercLE() +{ + CheckboxChangeConditions(sets.boolDailyProfitLossPercLE, m_ChkDailyProfitLossPercLE); +} + // Supplementary function to process checkbox clicks (for Actions tab). void CAccountProtector::CheckboxChangeActions(bool& SettingsCheckboxValue, CCheckBox& CheckBox) { @@ -1996,16 +2359,16 @@ void CAccountProtector::OnEndEditLossQuanUnitsReverse() EditChangeConditions(sets.doubleLossQuanUnitsReverse, m_EdtLossQuanUnitsReverse, "Floating loss falls to currency units", AccountInfoDouble(ACCOUNT_BALANCE) + AdditionalFunds); } -// Processes edit of input-field of Condition "Floating loss rises to pips". -void CAccountProtector::OnEndEditLossPips() +// Processes edit of input-field of Condition "Floating loss rises to points". +void CAccountProtector::OnEndEditLossPoints() { - EditChangeConditions(sets.intLossPips, m_EdtLossPips, "Floating loss rises to pips"); + EditChangeConditions(sets.intLossPoints, m_EdtLossPoints, "Floating loss rises to points"); } -// Processes edit of input-field of Condition "Floating loss falls to pips". -void CAccountProtector::OnEndEditLossPipsReverse() +// Processes edit of input-field of Condition "Floating loss falls to points". +void CAccountProtector::OnEndEditLossPointsReverse() { - EditChangeConditions(sets.intLossPipsReverse, m_EdtLossPipsReverse, "Floating loss falls to pips"); + EditChangeConditions(sets.intLossPointsReverse, m_EdtLossPointsReverse, "Floating loss falls to points"); } // Processes edit of input-field of Condition "Floating profit rises to % of balance". @@ -2032,16 +2395,16 @@ void CAccountProtector::OnEndEditProfQuanUnitsReverse() EditChangeConditions(sets.doubleProfQuanUnitsReverse, m_EdtProfQuanUnitsReverse, "Floating profit falls to currency units"); } -// Processes edit of input-field of Condition "Floating profit rises pips". -void CAccountProtector::OnEndEditProfPips() +// Processes edit of input-field of Condition "Floating profit rises points". +void CAccountProtector::OnEndEditProfPoints() { - EditChangeConditions(sets.intProfPips, m_EdtProfPips, "Floating profit reaches pips"); + EditChangeConditions(sets.intProfPoints, m_EdtProfPoints, "Floating profit reaches points"); } -// Processes edit of input-field of Condition "Floating profit rises to pips". -void CAccountProtector::OnEndEditProfPipsReverse() +// Processes edit of input-field of Condition "Floating profit rises to points". +void CAccountProtector::OnEndEditProfPointsReverse() { - EditChangeConditions(sets.intProfPipsReverse, m_EdtProfPipsReverse, "Floating profit falls to pips"); + EditChangeConditions(sets.intProfPointsReverse, m_EdtProfPointsReverse, "Floating profit falls to points"); } // Processes edit of input-field of Condition "Equity <= currency units". @@ -2116,6 +2479,66 @@ void CAccountProtector::OnEndEditPriceLE() EditChangeConditions(sets.doublePriceLE, m_EdtPriceLE, "Current price <="); } +// Processes edit of input-field of Condition "Margin level >= % value". +void CAccountProtector::OnEndEditMarginLevelGE() +{ + EditChangeConditions(sets.doubleMarginLevelGE, m_EdtMarginLevelGE, "Margin level >= %"); +} + +// Processes edit of input-field of Condition "Margin level <= % value". +void CAccountProtector::OnEndEditMarginLevelLE() +{ + EditChangeConditions(sets.doubleMarginLevelLE, m_EdtMarginLevelLE, "Margin level <= %"); +} + +// Processes edit of input-field of Condition "Spread >= points". +void CAccountProtector::OnEndEditSpreadGE() +{ + EditChangeConditions(sets.intSpreadGE, m_EdtSpreadGE, "Spread >= points"); +} + +// Processes edit of input-field of Condition "Spread <= points". +void CAccountProtector::OnEndEditSpreadLE() +{ + EditChangeConditions(sets.intSpreadLE, m_EdtSpreadLE, "Spread <= points"); +} + +// Processes edit of input-field of Condition "Daily profit/loss >= currency units". +void CAccountProtector::OnEndEditDailyProfitLossUnitsGE() +{ + EditChangeConditions(sets.doubleDailyProfitLossUnitsGE, m_EdtDailyProfitLossUnitsGE, "Daily profit/loss >= currency units"); +} + +// Processes edit of input-field of Condition "Daily profit/loss <= currency units". +void CAccountProtector::OnEndEditDailyProfitLossUnitsLE() +{ + EditChangeConditions(sets.doubleDailyProfitLossUnitsLE, m_EdtDailyProfitLossUnitsLE, "Daily profit/loss <= currency units"); +} + +// Processes edit of input-field of Condition "Daily profit/loss >= points". +void CAccountProtector::OnEndEditDailyProfitLossPointsGE() +{ + EditChangeConditions(sets.intDailyProfitLossPointsGE, m_EdtDailyProfitLossPointsGE, "Daily profit/loss >= points"); +} + +// Processes edit of input-field of Condition "Daily profit/loss <= points". +void CAccountProtector::OnEndEditDailyProfitLossPointsLE() +{ + EditChangeConditions(sets.intDailyProfitLossPointsLE, m_EdtDailyProfitLossPointsLE, "Daily profit/loss <= points"); +} + +// Processes edit of input-field of Condition "Daily profit/loss >= %". +void CAccountProtector::OnEndEditDailyProfitLossPercGE() +{ + EditChangeConditions(sets.doubleDailyProfitLossPercGE, m_EdtDailyProfitLossPercGE, "Daily profit/loss >= %"); +} + +// Processes edit of input-field of Condition "Daily profit/loss <= %". +void CAccountProtector::OnEndEditDailyProfitLossPercLE() +{ + EditChangeConditions(sets.doubleDailyProfitLossPercLE, m_EdtDailyProfitLossPercLE, "Daily profit/loss <= %"); +} + // Processes edit of input-field for percentage of volume to be close in Action "Close Positions". void CAccountProtector::OnEndEditClosePercentage() { @@ -2171,25 +2594,25 @@ void CAccountProtector::EditChangeMain(int& SettingsEditValue, CEdit& Edit, cons // Processes edit of input-field of Trailing Start. void CAccountProtector::OnEndEditTrailingStart() { - EditChangeMain(sets.intTrailingStart, m_EdtTrailingStart, "Profit value (pips) to start trailing SL"); + EditChangeMain(sets.intTrailingStart, m_EdtTrailingStart, "Profit value (points) to start trailing SL"); } // Processes edit of input-field of Trailing Step. void CAccountProtector::OnEndEditTrailingStep() { - EditChangeMain(sets.intTrailingStep, m_EdtTrailingStep, "Trailing SL value (pips)"); + EditChangeMain(sets.intTrailingStep, m_EdtTrailingStep, "Trailing SL value (points)"); } // Processes edit of input-field of Break Even. void CAccountProtector::OnEndEditBreakEven() { - EditChangeMain(sets.intBreakEven, m_EdtBreakEven, "Profit value (pips) to move SL to breakeven"); + EditChangeMain(sets.intBreakEven, m_EdtBreakEven, "Profit value (points) to set SL to breakeven"); } // Processes edit of input-field of Break Even Extra. void CAccountProtector::OnEndEditBreakEvenExtra() { - EditChangeMain(sets.intBreakEvenExtra, m_EdtBreakEvenExtra, "Breakeven extra profit value (pips)"); + EditChangeMain(sets.intBreakEvenExtra, m_EdtBreakEvenExtra, "Breakeven extra profit value (points)"); } // Processes edit of input-field of Equity Trailing Stop. @@ -2216,6 +2639,7 @@ void CAccountProtector::OnClickBtnEmergency() Logging("Emergency button pressed!"); if (TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) { + Logging_Condition_Is_Met(); Close_All_Positions(); Delete_All_Pending_Orders(); // Toggle AutoTrading button. "2" in GetAncestor call is the "root window". @@ -2301,7 +2725,7 @@ bool CAccountProtector::SaveSettingsOnDisk() if (fh == INVALID_HANDLE) { Logging("Failed to open file for writing: " + m_FileName + ". Error: " + IntegerToString(GetLastError())); - return(false); + return false; } // Order does not matter. @@ -2355,6 +2779,12 @@ bool CAccountProtector::SaveSettingsOnDisk() FileWrite(fh, IntegerToString(sets.boolExcludeMagics)); FileWrite(fh, "intInstrumentFilter"); FileWrite(fh, IntegerToString(sets.intInstrumentFilter)); + FileWrite(fh, "Instruments"); + FileWrite(fh, sets.Instruments); + FileWrite(fh, "boolIgnoreLossTrades"); + FileWrite(fh, IntegerToString(sets.boolIgnoreLossTrades)); + FileWrite(fh, "boolIgnoreProfitTrades"); + FileWrite(fh, IntegerToString(sets.boolIgnoreProfitTrades)); FileWrite(fh, "boolLossPerBalance"); FileWrite(fh, IntegerToString(sets.boolLossPerBalance)); FileWrite(fh, "boolLossPerBalanceReverse"); @@ -2363,10 +2793,10 @@ bool CAccountProtector::SaveSettingsOnDisk() FileWrite(fh, IntegerToString(sets.boolLossQuanUnits)); FileWrite(fh, "boolLossQuanUnitsReverse"); FileWrite(fh, IntegerToString(sets.boolLossQuanUnitsReverse)); - FileWrite(fh, "boolLossPips"); - FileWrite(fh, IntegerToString(sets.boolLossPips)); - FileWrite(fh, "boolLossPipsReverse"); - FileWrite(fh, IntegerToString(sets.boolLossPipsReverse)); + FileWrite(fh, "boolLossPoints"); + FileWrite(fh, IntegerToString(sets.boolLossPoints)); + FileWrite(fh, "boolLossPointsReverse"); + FileWrite(fh, IntegerToString(sets.boolLossPointsReverse)); FileWrite(fh, "boolProfPerBalance"); FileWrite(fh, IntegerToString(sets.boolProfPerBalance)); FileWrite(fh, "boolProfPerBalanceReverse"); @@ -2375,10 +2805,10 @@ bool CAccountProtector::SaveSettingsOnDisk() FileWrite(fh, IntegerToString(sets.boolProfQuanUnits)); FileWrite(fh, "boolProfQuanUnitsReverse"); FileWrite(fh, IntegerToString(sets.boolProfQuanUnitsReverse)); - FileWrite(fh, "boolProfPips"); - FileWrite(fh, IntegerToString(sets.boolProfPips)); - FileWrite(fh, "boolProfPipsReverse"); - FileWrite(fh, IntegerToString(sets.boolProfPipsReverse)); + FileWrite(fh, "boolProfPoints"); + FileWrite(fh, IntegerToString(sets.boolProfPoints)); + FileWrite(fh, "boolProfPointsReverse"); + FileWrite(fh, IntegerToString(sets.boolProfPointsReverse)); FileWrite(fh, "boolEquityLessUnits"); FileWrite(fh, IntegerToString(sets.boolEquityLessUnits)); FileWrite(fh, "boolEquityGrUnits"); @@ -2403,6 +2833,26 @@ bool CAccountProtector::SaveSettingsOnDisk() FileWrite(fh, IntegerToString(sets.boolPriceGE)); FileWrite(fh, "boolPriceLE"); FileWrite(fh, IntegerToString(sets.boolPriceLE)); + FileWrite(fh, "boolMarginLevelGE"); + FileWrite(fh, IntegerToString(sets.boolMarginLevelGE)); + FileWrite(fh, "boolMarginLevelLE"); + FileWrite(fh, IntegerToString(sets.boolMarginLevelLE)); + FileWrite(fh, "boolSpreadGE"); + FileWrite(fh, IntegerToString(sets.boolSpreadGE)); + FileWrite(fh, "boolSpreadLE"); + FileWrite(fh, IntegerToString(sets.boolSpreadLE)); + FileWrite(fh, "boolDailyProfitLossUnitsGE"); + FileWrite(fh, IntegerToString(sets.boolDailyProfitLossUnitsGE)); + FileWrite(fh, "boolDailyProfitLossUnitsLE"); + FileWrite(fh, IntegerToString(sets.boolDailyProfitLossUnitsLE)); + FileWrite(fh, "boolDailyProfitLossPointsGE"); + FileWrite(fh, IntegerToString(sets.boolDailyProfitLossPointsGE)); + FileWrite(fh, "boolDailyProfitLossPointsLE"); + FileWrite(fh, IntegerToString(sets.boolDailyProfitLossPointsLE)); + FileWrite(fh, "boolDailyProfitLossPercGE"); + FileWrite(fh, IntegerToString(sets.boolDailyProfitLossPercGE)); + FileWrite(fh, "boolDailyProfitLossPercLE"); + FileWrite(fh, IntegerToString(sets.boolDailyProfitLossPercLE)); FileWrite(fh, "doubleLossPerBalance"); FileWrite(fh, DoubleToString(sets.doubleLossPerBalance)); FileWrite(fh, "doubleLossPerBalanceReverse"); @@ -2411,10 +2861,10 @@ bool CAccountProtector::SaveSettingsOnDisk() FileWrite(fh, DoubleToString(sets.doubleLossQuanUnits)); FileWrite(fh, "doubleLossQuanUnitsReverse"); FileWrite(fh, DoubleToString(sets.doubleLossQuanUnitsReverse)); - FileWrite(fh, "intLossPips"); - FileWrite(fh, IntegerToString(sets.intLossPips)); - FileWrite(fh, "intLossPipsReverse"); - FileWrite(fh, IntegerToString(sets.intLossPipsReverse)); + FileWrite(fh, "intLossPoints"); + FileWrite(fh, IntegerToString(sets.intLossPoints)); + FileWrite(fh, "intLossPointsReverse"); + FileWrite(fh, IntegerToString(sets.intLossPointsReverse)); FileWrite(fh, "doubleProfPerBalance"); FileWrite(fh, DoubleToString(sets.doubleProfPerBalance)); FileWrite(fh, "doubleProfPerBalanceReverse"); @@ -2423,10 +2873,10 @@ bool CAccountProtector::SaveSettingsOnDisk() FileWrite(fh, DoubleToString(sets.doubleProfQuanUnits)); FileWrite(fh, "doubleProfQuanUnitsReverse"); FileWrite(fh, DoubleToString(sets.doubleProfQuanUnitsReverse)); - FileWrite(fh, "intProfPips"); - FileWrite(fh, IntegerToString(sets.intProfPips)); - FileWrite(fh, "intProfPipsReverse"); - FileWrite(fh, IntegerToString(sets.intProfPipsReverse)); + FileWrite(fh, "intProfPoints"); + FileWrite(fh, IntegerToString(sets.intProfPoints)); + FileWrite(fh, "intProfPointsReverse"); + FileWrite(fh, IntegerToString(sets.intProfPointsReverse)); FileWrite(fh, "doubleEquityLessUnits"); FileWrite(fh, DoubleToString(sets.doubleEquityLessUnits)); FileWrite(fh, "doubleEquityGrUnits"); @@ -2451,6 +2901,26 @@ bool CAccountProtector::SaveSettingsOnDisk() FileWrite(fh, DoubleToString(sets.doublePriceGE)); FileWrite(fh, "doublePriceLE"); FileWrite(fh, DoubleToString(sets.doublePriceLE)); + FileWrite(fh, "doubleMarginLevelGE"); + FileWrite(fh, DoubleToString(sets.doubleMarginLevelGE)); + FileWrite(fh, "doubleMarginLevelLE"); + FileWrite(fh, DoubleToString(sets.doubleMarginLevelLE)); + FileWrite(fh, "intSpreadGE"); + FileWrite(fh, IntegerToString(sets.intSpreadGE)); + FileWrite(fh, "intSpreadLE"); + FileWrite(fh, IntegerToString(sets.intSpreadLE)); + FileWrite(fh, "doubleDailyProfitLossUnitsGE"); + FileWrite(fh, DoubleToString(sets.doubleDailyProfitLossUnitsGE)); + FileWrite(fh, "doubleDailyProfitLossUnitsLE"); + FileWrite(fh, DoubleToString(sets.doubleDailyProfitLossUnitsLE)); + FileWrite(fh, "intDailyProfitLossPointsGE"); + FileWrite(fh, IntegerToString(sets.intDailyProfitLossPointsGE)); + FileWrite(fh, "intDailyProfitLossPointsLE"); + FileWrite(fh, IntegerToString(sets.intDailyProfitLossPointsLE)); + FileWrite(fh, "doubleDailyProfitLossPercGE"); + FileWrite(fh, DoubleToString(sets.doubleDailyProfitLossPercGE)); + FileWrite(fh, "doubleDailyProfitLossPercLE"); + FileWrite(fh, DoubleToString(sets.doubleDailyProfitLossPercLE)); FileWrite(fh, "ClosePos"); FileWrite(fh, IntegerToString(sets.ClosePos)); FileWrite(fh, "doubleClosePercentage"); @@ -2480,9 +2950,19 @@ bool CAccountProtector::SaveSettingsOnDisk() FileWrite(fh, "TimerDayOfWeek"); FileWrite(fh, IntegerToString(sets.TimerDayOfWeek)); + // These are not part of settings but are panel-related input parameters. + // When the EA is reloaded due to its input parameters change, these should be compared to the new values. + // If the value is changed, it should be updated in the panel too. + // Is indicator reloading due to the input parameters change? + if (GlobalVariableGet("AP-" + IntegerToString(ChartID()) + "-Parameters") > 0) + { + FileWrite(fh, "Parameter_Instruments"); + FileWrite(fh, Instruments); + } + FileClose(fh); - return(true); + return true; } // Supplementary function to load changes to relevant fields in tabs: @@ -2505,12 +2985,12 @@ void CAccountProtector::RefreshConditions(const bool SettingsCheckBoxValue, cons // Loads settings from a file to the panel. bool CAccountProtector::LoadSettingsFromDisk() { - if (!FileIsExist(m_FileName)) return(false); + if (!FileIsExist(m_FileName)) return false; int fh = FileOpen(m_FileName, FILE_TXT | FILE_READ); if (fh == INVALID_HANDLE) { Logging("Failed to open file for reading: " + m_FileName + ". Error: " + IntegerToString(GetLastError())); - return(false); + return false; } while (!FileIsEnding(fh)) @@ -2567,6 +3047,12 @@ bool CAccountProtector::LoadSettingsFromDisk() sets.boolExcludeMagics = (bool)StringToInteger(var_content); else if (var_name == "intInstrumentFilter") sets.intInstrumentFilter = (int)StringToInteger(var_content); + else if (var_name == "Instruments") + sets.Instruments = var_content; + else if (var_name == "boolIgnoreLossTrades") + sets.boolIgnoreLossTrades = (bool)StringToInteger(var_content); + else if (var_name == "boolIgnoreProfitTrades") + sets.boolIgnoreProfitTrades = (bool)StringToInteger(var_content); else if (var_name == "boolLossPerBalance") { if (!DisableFloatLossRisePerc) sets.boolLossPerBalance = (bool)StringToInteger(var_content); @@ -2587,15 +3073,15 @@ bool CAccountProtector::LoadSettingsFromDisk() if (!DisableFloatLossFallCurr) sets.boolLossQuanUnitsReverse = (bool)StringToInteger(var_content); else sets.boolLossQuanUnitsReverse = false; } - else if (var_name == "boolLossPips") + else if (var_name == "boolLossPoints") { - if (!DisableFloatLossRisePips) sets.boolLossPips = (bool)StringToInteger(var_content); - else sets.boolLossPips = false; + if (!DisableFloatLossRisePoints) sets.boolLossPoints = (bool)StringToInteger(var_content); + else sets.boolLossPoints = false; } - else if (var_name == "boolLossPipsReverse") + else if (var_name == "boolLossPointsReverse") { - if (!DisableFloatLossFallPips) sets.boolLossPipsReverse = (bool)StringToInteger(var_content); - else sets.boolLossPipsReverse = false; + if (!DisableFloatLossFallPoints) sets.boolLossPointsReverse = (bool)StringToInteger(var_content); + else sets.boolLossPointsReverse = false; } else if (var_name == "boolProfPerBalance") { @@ -2617,15 +3103,15 @@ bool CAccountProtector::LoadSettingsFromDisk() if (!DisableFloatProfitFallCurr) sets.boolProfQuanUnitsReverse = (bool)StringToInteger(var_content); else sets.boolProfQuanUnitsReverse = false; } - else if (var_name == "boolProfPips") + else if (var_name == "boolProfPoints") { - if (!DisableFloatProfitRisePips) sets.boolProfPips = (bool)StringToInteger(var_content); - else sets.boolProfPips = false; + if (!DisableFloatProfitRisePoints) sets.boolProfPoints = (bool)StringToInteger(var_content); + else sets.boolProfPoints = false; } - else if (var_name == "boolProfPipsReverse") + else if (var_name == "boolProfPointsReverse") { - if (!DisableFloatProfitFallPips) sets.boolProfPipsReverse = (bool)StringToInteger(var_content); - else sets.boolProfPipsReverse = false; + if (!DisableFloatProfitFallPoints) sets.boolProfPointsReverse = (bool)StringToInteger(var_content); + else sets.boolProfPointsReverse = false; } else if (var_name == "boolEquityLessUnits") sets.boolEquityLessUnits = (bool)StringToInteger(var_content); @@ -2663,6 +3149,56 @@ bool CAccountProtector::LoadSettingsFromDisk() if (!DisableCurrentPriceLE) sets.boolPriceLE = (bool)StringToInteger(var_content); else sets.boolPriceLE = false; } + else if (var_name == "boolMarginLevelGE") + { + if (!DisableMarginLevelGE) sets.boolMarginLevelGE = (bool)StringToInteger(var_content); + else sets.boolMarginLevelGE = false; + } + else if (var_name == "boolMarginLevelLE") + { + if (!DisableMarginLevelLE) sets.boolMarginLevelLE = (bool)StringToInteger(var_content); + else sets.boolMarginLevelLE = false; + } + else if (var_name == "boolSpreadGE") + { + if (!DisableSpreadGE) sets.boolSpreadGE = (bool)StringToInteger(var_content); + else sets.boolSpreadGE = false; + } + else if (var_name == "boolSpreadLE") + { + if (!DisableSpreadLE) sets.boolSpreadLE = (bool)StringToInteger(var_content); + else sets.boolSpreadLE = false; + } + else if (var_name == "boolDailyProfitLossUnitsGE") + { + if (!DisableDailyProfitLossUnitsGE) sets.boolDailyProfitLossUnitsGE = (bool)StringToInteger(var_content); + else sets.boolDailyProfitLossUnitsGE = false; + } + else if (var_name == "boolDailyProfitLossUnitsLE") + { + if (!DisableDailyProfitLossUnitsLE) sets.boolDailyProfitLossUnitsLE = (bool)StringToInteger(var_content); + else sets.boolDailyProfitLossUnitsLE = false; + } + else if (var_name == "boolDailyProfitLossPointsGE") + { + if (!DisableDailyProfitLossPointsGE) sets.boolDailyProfitLossPointsGE = (bool)StringToInteger(var_content); + else sets.boolDailyProfitLossPointsGE = false; + } + else if (var_name == "boolDailyProfitLossPointsLE") + { + if (!DisableDailyProfitLossPointsLE) sets.boolDailyProfitLossPointsLE = (bool)StringToInteger(var_content); + else sets.boolDailyProfitLossPointsLE = false; + } + else if (var_name == "boolDailyProfitLossPercGE") + { + if (!DisableDailyProfitLossPercGE) sets.boolDailyProfitLossPercGE = (bool)StringToInteger(var_content); + else sets.boolDailyProfitLossPercGE = false; + } + else if (var_name == "boolDailyProfitLossPercLE") + { + if (!DisableDailyProfitLossPercLE) sets.boolDailyProfitLossPercLE = (bool)StringToInteger(var_content); + else sets.boolDailyProfitLossPercLE = false; + } else if (var_name == "doubleLossPerBalance") { if (!DisableFloatLossRisePerc) sets.doubleLossPerBalance = StringToDouble(var_content); @@ -2683,15 +3219,15 @@ bool CAccountProtector::LoadSettingsFromDisk() if (!DisableFloatLossFallCurr) sets.doubleLossQuanUnitsReverse = StringToDouble(var_content); else sets.doubleLossQuanUnitsReverse = 0; } - else if (var_name == "intLossPips") + else if (var_name == "intLossPoints") { - if (!DisableFloatLossRisePips) sets.intLossPips = (int)StringToInteger(var_content); - else sets.intLossPips = 0; + if (!DisableFloatLossRisePoints) sets.intLossPoints = (int)StringToInteger(var_content); + else sets.intLossPoints = 0; } - else if (var_name == "intLossPipsReverse") + else if (var_name == "intLossPointsReverse") { - if (!DisableFloatLossFallPips) sets.intLossPipsReverse = (int)StringToInteger(var_content); - else sets.intLossPipsReverse = 0; + if (!DisableFloatLossFallPoints) sets.intLossPointsReverse = (int)StringToInteger(var_content); + else sets.intLossPointsReverse = 0; } else if (var_name == "doubleProfPerBalance") { @@ -2713,15 +3249,15 @@ bool CAccountProtector::LoadSettingsFromDisk() if (!DisableFloatProfitFallCurr) sets.doubleProfQuanUnitsReverse = StringToDouble(var_content); else sets.doubleProfQuanUnitsReverse = 0; } - else if (var_name == "intProfPips") + else if (var_name == "intProfPoints") { - if (!DisableFloatProfitRisePips) sets.intProfPips = (int)StringToInteger(var_content); - else sets.intProfPips = 0; + if (!DisableFloatProfitRisePoints) sets.intProfPoints = (int)StringToInteger(var_content); + else sets.intProfPoints = 0; } - else if (var_name == "intProfPipsReverse") + else if (var_name == "intProfPointsReverse") { - if (!DisableFloatProfitFallPips) sets.intProfPipsReverse = (int)StringToInteger(var_content); - else sets.intProfPipsReverse = 0; + if (!DisableFloatProfitFallPoints) sets.intProfPointsReverse = (int)StringToInteger(var_content); + else sets.intProfPointsReverse = 0; } else if (var_name == "doubleEquityLessUnits") sets.doubleEquityLessUnits = StringToDouble(var_content); @@ -2759,6 +3295,56 @@ bool CAccountProtector::LoadSettingsFromDisk() if (!DisableCurrentPriceLE) sets.doublePriceLE = StringToDouble(var_content); else sets.doublePriceLE = 0; } + else if (var_name == "doubleMarginLevelGE") + { + if (!DisableMarginLevelGE) sets.doubleMarginLevelGE = StringToDouble(var_content); + else sets.doubleMarginLevelGE = 0; + } + else if (var_name == "doubleMarginLevelLE") + { + if (!DisableMarginLevelLE) sets.doubleMarginLevelLE = StringToDouble(var_content); + else sets.doubleMarginLevelLE = 0; + } + else if (var_name == "intSpreadGE") + { + if (!DisableSpreadGE) sets.intSpreadGE = (int)StringToInteger(var_content); + else sets.intSpreadGE = 0; + } + else if (var_name == "intSpreadLE") + { + if (!DisableSpreadLE) sets.intSpreadLE = (int)StringToInteger(var_content); + else sets.intSpreadLE = 0; + } + else if (var_name == "doubleDailyProfitLossUnitsGE") + { + if (!DisableDailyProfitLossUnitsGE) sets.doubleDailyProfitLossUnitsGE = StringToDouble(var_content); + else sets.doubleDailyProfitLossUnitsGE = 0; + } + else if (var_name == "doubleDailyProfitLossUnitsLE") + { + if (!DisableDailyProfitLossUnitsLE) sets.doubleDailyProfitLossUnitsLE = StringToDouble(var_content); + else sets.doubleDailyProfitLossUnitsLE = 0; + } + else if (var_name == "intDailyProfitLossPointsGE") + { + if (!DisableDailyProfitLossPointsGE) sets.intDailyProfitLossPointsGE = (int)StringToInteger(var_content); + else sets.intDailyProfitLossPointsGE = 0; + } + else if (var_name == "intDailyProfitLossPointsLE") + { + if (!DisableDailyProfitLossPointsLE) sets.intDailyProfitLossPointsLE = (int)StringToInteger(var_content); + else sets.intDailyProfitLossPointsLE = 0; + } + else if (var_name == "doubleDailyProfitLossPercGE") + { + if (!DisableDailyProfitLossPercGE) sets.doubleDailyProfitLossPercGE = StringToDouble(var_content); + else sets.doubleDailyProfitLossPercGE = 0; + } + else if (var_name == "doubleDailyProfitLossPercLE") + { + if (!DisableDailyProfitLossPercLE) sets.doubleDailyProfitLossPercLE = StringToDouble(var_content); + else sets.doubleDailyProfitLossPercLE = 0; + } else if (var_name == "ClosePos") sets.ClosePos = (bool)StringToInteger(var_content); else if (var_name == "doubleClosePercentage") @@ -2787,26 +3373,41 @@ bool CAccountProtector::LoadSettingsFromDisk() sets.TriggeredTime = var_content; else if (var_name == "TimerDayOfWeek") sets.TimerDayOfWeek = (Day_of_Week)StringToInteger(var_content); + + // Is the EA reloading due to the input parameters change? + if (GlobalVariableGet("AP-" + IntegerToString(ChartID()) + "-Parameters") > 0) + { + // These are not part of settings but are panel-related input parameters. + // When the EA is reloaded due to its input parameters change, these should be compared to the new values. + // If the value is changed, it should be updated in the panel too. + if (var_name == "Parameter_Instruments") + { + if (var_content != Instruments) sets.Instruments = Instruments; + } + } } FileClose(fh); -// Refreshing panel controls. + // Refreshing panel controls. RefreshPanelControls(); - return(true); + // Is the EA reloading due to the input parameters change? Delete the flag variable. + if (GlobalVariableGet("AP-" + IntegerToString(ChartID()) + "-Parameters") > 0) GlobalVariableDel("AP-" + IntegerToString(ChartID()) + "-Parameters"); + + return true; } // Deletes the settings file. bool CAccountProtector::DeleteSettingsFile() { - if (!FileIsExist(m_FileName)) return(false); + if (!FileIsExist(m_FileName)) return false; if (!FileDelete(m_FileName)) { Logging("Failed to delete file: " + m_FileName + ". Error: " + IntegerToString(GetLastError())); - return(false); + return false; } - return(true); + return true; } //+------------------------------------------------------------------+ @@ -2814,7 +3415,7 @@ bool CAccountProtector::DeleteSettingsFile() //+------------------------------------------------------------------+ void CAccountProtector::HideShowMaximize(bool max = true) { -// Remember the panel's location. + // Remember the panel's location. remember_left = Left(); remember_top = Top(); @@ -2863,24 +3464,27 @@ void CAccountProtector::Check_Status() bool CAccountProtector::No_Condition() { if ((!sets.UseTimer) && - (!sets.boolProfPerBalance) && (!sets.boolProfQuanUnits) && (!sets.boolProfPips) && - (!sets.boolLossPerBalance) && (!sets.boolLossQuanUnits) && (!sets.boolLossPips) && - (!sets.boolProfPerBalanceReverse) && (!sets.boolProfQuanUnitsReverse) && (!sets.boolProfPipsReverse) && - (!sets.boolLossPerBalanceReverse) && (!sets.boolLossQuanUnitsReverse) && (!sets.boolLossPipsReverse) && + (!sets.boolProfPerBalance) && (!sets.boolProfQuanUnits) && (!sets.boolProfPoints) && + (!sets.boolLossPerBalance) && (!sets.boolLossQuanUnits) && (!sets.boolLossPoints) && + (!sets.boolProfPerBalanceReverse) && (!sets.boolProfQuanUnitsReverse) && (!sets.boolProfPointsReverse) && + (!sets.boolLossPerBalanceReverse) && (!sets.boolLossQuanUnitsReverse) && (!sets.boolLossPointsReverse) && (!sets.boolEquityLessUnits) && (!sets.boolEquityGrUnits) && (!sets.boolEquityLessPerSnap) && (!sets.boolEquityGrPerSnap) && (!sets.boolEquityMinusSnapshot) && (!sets.boolSnapshotMinusEquity) && (!sets.boolMarginLessUnits) && (!sets.boolMarginGrUnits) && (!sets.boolMarginLessPerSnap) && (!sets.boolMarginGrPerSnap) && - (!sets.boolPriceGE) && (!sets.boolPriceLE) - ) return(true); + (!sets.boolPriceGE) && (!sets.boolPriceLE) && + (!sets.boolMarginLevelGE) && (!sets.boolMarginLevelLE) && + (!sets.boolSpreadGE) && (!sets.boolSpreadLE) && + (!sets.boolDailyProfitLossUnitsGE) && (!sets.boolDailyProfitLossUnitsLE) && (!sets.boolDailyProfitLossPointsGE) && (!sets.boolDailyProfitLossPointsLE) && (!sets.boolDailyProfitLossPercGE) && (!sets.boolDailyProfitLossPercLE) + ) return true; - return(false); + return false; } // Checks if there is no action set. bool CAccountProtector::No_Action() { - if ((!sets.ClosePos) && (!sets.DeletePend) && (!sets.DisAuto) && (!sets.SendMails) && (!sets.SendNotif) && (!sets.ClosePlatform) && (!sets.EnableAuto) && (!sets.RecaptureSnapshots)) return(true); + if ((!sets.ClosePos) && (!sets.DeletePend) && (!sets.DisAuto) && (!sets.SendMails) && (!sets.SendNotif) && (!sets.ClosePlatform) && (!sets.EnableAuto) && (!sets.RecaptureSnapshots)) return true; - return(false); + return false; } // Calculates TimeLeft (to trigger actions "Timeout by Timer"). @@ -2960,11 +3564,11 @@ string CAccountProtector::NewTime() mod_time_60 = (int)MathMod(time, 60); -// Leading zero for hours. + // Leading zero for hours. if ((time - mod_time_60) / 60 < 10) hour = "0" + DoubleToString((time - mod_time_60) / 60, 0); else hour = DoubleToString((time - mod_time_60) / 60, 0); -// Leading zero for minutes + // Leading zero for minutes if (mod_time_60 < 10) minute = "0" + DoubleToString(mod_time_60, 0); else minute = DoubleToString(mod_time_60, 0); @@ -2972,29 +3576,55 @@ string CAccountProtector::NewTime() } // Returns true if order should be filtered out based on its symbol and filter settings. -bool CAccountProtector::CheckFilterSymbol(const string order_symbol) +bool CAccountProtector::CheckFilterSymbol(string order_symbol) { -// Skip an order if its Symbol is not the current one, and instrument filter is set to 'Use only current trading instrument'. - if ((order_symbol != Symbol()) && (sets.intInstrumentFilter == 1)) return(true); -// Skip an order if its Symbol is the same as the current one, and instrument filter is set to 'Exclude current trading instrument'. - if ((order_symbol == Symbol()) && (sets.intInstrumentFilter == 2)) return(true); - - return(false); + // Skip an order if instrument filter is set to 'Use only current trading instrument' and the Symbol is not the chart's current one. + if (sets.intInstrumentFilter == 1) + { + if (order_symbol != Symbol()) return true; + } + // Skip an order if instrument filter is set to 'Exclude current trading instrument' and the Symbol is the same as the chart's current one. + else if (sets.intInstrumentFilter == 2) + { + if (order_symbol == Symbol()) return true; + } + { + StringToLower(order_symbol); + // Skip if using an "Include" list and the symbol IS NOT found among the listed ones. + if (sets.intInstrumentFilter == 3) + { + for (int i = 0; i < instruments_array_counter; i++) + { + if (order_symbol == Instruments_array[i]) return false; // Pass. + } + return true; // Didn't pass. + } + // Skip if using an "Exclude" list and the symbol IS found among the listed ones. + else if (sets.intInstrumentFilter == 4) + { + for (int i = 0; i < instruments_array_counter; i++) + { + if (order_symbol == Instruments_array[i]) return true; // Didn't pass. + } + return false; // Pass. + } + } + return false; } // Returns true if order should be filtered out based on its comment and filter settings. bool CAccountProtector::CheckFilterComment(const string order_comment) { -// Skip an order if its commentary is not the same as filter value, and list view is set to "Equals". - if ((order_comment != sets.OrderCommentary) && (sets.intOrderCommentaryCondition == 1)) return(true); -// Skip an order if its commentary is the same as filter value, and list view is set to "Not equal". - if ((order_comment == sets.OrderCommentary) && (sets.intOrderCommentaryCondition == 3)) return(true); -// Skip an order if the filter value was given but was not found in order commentary, and list view is set to "Contains". - if ((StringCompare(sets.OrderCommentary, "") != 0) && (StringFind(order_comment, sets.OrderCommentary) == -1) && (sets.intOrderCommentaryCondition == 0)) return(true); -// Skip an order if the filter value was given and was found in order commentary, and list view is set to "Does not contain". - if ((StringCompare(sets.OrderCommentary, "") != 0) && (StringFind(order_comment, sets.OrderCommentary) >= 0) && (sets.intOrderCommentaryCondition == 2)) return(true); + // Skip an order if its commentary is not the same as filter value, and list view is set to "Equals". + if ((order_comment != sets.OrderCommentary) && (sets.intOrderCommentaryCondition == 1)) return true; + // Skip an order if its commentary is the same as filter value, and list view is set to "Not equal". + if ((order_comment == sets.OrderCommentary) && (sets.intOrderCommentaryCondition == 3)) return true; + // Skip an order if the filter value was given but was not found in order commentary, and list view is set to "Contains". + if ((StringCompare(sets.OrderCommentary, "") != 0) && (StringFind(order_comment, sets.OrderCommentary) == -1) && (sets.intOrderCommentaryCondition == 0)) return true; + // Skip an order if the filter value was given and was found in order commentary, and list view is set to "Does not contain". + if ((StringCompare(sets.OrderCommentary, "") != 0) && (StringFind(order_comment, sets.OrderCommentary) >= 0) && (sets.intOrderCommentaryCondition == 2)) return true; - return(false); + return false; } // Returns true if order should be filtered out based on its magic number and filter settings. j - MagicNumbers_array cycle iteration. @@ -3003,19 +3633,27 @@ bool CAccountProtector::CheckFilterMagic(const int magic, const int j) if (j == -1) { // There are some Magic numbers given but we are in a general cycle. - if (magic_array_counter > 0) return(true); + if (magic_array_counter > 0) return true; // No Magic numbers given but "Exclude" option is checked, and we are in a general cycle. - if ((magic == 0) && (sets.boolExcludeMagics)) return(true); + if ((magic == 0) && (sets.boolExcludeMagics)) return true; } else if (j >= 0) { // Skip order if its magic number is not in the array, and "Exclude" option is turned off. - if ((magic != MagicNumbers_array[j]) && (!sets.boolExcludeMagics)) return(true); + if ((magic != MagicNumbers_array[j]) && (!sets.boolExcludeMagics)) return true; // Skip order if its magic number is in the array, and "Exclude" option is turned on. - if ((magic == MagicNumbers_array[j]) && (sets.boolExcludeMagics)) return(true); + if ((magic == MagicNumbers_array[j]) && (sets.boolExcludeMagics)) return true; } - return(false); + return false; +} + +// Returns true if order should be filtered out based on its profit and filter settings. +inline bool CAccountProtector::CheckFilterLossProfit(const double order_profit) +{ + if ((sets.boolIgnoreLossTrades) && (order_profit < 0)) return true; + if ((sets.boolIgnoreProfitTrades) && (order_profit > 0)) return true; + return false; } // Closes all orders or deletes all pending orders. @@ -3031,8 +3669,8 @@ void CAccountProtector::Close_All_Positions() // Check condition to know whether and how to sort PositionsByProfit. // Switching sorting modes because the array is traversed backwards - from total - 1 to 0. - if ((TriggeredCondition == Floating_loss_rises_to_perecentage) || (TriggeredCondition == Floating_loss_rises_to_currency_units) || (TriggeredCondition == Floating_loss_rises_to_pips)) ArraySort(PositionsByProfit, WHOLE_ARRAY, 0, MODE_DESCEND); - else if ((TriggeredCondition == Floating_profit_rises_to_perecentage) || (TriggeredCondition == Floating_profit_rises_to_currency_units) || (TriggeredCondition == Floating_profit_rises_to_pips)) ArraySort(PositionsByProfit, WHOLE_ARRAY, 0, MODE_ASCEND); + if ((TriggeredCondition == Floating_loss_rises_to_perecentage) || (TriggeredCondition == Floating_loss_rises_to_currency_units) || (TriggeredCondition == Floating_loss_rises_to_points)) ArraySort(PositionsByProfit, WHOLE_ARRAY, 0, MODE_DESCEND); + else if ((TriggeredCondition == Floating_profit_rises_to_perecentage) || (TriggeredCondition == Floating_profit_rises_to_currency_units) || (TriggeredCondition == Floating_profit_rises_to_points)) ArraySort(PositionsByProfit, WHOLE_ARRAY, 0, MODE_ASCEND); // Otherwise no sorting needed. int total = ArrayRange(PositionsByProfit, 0); // We already have an array with all tickets. @@ -3188,6 +3826,7 @@ void CAccountProtector::Delete_All_Pending_Orders() Logging("Account Protector: " + OrderSymbol() + " Pending order #" + IntegerToString(OrderTicket()) + "; Lotsize = " + DoubleToString(OrderLots(), 2) + ", OpenPrice = " + DoubleToString(OrderOpenPrice(), (int)MarketInfo(OrderSymbol(), MODE_DIGITS)) + ", SL = " + DoubleToString(OrderStopLoss(), (int)MarketInfo(OrderSymbol(), MODE_DIGITS)) + ", TP = " + DoubleToString(OrderTakeProfit(), (int)MarketInfo(OrderSymbol(), MODE_DIGITS)) + " was deleted."); QuantityDeletedPendingOrders++; } + break; // Order already processed - no point to process this order with other magic numbers. } } } @@ -3222,8 +3861,8 @@ void CAccountProtector::Delete_All_Pending_Orders() if ((OrderType() == OP_BUYLIMIT) || (OrderType() == OP_SELLLIMIT) || (OrderType() == OP_BUYSTOP) || (OrderType() == OP_SELLSTOP)) { AreAllOrdersEliminated = false; - break; } + break; // Order already processed - no point to process this order with other magic numbers. } if (!AreAllOrdersEliminated) break; } @@ -3332,6 +3971,7 @@ void CAccountProtector::Trailing() else if (SymbolInfoInteger(OrderSymbol(), SYMBOL_TRADE_MODE) == SYMBOL_TRADE_MODE_DISABLED) continue; else { + if (CheckFilterLossProfit(OrderProfit())) continue; if (CheckFilterSymbol(OrderSymbol())) continue; if (CheckFilterComment(OrderComment())) continue; // Starting from -1 index to check for orders irrespective of their Magic numbers. @@ -3370,12 +4010,13 @@ void CAccountProtector::Trailing() } } } + break; // Order already processed - no point to process this order with other magic numbers. } } } } -// Moves stop-loss to breakeven or breakeven with extra pips of profit. +// Moves stop-loss to breakeven or breakeven with extra points of profit. void CAccountProtector::MoveToBreakEven() { double SL; @@ -3389,6 +4030,7 @@ void CAccountProtector::MoveToBreakEven() else if (SymbolInfoInteger(OrderSymbol(), SYMBOL_TRADE_MODE) == SYMBOL_TRADE_MODE_DISABLED) continue; else { + if (CheckFilterLossProfit(OrderProfit())) continue; if (CheckFilterSymbol(OrderSymbol())) continue; if (CheckFilterComment(OrderComment())) continue; // Starting from -1 index to check for orders irrespective of their Magic numbers. @@ -3400,7 +4042,7 @@ void CAccountProtector::MoveToBreakEven() { if (MarketInfo(OrderSymbol(), MODE_BID) - OrderOpenPrice() >= sets.intBreakEven * MarketInfo(OrderSymbol(), MODE_POINT)) { - if (sets.intBreakEvenExtra == 0) SL = OrderOpenPrice(); + if ((!sets.boolBreakEvenExtra) || (sets.intBreakEvenExtra == 0)) SL = OrderOpenPrice(); else SL = OrderOpenPrice() + sets.intBreakEvenExtra * MarketInfo(OrderSymbol(), MODE_POINT); if (SL > OrderStopLoss()) { @@ -3415,7 +4057,7 @@ void CAccountProtector::MoveToBreakEven() { if (OrderOpenPrice() - MarketInfo(OrderSymbol(), MODE_ASK) >= sets.intBreakEven * MarketInfo(OrderSymbol(), MODE_POINT)) { - if (sets.intBreakEvenExtra == 0) SL = OrderOpenPrice(); + if ((!sets.boolBreakEvenExtra) || (sets.intBreakEvenExtra == 0)) SL = OrderOpenPrice(); else SL = OrderOpenPrice() - sets.intBreakEvenExtra * MarketInfo(OrderSymbol(), MODE_POINT); if ((SL < OrderStopLoss()) || (OrderStopLoss() == 0)) { @@ -3426,6 +4068,7 @@ void CAccountProtector::MoveToBreakEven() } } } + break; // Order already processed - no point to process this order with other magic numbers. } } } @@ -3439,7 +4082,7 @@ void CAccountProtector::EquityTrailing() double AE = AccountInfoDouble(ACCOUNT_EQUITY) + AdditionalFunds; -// If equity stop-loss has been hit - close all positions. + // If equity stop-loss has been hit - close all positions. if ((AE <= sets.doubleCurrentEquityStopLoss) && (sets.doubleCurrentEquityStopLoss != 0)) { string AdditionalFunds_Asterisk = ""; @@ -3456,7 +4099,7 @@ void CAccountProtector::EquityTrailing() SaveSettingsOnDisk(); MoveAndResize(); } -// If equity stop-loss should be trailed - update the stop-loss. + // If equity stop-loss should be trailed - update the stop-loss. else if ((AE - sets.doubleEquityTrailingStop > sets.doubleCurrentEquityStopLoss) || (sets.doubleCurrentEquityStopLoss == 0)) { double old_value = sets.doubleCurrentEquityStopLoss; @@ -3498,18 +4141,21 @@ void CAccountProtector::Logging_Current_Settings() Logging("sets.MagicNumbers = " + sets.MagicNumbers); Logging("sets.boolExcludeMagics = " + (string)sets.boolExcludeMagics); Logging("sets.intInstrumentFilter = " + IntegerToString(sets.intInstrumentFilter)); + Logging("sets.Instruments = " + sets.Instruments); + Logging("sets.boolIgnoreLossTrades = " + (string)sets.boolIgnoreLossTrades); + Logging("sets.boolIgnoreProfitTrades = " + (string)sets.boolIgnoreProfitTrades); Logging("sets.boolLossPerBalance = " + IntegerToString(sets.boolLossPerBalance)); Logging("sets.boolLossPerBalancReversee = " + IntegerToString(sets.boolLossPerBalanceReverse)); Logging("sets.boolLossQuanUnits = " + IntegerToString(sets.boolLossQuanUnits)); Logging("sets.boolLossQuanUnitsReverse = " + IntegerToString(sets.boolLossQuanUnitsReverse)); - Logging("sets.boolLossPips = " + IntegerToString(sets.boolLossPips)); - Logging("sets.boolLossPipsReverse = " + IntegerToString(sets.boolLossPipsReverse)); + Logging("sets.boolLossPoints = " + IntegerToString(sets.boolLossPoints)); + Logging("sets.boolLossPointsReverse = " + IntegerToString(sets.boolLossPointsReverse)); Logging("sets.boolProfPerBalance = " + IntegerToString(sets.boolProfPerBalance)); Logging("sets.boolProfPerBalanceReverse = " + IntegerToString(sets.boolProfPerBalanceReverse)); Logging("sets.boolProfQuanUnits = " + IntegerToString(sets.boolProfQuanUnits)); Logging("sets.boolProfQuanUnitsReverse = " + IntegerToString(sets.boolProfQuanUnitsReverse)); - Logging("sets.boolProfPips = " + IntegerToString(sets.boolProfPips)); - Logging("sets.boolProfPipsReverse = " + IntegerToString(sets.boolProfPipsReverse)); + Logging("sets.boolProfPoints = " + IntegerToString(sets.boolProfPoints)); + Logging("sets.boolProfPointsReverse = " + IntegerToString(sets.boolProfPointsReverse)); Logging("sets.boolEquityLessUnits = " + IntegerToString(sets.boolEquityLessUnits)); Logging("sets.boolEquityGrUnits = " + IntegerToString(sets.boolEquityGrUnits)); Logging("sets.boolEquityLessPerSnap = " + IntegerToString(sets.boolEquityLessPerSnap)); @@ -3522,18 +4168,28 @@ void CAccountProtector::Logging_Current_Settings() Logging("sets.boolMarginGrPerSnap = " + IntegerToString(sets.boolMarginGrPerSnap)); Logging("sets.boolPriceGE = " + IntegerToString(sets.boolPriceGE)); Logging("sets.boolPriceLE = " + IntegerToString(sets.boolPriceLE)); + Logging("sets.boolMarginLevelGE = " + IntegerToString(sets.boolMarginLevelGE)); + Logging("sets.boolMarginLevelLE = " + IntegerToString(sets.boolMarginLevelLE)); + Logging("sets.boolSpreadGE = " + IntegerToString(sets.boolSpreadGE)); + Logging("sets.boolSpreadLE = " + IntegerToString(sets.boolSpreadLE)); + Logging("sets.boolDailyProfitLossUnitsGE = " + IntegerToString(sets.boolDailyProfitLossUnitsGE)); + Logging("sets.boolDailyProfitLossUnitsLE = " + IntegerToString(sets.boolDailyProfitLossUnitsLE)); + Logging("sets.boolDailyProfitLossPointsGE = " + IntegerToString(sets.boolDailyProfitLossPointsGE)); + Logging("sets.boolDailyProfitLossPointsLE = " + IntegerToString(sets.boolDailyProfitLossPointsLE)); + Logging("sets.boolDailyProfitLossPercGE = " + IntegerToString(sets.boolDailyProfitLossPercGE)); + Logging("sets.boolDailyProfitLossPercLE = " + IntegerToString(sets.boolDailyProfitLossPercLE)); Logging("sets.doubleLossPerBalance = " + DoubleToString(sets.doubleLossPerBalance, 2)); Logging("sets.doubleLossPerBalanceReverse = " + DoubleToString(sets.doubleLossPerBalanceReverse, 2)); Logging("sets.doubleLossQuanUnits = " + DoubleToString(sets.doubleLossQuanUnits, 2)); Logging("sets.doubleLossQuanUnitsReverse = " + DoubleToString(sets.doubleLossQuanUnitsReverse, 2)); - Logging("sets.intLossPips = " + IntegerToString(sets.intLossPips)); - Logging("sets.intLossPipsReverse = " + IntegerToString(sets.intLossPipsReverse)); + Logging("sets.intLossPoints = " + IntegerToString(sets.intLossPoints)); + Logging("sets.intLossPointsReverse = " + IntegerToString(sets.intLossPointsReverse)); Logging("sets.doubleProfPerBalance = " + DoubleToString(sets.doubleProfPerBalance, 2)); Logging("sets.doubleProfPerBalanceReverse = " + DoubleToString(sets.doubleProfPerBalanceReverse, 2)); Logging("sets.doubleProfQuanUnits = " + DoubleToString(sets.doubleProfQuanUnits, 2)); Logging("sets.doubleProfQuanUnitsReverse = " + DoubleToString(sets.doubleProfQuanUnitsReverse, 2)); - Logging("sets.intProfPips = " + IntegerToString(sets.intProfPips)); - Logging("sets.intProfPipsReverse = " + IntegerToString(sets.intProfPipsReverse)); + Logging("sets.intProfPoints = " + IntegerToString(sets.intProfPoints)); + Logging("sets.intProfPointsReverse = " + IntegerToString(sets.intProfPointsReverse)); Logging("sets.doubleEquityLessUnits = " + DoubleToString(sets.doubleEquityLessUnits, 2)); Logging("sets.doubleEquityGrUnits = " + DoubleToString(sets.doubleEquityGrUnits, 2)); Logging("sets.doubleEquityLessPerSnap = " + DoubleToString(sets.doubleEquityLessPerSnap, 2)); @@ -3546,6 +4202,16 @@ void CAccountProtector::Logging_Current_Settings() Logging("sets.doubleMarginGrPerSnap = " + DoubleToString(sets.doubleMarginGrPerSnap, 2)); Logging("sets.doublePriceGE = " + DoubleToString(sets.doublePriceGE, _Digits)); Logging("sets.doublePriceLE = " + DoubleToString(sets.doublePriceLE, _Digits)); + Logging("sets.doubleMarginLevelGE = " + DoubleToString(sets.doubleMarginLevelGE, 2) + "%"); + Logging("sets.doubleMarginLevelLE = " + DoubleToString(sets.doubleMarginLevelLE, 2) + "%"); + Logging("sets.intSpreadGE = " + IntegerToString(sets.intSpreadGE)); + Logging("sets.intSpreadLE = " + IntegerToString(sets.intSpreadLE)); + Logging("sets.doubleDailyProfitLossUnitsGE = " + DoubleToString(sets.doubleDailyProfitLossUnitsGE, 2)); + Logging("sets.doubleDailyProfitLossUnitsLE = " + DoubleToString(sets.doubleDailyProfitLossUnitsLE, 2)); + Logging("sets.intDailyProfitLossPointsGE = " + IntegerToString(sets.intDailyProfitLossPointsGE)); + Logging("sets.intDailyProfitLossPointsLE = " + IntegerToString(sets.intDailyProfitLossPointsLE)); + Logging("sets.doubleDailyProfitLossPercGE = " + DoubleToString(sets.doubleDailyProfitLossPercGE, 2)); + Logging("sets.doubleDailyProfitLossPercLE = " + DoubleToString(sets.doubleDailyProfitLossPercLE, 2)); Logging("sets.ClosePos = " + IntegerToString(sets.ClosePos)); Logging("sets.doubleClosePerecentage = " + DoubleToString(sets.doubleClosePercentage, 2) + "%"); Logging("sets.CloseWhichPositions = " + EnumToString(sets.CloseWhichPositions)); @@ -3574,6 +4240,7 @@ void CAccountProtector::Logging_Condition_Is_Met() if (!OrderSelect(i, SELECT_BY_POS)) Logging("Account Protector: OrderSelect failed " + IntegerToString(GetLastError())); else { + if (CheckFilterLossProfit(OrderProfit())) continue; if (CheckFilterSymbol(OrderSymbol())) continue; if (CheckFilterComment(OrderComment())) continue; // Starting from -1 index to check for orders irrespective of their Magic numbers. @@ -3592,6 +4259,7 @@ void CAccountProtector::Logging_Condition_Is_Met() TotalVolume += OrderLots(); } else if ((OrderType() == OP_BUYSTOP) || (OrderType() == OP_SELLSTOP) || (OrderType() == OP_BUYLIMIT) || (OrderType() == OP_SELLLIMIT)) pending++; + break; // Order already processed - no point to process this order with other magic numbers. } } @@ -3673,20 +4341,25 @@ void CAccountProtector::CheckOneCondition(T &SettingsEditValue, bool &SettingsCh // Checks if some of the conditions are met. void CAccountProtector::CheckAllConditions() { - double floating_profit = 0, floating_profit_pips = 0; + double floating_profit = 0; + int floating_profit_points = 0; + double daily_profit_loss_units = 0, daily_profit_loss_perc = 0; + int daily_profit_loss_points = 0; if (No_Condition() || No_Action()) return; -// Calculating floating profit/loss. + // Calculating floating profit/loss. for (int i = 0; i < OrdersTotal(); i++) { if (!OrderSelect(i, SELECT_BY_POS)) { - Logging("Account Protector: OrderSelect failed " + IntegerToString(GetLastError())); + Logging("Account Protector: MODE_TRADES OrderSelect failed " + IntegerToString(GetLastError())); continue; } + if (CheckFilterLossProfit(OrderProfit())) continue; if (CheckFilterSymbol(OrderSymbol())) continue; + if ((OrderClosePrice() == 0) || (iClose(OrderSymbol(), Period(), 0) == 0) || (SymbolInfoDouble(OrderSymbol(), SYMBOL_ASK) == 0) || (SymbolInfoDouble(OrderSymbol(), SYMBOL_BID) == 0)) return; // Prevents incorrect profit/loss values when working with account that is traded via API calls. if (CheckFilterComment(OrderComment())) continue; // Starting from -1 index to check for orders irrespective of their Magic numbers. for (int j = -1; j < magic_array_counter; j++) @@ -3696,10 +4369,54 @@ void CAccountProtector::CheckAllConditions() floating_profit += OrderProfit(); if (sets.CountCommSwaps) floating_profit += OrderCommission() + OrderSwap(); - if (OrderType() == OP_BUY) floating_profit_pips += MathRound((MarketInfo(OrderSymbol(), MODE_BID) - OrderOpenPrice()) / MarketInfo(OrderSymbol(), MODE_POINT)); - if (OrderType() == OP_SELL) floating_profit_pips += MathRound((OrderOpenPrice() - MarketInfo(OrderSymbol(), MODE_ASK)) / MarketInfo(OrderSymbol(), MODE_POINT)); + if (OrderType() == OP_BUY) floating_profit_points += (int)MathRound((MarketInfo(OrderSymbol(), MODE_BID) - OrderOpenPrice()) / MarketInfo(OrderSymbol(), MODE_POINT)); + else if (OrderType() == OP_SELL) floating_profit_points += (int)MathRound((OrderOpenPrice() - MarketInfo(OrderSymbol(), MODE_ASK)) / MarketInfo(OrderSymbol(), MODE_POINT)); + break; // Order already processed - no point to process this order with other magic numbers. } } + + // Calculating daily profit/loss if necessary. + if ( + ((!DisableDailyProfitLossUnitsGE) && (sets.boolDailyProfitLossUnitsGE)) || + ((!DisableDailyProfitLossUnitsLE) && (sets.boolDailyProfitLossUnitsLE)) || + ((!DisableDailyProfitLossPointsGE) && (sets.boolDailyProfitLossPointsGE)) || + ((!DisableDailyProfitLossPointsLE) && (sets.boolDailyProfitLossPointsLE)) || + ((!DisableDailyProfitLossPercGE) && (sets.boolDailyProfitLossPercGE)) || + ((!DisableDailyProfitLossPercLE) && (sets.boolDailyProfitLossPercLE)) + ) + { + datetime start_of_today = StringToTime(TimeToString(TimeCurrent(), TIME_DATE)); // 00:00 of the current day by broker's time. + for (int i = 0; i < OrdersHistoryTotal(); i++) + { + if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) + { + Logging("Account Protector: MODE_HISTORY OrderSelect failed " + IntegerToString(GetLastError())); + continue; + } + + if (OrderCloseTime() < start_of_today) continue; // Older trade - skip. + if (CheckFilterLossProfit(OrderProfit())) continue; + if (CheckFilterSymbol(OrderSymbol())) continue; + if (CheckFilterComment(OrderComment())) continue; + // Starting from -1 index to check for orders irrespective of their Magic numbers. + for (int j = -1; j < magic_array_counter; j++) + { + if (CheckFilterMagic(OrderMagicNumber(), j)) continue; + + daily_profit_loss_units += OrderProfit(); + if (sets.CountCommSwaps) daily_profit_loss_units += OrderCommission() + OrderSwap(); + + if (OrderType() == OP_BUY) daily_profit_loss_points += (int)MathRound((OrderClosePrice() - OrderOpenPrice()) / MarketInfo(OrderSymbol(), MODE_POINT)); + else if (OrderType() == OP_SELL) daily_profit_loss_points += (int)MathRound((OrderOpenPrice() - OrderClosePrice()) / MarketInfo(OrderSymbol(), MODE_POINT)); + break; // Order already processed - no point to process this order with other magic numbers. + } + } + // Current floating profit/loss is a part of the daily profit/loss. + daily_profit_loss_units += floating_profit; + daily_profit_loss_points += floating_profit_points; + // Percentage of balance at the start of the day calculated by subtracting the current daily profit from the current balance. + daily_profit_loss_perc = daily_profit_loss_units / (AccountInfoDouble(ACCOUNT_BALANCE) - daily_profit_loss_units) * 100; + } string AdditionalFunds_Asterisk = ""; if (AdditionalFunds != 0) AdditionalFunds_Asterisk = "*"; @@ -3720,13 +4437,13 @@ void CAccountProtector::CheckAllConditions() if ((!DisableFloatLossFallCurr) && (floating_profit >= -sets.doubleLossQuanUnitsReverse)) CheckOneCondition(sets.doubleLossQuanUnitsReverse, sets.boolLossQuanUnitsReverse, "Floating loss fell to " + DoubleToString(sets.doubleLossQuanUnitsReverse, 2) + " " + AccountInfoString(ACCOUNT_CURRENCY)); -// Floating loss rose to pips. - if ((!DisableFloatLossRisePips) && (floating_profit_pips <= - sets.intLossPips)) - CheckOneCondition(sets.intLossPips, sets.boolLossPips, "Floating loss rose to " + IntegerToString(sets.intLossPips) + " pips", Floating_loss_rises_to_pips); +// Floating loss rose to points. + if ((!DisableFloatLossRisePoints) && (floating_profit_points <= - sets.intLossPoints)) + CheckOneCondition(sets.intLossPoints, sets.boolLossPoints, "Floating loss rose to " + IntegerToString(sets.intLossPoints) + " points", Floating_loss_rises_to_points); -// Floating loss fell to pips. - if ((!DisableFloatLossFallPips) && (floating_profit_pips >= - sets.intLossPipsReverse)) - CheckOneCondition(sets.intLossPipsReverse, sets.boolLossPipsReverse, "Floating loss fell to " + IntegerToString(sets.intLossPipsReverse) + " pips"); +// Floating loss fell to points. + if ((!DisableFloatLossFallPoints) && (floating_profit_points >= - sets.intLossPointsReverse)) + CheckOneCondition(sets.intLossPointsReverse, sets.boolLossPointsReverse, "Floating loss fell to " + IntegerToString(sets.intLossPointsReverse) + " points"); // Floating profit rose to % of balance. if ((!DisableFloatProfitRisePerc) && (floating_profit >= (AccountInfoDouble(ACCOUNT_BALANCE) + AdditionalFunds) * sets.doubleProfPerBalance / 100)) @@ -3744,13 +4461,13 @@ void CAccountProtector::CheckAllConditions() if ((!DisableFloatProfitFallCurr) && (floating_profit <= sets.doubleProfQuanUnitsReverse)) CheckOneCondition(sets.doubleProfQuanUnitsReverse, sets.boolProfQuanUnitsReverse, "Floating profit fell to " + DoubleToString(sets.doubleProfQuanUnitsReverse, 2) + " " + AccountInfoString(ACCOUNT_CURRENCY)); -// Floating profit rose to pips. - if ((!DisableFloatProfitRisePips) && (floating_profit_pips >= sets.intProfPips)) - CheckOneCondition(sets.intProfPips, sets.boolProfPips, "Floating profit rose to " + IntegerToString(sets.intProfPips) + " pips.", Floating_profit_rises_to_pips); +// Floating profit rose to points. + if ((!DisableFloatProfitRisePoints) && (floating_profit_points >= sets.intProfPoints)) + CheckOneCondition(sets.intProfPoints, sets.boolProfPoints, "Floating profit rose to " + IntegerToString(sets.intProfPoints) + " points.", Floating_profit_rises_to_points); -// Floating profit fell to pips. - if ((!DisableFloatProfitFallPips) && (floating_profit_pips <= sets.intProfPipsReverse)) - CheckOneCondition(sets.intProfPipsReverse, sets.boolProfPipsReverse, "Floating profit fell to " + IntegerToString(sets.intProfPipsReverse) + " pips."); +// Floating profit fell to points. + if ((!DisableFloatProfitFallPoints) && (floating_profit_points <= sets.intProfPointsReverse)) + CheckOneCondition(sets.intProfPointsReverse, sets.boolProfPointsReverse, "Floating profit fell to " + IntegerToString(sets.intProfPointsReverse) + " points."); // Equity fell to . if (AccountInfoDouble(ACCOUNT_EQUITY) + AdditionalFunds <= sets.doubleEquityLessUnits) @@ -3793,13 +4510,53 @@ void CAccountProtector::CheckAllConditions() CheckOneCondition(sets.doubleMarginGrPerSnap, sets.boolMarginGrPerSnap, "Free Margin rose to " + DoubleToString(sets.doubleMarginGrPerSnap, 2) + "% of previous snapshot (" + DoubleToString(sets.SnapMargin, 2) + AdditionalFunds_Asterisk + " " + AccountInfoString(ACCOUNT_CURRENCY) + ")"); // Current price greater or equal to . - if (Ask >= sets.doublePriceGE) + if ((!DisableCurrentPriceGE) && (Ask >= sets.doublePriceGE)) CheckOneCondition(sets.doublePriceGE, sets.boolPriceGE, "Current price greater or equal to " + DoubleToString(sets.doublePriceGE, _Digits)); // Current price less or equal to . - if (Bid <= sets.doublePriceLE) + if ((!DisableCurrentPriceLE) && (Bid <= sets.doublePriceLE)) CheckOneCondition(sets.doublePriceLE, sets.boolPriceLE, "Current price less or equal to " + DoubleToString(sets.doublePriceLE, _Digits)); +// Margin level greater or equal to %. + if ((!DisableMarginLevelGE) && (AccountInfoDouble(ACCOUNT_MARGIN_LEVEL) >= sets.doubleMarginLevelGE)) + CheckOneCondition(sets.doubleMarginLevelGE, sets.boolMarginLevelGE, "Margin level greater or equal to " + DoubleToString(sets.doubleMarginLevelGE, 2) + "%"); + +// Margin level less or equal to %. + if ((!DisableMarginLevelLE) && (AccountInfoDouble(ACCOUNT_MARGIN_LEVEL) <= sets.doubleMarginLevelLE)) + CheckOneCondition(sets.doubleMarginLevelLE, sets.boolMarginLevelLE, "Margin level less or equal to " + DoubleToString(sets.doubleMarginLevelLE, 2) + "%"); + +// Spread greater or equal to points. + if ((!DisableSpreadGE) && (SymbolInfoInteger(Symbol(), SYMBOL_SPREAD) >= sets.intSpreadGE)) + CheckOneCondition(sets.intSpreadGE, sets.boolSpreadGE, "Spread greater or equal to " + IntegerToString(sets.intSpreadGE)); + +// Spread less or equal to points. + if ((!DisableSpreadLE) && (SymbolInfoInteger(Symbol(), SYMBOL_SPREAD) <= sets.intSpreadLE)) + CheckOneCondition(sets.intSpreadLE, sets.boolSpreadLE, "Spread less or equal to " + IntegerToString(sets.intSpreadLE)); + +// Daily profit/loss greater or equal to currency units. + if ((!DisableDailyProfitLossUnitsGE) && (daily_profit_loss_units >= sets.doubleDailyProfitLossUnitsGE)) + CheckOneCondition(sets.doubleDailyProfitLossUnitsGE, sets.boolDailyProfitLossUnitsGE, "Daily profit/loss greater or equal to " + DoubleToString(sets.doubleDailyProfitLossUnitsGE, 2) + " " + AccountInfoString(ACCOUNT_CURRENCY)); + +// Daily profit/loss less or equal to currency units. + if ((!DisableDailyProfitLossUnitsLE) && (daily_profit_loss_units <= sets.doubleDailyProfitLossUnitsLE)) + CheckOneCondition(sets.doubleDailyProfitLossUnitsLE, sets.boolDailyProfitLossUnitsLE, "Daily profit/loss less or equal to " + DoubleToString(sets.doubleDailyProfitLossUnitsLE, 2) + " " + AccountInfoString(ACCOUNT_CURRENCY)); + +// Daily profit/loss greater or equal to points. + if ((!DisableDailyProfitLossPointsGE) && (daily_profit_loss_points >= sets.intDailyProfitLossPointsGE)) + CheckOneCondition(sets.intDailyProfitLossPointsGE, sets.boolDailyProfitLossPointsGE, "Daily profit/loss greater or equal to " + IntegerToString(sets.intDailyProfitLossPointsGE)); + +// Daily profit/loss less or equal to points. + if ((!DisableDailyProfitLossPointsLE) && (daily_profit_loss_points <= sets.intDailyProfitLossPointsLE)) + CheckOneCondition(sets.intDailyProfitLossPointsLE, sets.boolDailyProfitLossPointsLE, "Daily profit/loss less or equal to " + IntegerToString(sets.intDailyProfitLossPointsLE)); + +// Daily profit/loss greater or equal to %. + if ((!DisableDailyProfitLossPercGE) && (daily_profit_loss_perc >= sets.doubleDailyProfitLossPercGE)) + CheckOneCondition(sets.doubleDailyProfitLossPercGE, sets.boolDailyProfitLossPercGE, "Daily profit/loss greater or equal to " + DoubleToString(sets.doubleDailyProfitLossPercGE, 2) + "%"); + +// Daily profit/loss less or equal to %. + if ((!DisableDailyProfitLossPercLE) && (daily_profit_loss_perc <= sets.doubleDailyProfitLossPercLE)) + CheckOneCondition(sets.doubleDailyProfitLossPercLE, sets.boolDailyProfitLossPercLE, "Daily profit/loss less or equal to " + DoubleToString(sets.doubleDailyProfitLossPercLE, 2) + "%"); + // Timeout by timer. if ((sets.UseTimer) && (sets.TimeLeft == "00:00")) { @@ -3836,7 +4593,7 @@ void CAccountProtector::Trigger_Actions(string title) if (sets.RecaptureSnapshots) WasRecapturedSnapshots = true; else WasRecapturedSnapshots = false; -// Close all positions. + // Close all positions. if (sets.ClosePos) { if (!DoNotResetActions) sets.ClosePos = false; @@ -3847,7 +4604,7 @@ void CAccountProtector::Trigger_Actions(string title) sets.TriggeredTime = TimeToString(TimeLocal(), TIME_DATE | TIME_MINUTES | TIME_SECONDS); } -// Delete all pending orders. + // Delete all pending orders. if (sets.DeletePend) { if (!DoNotResetActions) sets.DeletePend = false; @@ -3857,7 +4614,7 @@ void CAccountProtector::Trigger_Actions(string title) sets.TriggeredTime = TimeToString(TimeLocal(), TIME_DATE | TIME_MINUTES | TIME_SECONDS); } -// Disable autotrading. + // Disable autotrading. if (sets.DisAuto) { if (!DoNotResetActions) sets.DisAuto = false; @@ -3869,7 +4626,7 @@ void CAccountProtector::Trigger_Actions(string title) } string subject, body; -// Send emails. + // Send emails. if (sets.SendMails) { if (!DoNotResetActions) sets.SendMails = false; @@ -3880,7 +4637,7 @@ void CAccountProtector::Trigger_Actions(string title) sets.TriggeredTime = TimeToString(TimeLocal(), TIME_DATE | TIME_MINUTES | TIME_SECONDS); } -// Send push notifications. + // Send push notifications. if (sets.SendNotif) { if (!DoNotResetActions) sets.SendNotif = false; @@ -3891,7 +4648,7 @@ void CAccountProtector::Trigger_Actions(string title) sets.TriggeredTime = TimeToString(TimeLocal(), TIME_DATE | TIME_MINUTES | TIME_SECONDS); } -// Close platform. + // Close platform. if (sets.ClosePlatform) { if (!DoNotResetActions) sets.ClosePlatform = false; @@ -3899,7 +4656,7 @@ void CAccountProtector::Trigger_Actions(string title) TerminalClose(0); } -// Enable autotrading. + // Enable autotrading. if (sets.EnableAuto) { if (!DoNotResetActions) sets.EnableAuto = false; @@ -3910,7 +4667,7 @@ void CAccountProtector::Trigger_Actions(string title) sets.TriggeredTime = TimeToString(TimeLocal(), TIME_DATE | TIME_MINUTES | TIME_SECONDS); } -// Recapture snapshots. + // Recapture snapshots. if (sets.RecaptureSnapshots) { if (!DoNotResetActions) sets.RecaptureSnapshots = false; @@ -3951,10 +4708,7 @@ void CAccountProtector::ProcessMagicNumbers() if (sets.MagicNumbers == "") return; -// Maximum possible number of Magic Numbers based on string length. - ArrayResize(MagicNumbers_array, StringLen(sets.MagicNumbers) / 2 + 1); - -// Split string with Magic numbers using all separators, getting an array with clean Magic numbers. + // Split string with Magic numbers using all separators, getting an array with clean Magic numbers. string result[]; int n = StringSplit(sets.MagicNumbers, StringGetCharacter(",", 0), result); for (int i = 0; i < n; i++) @@ -3972,6 +4726,7 @@ void CAccountProtector::ProcessMagicNumbers() for (int k = 0; k < l; k++) { if (third_result[k] == "") continue; + ArrayResize(MagicNumbers_array, magic_array_counter + 1, 10); MagicNumbers_array[magic_array_counter] = (int)StringToInteger(third_result[k]); magic_array_counter++; } @@ -3979,6 +4734,40 @@ void CAccountProtector::ProcessMagicNumbers() } } +// Creates array of Magic numbers and updates its counter. +void CAccountProtector::ProcessInstruments() +{ + instruments_array_counter = 0; + + if (sets.Instruments == "") return; + + // Split string with Instruments using all separators, getting an array with clean Magic numbers. + string result[]; + int n = StringSplit(sets.Instruments, StringGetCharacter(",", 0), result); + for (int i = 0; i < n; i++) + { + string second_result[]; + int m = StringSplit(result[i], StringGetCharacter(";", 0), second_result); + for (int j = 0; j < m; j++) + { + string third_result[]; + // Third result, at this point, holds all the Instruments (strings) even if there was only one. + // The problem is that it will vanish on next cycle iteration. + int l = StringSplit(second_result[j], StringGetCharacter(" ", 0), third_result); + + // Fill Instruments using instruments_array_counter as an absolute counter. + for (int k = 0; k < l; k++) + { + if (third_result[k] == "") continue; + ArrayResize(Instruments_array, instruments_array_counter + 1, 10); + Instruments_array[instruments_array_counter] = third_result[k]; + StringToLower(Instruments_array[instruments_array_counter]); + instruments_array_counter++; + } + } + } +} + // Checks if value, entered into input field, is of double type. bool CAccountProtector::IsDouble(const string value) { @@ -3986,12 +4775,13 @@ bool CAccountProtector::IsDouble(const string value) for (i = 0; i < StringLen(value); i++) { + if ((i == 0) && (value[i] == '-')) continue; // Allow negative numbers. if (value[i] == '.') dot++; - else if ((value[i] < '0') || (value[i] > '9')) return(false); + else if ((value[i] < '0') || (value[i] > '9')) return false; } - if (dot > 1) return(false); + if (dot > 1) return false; - return(true); + return true; } // Checks if value, entered into input field, is of integer type. @@ -4000,9 +4790,12 @@ bool CAccountProtector::IsInteger(const string value) int i; for (i = 0; i < StringLen(value); i++) - if ((value[i] < '0') || (value[i] > '9')) return(false); + { + if ((i == 0) && (value[i] == '-')) continue; // Allow negative numbers. + if ((value[i] < '0') || (value[i] > '9')) return false; + } - return(true); + return true; } // Calculate order lots to close based on partial close percentage given. diff --git a/MQL4/Experts/Account Protector/Defines.mqh b/MQL4/Experts/Account Protector/Defines.mqh index cd305d7..bad8696 100644 --- a/MQL4/Experts/Account Protector/Defines.mqh +++ b/MQL4/Experts/Account Protector/Defines.mqh @@ -1,6 +1,6 @@ //+------------------------------------------------------------------+ //| Defines.mqh | -//| Copyright © 2017-2021, EarnForex.com | +//| Copyright © 2017-2022, EarnForex.com | //| https://www.earnforex.com/ | //+------------------------------------------------------------------+ #include @@ -62,10 +62,10 @@ enum ENUM_CONDITIONS { Floating_loss_rises_to_perecentage, Floating_loss_rises_to_currency_units, - Floating_loss_rises_to_pips, + Floating_loss_rises_to_points, Floating_profit_rises_to_perecentage, Floating_profit_rises_to_currency_units, - Floating_profit_rises_to_pips, + Floating_profit_rises_to_points, Other_condition // Any other condition where sorting or partial closure is irrelevant. }; @@ -96,18 +96,21 @@ struct Settings string MagicNumbers; bool boolExcludeMagics; int intInstrumentFilter; + string Instruments; + bool boolIgnoreLossTrades; + bool boolIgnoreProfitTrades; bool boolLossPerBalance; bool boolLossQuanUnits; - bool boolLossPips; + bool boolLossPoints; bool boolProfPerBalance; bool boolProfQuanUnits; - bool boolProfPips; + bool boolProfPoints; bool boolLossPerBalanceReverse; bool boolLossQuanUnitsReverse; - bool boolLossPipsReverse; + bool boolLossPointsReverse; bool boolProfPerBalanceReverse; bool boolProfQuanUnitsReverse; - bool boolProfPipsReverse; + bool boolProfPointsReverse; bool boolEquityLessUnits; bool boolEquityGrUnits; bool boolEquityLessPerSnap; @@ -120,18 +123,28 @@ struct Settings bool boolMarginGrPerSnap; bool boolPriceGE; bool boolPriceLE; + bool boolMarginLevelGE; + bool boolMarginLevelLE; + bool boolSpreadGE; + bool boolSpreadLE; + bool boolDailyProfitLossUnitsGE; + bool boolDailyProfitLossUnitsLE; + bool boolDailyProfitLossPointsGE; + bool boolDailyProfitLossPointsLE; + bool boolDailyProfitLossPercGE; + bool boolDailyProfitLossPercLE; double doubleLossPerBalance; double doubleLossQuanUnits; - int intLossPips; + int intLossPoints; double doubleProfPerBalance; double doubleProfQuanUnits; - int intProfPips; + int intProfPoints; double doubleLossPerBalanceReverse; double doubleLossQuanUnitsReverse; - int intLossPipsReverse; + int intLossPointsReverse; double doubleProfPerBalanceReverse; double doubleProfQuanUnitsReverse; - int intProfPipsReverse; + int intProfPointsReverse; double doubleEquityLessUnits; double doubleEquityGrUnits; double doubleEquityLessPerSnap; @@ -144,6 +157,16 @@ struct Settings double doubleMarginGrPerSnap; double doublePriceGE; double doublePriceLE; + double doubleMarginLevelGE; + double doubleMarginLevelLE; + int intSpreadGE; + int intSpreadLE; + double doubleDailyProfitLossUnitsGE; + double doubleDailyProfitLossUnitsLE; + int intDailyProfitLossPointsGE; + int intDailyProfitLossPointsLE; + double doubleDailyProfitLossPercGE; + double doubleDailyProfitLossPercLE; bool ClosePos; double doubleClosePercentage; Position_Status CloseWhichPositions; diff --git a/MQL5/Experts/Account Protector/Account Protector.mq5 b/MQL5/Experts/Account Protector/Account Protector.mq5 index e3beab5767c182c6ee4eb16cceddec5c126a1d31..5ad13df4a84dab6825a436ebdb9774eb26524d42 100644 GIT binary patch delta 2589 zcmbVOOH5Ny5ShmkobEvqOJ7xN5G(xK%nuT5Ck2k!b3G3#$@%|Z8b@nqXmBHZReGSLC!g%wQ7d4#y7`@DvSAZ z%j1HHzc~hYve{w0-+rNrQ%yVC&QOHXG$UMen&Na7Z-R$f_4av-MWaN~cC$6|53gSv zc!k?8)}N&mV#UEbB@yZ~mN8gM?BFV~!~ehtJm-+fH5vs^lBO}rBI_h&@Jyfr8E1sM zbE=5dRFneR4}XQ{o2^}JZ#-TxD>Bl{vXXVB!fkscf@kBrN0E=L{-!doP367#PV?|4 z`2VX0YpkwvwZzexSmhnCrMS7Tjqf>*R>=Hc6%?cFGXm`=?flW%z|U$O%O|kx87zF7 zmS`RuQ#AoC9Kh?6(}r(99*x#V9)@KEe$&`&OW0Uhj1y?4aB67KG(LqL8(y_|24iWp z88cK8bQ%t6<(39q)=^VCTxew^jx$E4qszW5hc-*IbXIXM0Pdz^0A*<$uozvTVUR7U zdfemzQ8(TYo`8CLDM%)qFIk2; zBqe8ShJ2`N5$S0_NU7o^Cr9eaFHlq^o<EcrV;tvHmTMNjG?hvWY~rcmQyLV7 zMOI}(Dw{)yB?XP3Vvz$80a^7tg#c43Gz1O5B~9r<40Bna(m?wuOhfqgQ6trHGSSJ` zCl4C$cAl#X77AW(YpiSIH+ww0PoVk*MIJBe(zvP>9pzQ;kxnbZs$wN5cDi@*=>B^} z5g*{Mo;vm(cx0Jzx?h{4`<@BdTG$zA8&^yveU`%x{s*LWE6tm@&%ArjoJ( ze}!n_Zr&T@fbWUff(JewqXzyFkd|)YOFkdZ`o~JFZnW-Uv1J{6J>W8ZUi>}#H1xcR zzxV8_HG9c-db?#@lfSxe_v-wqYfEEEClv;>C0DEc&NNDl|W1-0#j4UR< zFqWDuVB`cf*m&{-BZ0|tj8?$;5VeP(HY_xDpIl(cGTF|UZSp*zDf>(|Ajv3b^K3q4 z`h|xgc7h|*E2i2-*?+jFd%xlo*nS9DrVzZs& Z4CcujJh(Qid06O7{@^dNIjVF6KLE!BaI*ja diff --git a/MQL5/Experts/Account Protector/Account Protector.mqh b/MQL5/Experts/Account Protector/Account Protector.mqh index bf9343091085ec3ee3e4242dca4ba464228a1076..88f3a16f603797d2be2df55c23448b7d7473127b 100644 GIT binary patch delta 49704 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 delta 10125 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 b{5P9i2!}8bok#TM?*m(v@53Ydw!!}g{V;a( diff --git a/MQL5/Experts/Account Protector/Defines.mqh b/MQL5/Experts/Account Protector/Defines.mqh index 02612adf352432e878d62fb244014bde77ebb1aa..d6d461ff74e553f8abd35233b8c681b04d10158d 100644 GIT binary patch delta 1024 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 OEi0)cQ7&fm^?v}AmOC;4 literal 47360 zcmbSz1y~h*zW+fKP`ahN8>CZ2y1P51yIVlIyQRCkMOwPMySwW@`0l%V_uajF@BRBc z3jCfkXXY?7-%pN#(vm{3?=atiKpQNZ?JO`Lu6OYwWoS81{DisIQarUYooAXM6 zIY?wTavhp{VBF@#=`sWk1NifO50=1J7Y79LDlGh!k6QK-5(GjZ`0yDx%J0UiqN1W6 z9v%`B60)*UjFnIvuQ#6ANx?xYR%~BaNy*6aDl5-=BZ+8eXeK8oKY#u_I5?=HqH>CC z*Xh}-v>?q?JlxUfcNvq+xULl~^|?BTyu92b)y-`Jc<;>2%)Gq3ii(QtY+`2Sn!38_ z<7=%38-p)j$P-+@8lg5>tCCYQ9+3J*_zUO3K&V2aWi@k&YR1o=>A{1%8XFti+uJK) z4J7@U5TJI@3pgE*7Mh*q#;b8S9kO$B6ciLH>o~CeKAD*08(J$Lo*WJ7Elugf1O~s|AmgHe$S!3$IqEJvi zA{9#9S!ia!vv8{ud4^%`FvPv9E`PmW6t{(Mz}X;$0s_&~>O35_d;37bQxcZb_mLUo&I>Ymr__MK;HPo5|>Vd%~!tIFj32YP=DIEafH>2VB-Kmewn zo>qg4m(FPPe72#luMcCl3LYo__~w(f2Mfa?RLw3jeP+G zS{2FU(Y{+53eX~-mvm(!wGVDDEz(#@Dh$d1^ZYm)6EfX>=wRvLIIlLIo?_AOX7bP+ zwacVv!zw0ZhsXk(i+D@9aSNFULE$_XH}%C$R5PZ%S`P{&OnjEpe$n)?E3f^{XnpC# zO4HJZLpmd`%xR@Itz&cc>b0L47v}rwc$W4PnrXWjHzU_QOHv+76L<4Z!F8&N%@yiN zg|J`YY|9})d?S&_feQpbbB#wBaH;TEQ){uyr{YSVt2s{$istH*~|qbevcvfo`T6 z0s{gK;6(;rEeGu(sOajhY0$LiP|Bs~4)xngK3~Xe@wJ$WZ|e=o4~ObqA1%XPjaEtK z5^2?p}IS6H@xI(wwC{zZ57VAa@k>q9)==;8Hi^b{nTlF7cjrL%<@2swYpGRi!23MdX>N_+yN-1uv7P(c?G5mK8EdpAG+(dDAg>j(P{!Q?2#pV!pK8 zQeEbI3=pVODzN0v>&YEuaTM4uadP<~*{##el!A1=aq}?h`pXf`3`8Z3Sy$z9vEbH~ zdR0jXl~DoPX^eoCvc_7ND;=zMkB)^BCG~+ouTwo|Ig>}oqv&BgiChs;;0XitTu3o= z)XH#OP&mJ}N4uXQxLl7!y!Fv^xI!_sa=;I`F}=IT@qUg%aV=9&V5R z-m>yg(~URc1GPtCVPBUzcAGm76GGZC)j?0(HLaz<{N{42qzq~nYFzdX`%(XrrYzEe zy}gW_t?9t-&37#c8mKE(tMH_^G6@EbT)apePrZ(@w8`MT>??WnL*0#oTG-nwO=~*_ zi-C&tcCbzp%*_$_r5jPPT^ulEAy}*yJB?2_r+Oz&_gCgMsx8jvTUkQk+EP07?+;vV zm7k9H-$9}nDYb_^HKq9F_=(V}=c0rR6f+Yw2IawEi}GjtP#af$qx@zTF{v;QA(x1F zJ>SIGFR{!U^c_IHR{$k;p|U zgMm55JdB2e@B5|RwtrPw4){ebE<6|;O7ouoz0q)*`_sd1gV>GzGF=EK<30wSi4;E?OH*^fYxQ$j@<#@7n>kL1<~NGY|2*&b(9W{*ENVj!c2cdKktSfH$x_R#DvUQ{cTpc7+iDJ^DV!JdODCNDM^tdQ|MDP*GUqs68I zc}le47MIJtfkdWk#4EU$PlnUD`MOjPul)@<;Ts7Ur#baEZiLIJbXohzYWG?-ftwJD2&&kEb9-p??P8-{roY|f}Q=> zCuj)pD*}PSxVr=HT2;0>%m)~xG$;t*^a~M5N}QkN7QB*)V5h=mL`t%?s*cnn%ZGj? zT_lnR_6gc2hJe@Y=H%vdoldj)2KX|XCG_ZmW4K5EUVI0JU`a(>@ktJEIftK6*FYRD zjQFJHJJNJk5ZV(>&huMLo=6;31h5}P?=n}Hzc^1-dIpdm)Lp0NH3ip8+~Mo;ov#gP zteKi(z8`yo8mb?m-4hlxxA7YC9!;=Dl|*#&hqpzUi>vGXW`BHxI^0j^la-Ia%_3F& zpsU};ayydo$yGDALz`ZifpG~jxde{p@`qB4cQW;@KOExeP-U*=Arv|;C!e88nyF}m z2pry#muK~==hpdyNo;mz57kEkG5z4I{UxyIw#6t!h_QEs8SRhbS-`c`Ia8x+Wxn)b zpYI3qN2%2Toe@3!AWu(Dz4zv2AK3JX-?v3HgsUBW;Gs`XI?Azr9uz|tXp0gllG_g} zrFB_gv7_g4yBV>ldu&W05(-mqu-WX3COckk^SnO7IRFFBB0I+pTetu7Ah)(GTF_BW za>8-0z9CKaXAs-wotYS=K5{404$kuKds}8bICWZd8j_`bP%j@uppt-%aoW9$e<_MZ z;;#^s(XfRS{DAr{`()wZbWg#BikPPe7|@f=H-8p^k3KnVFbW6b`}{5IDNEF)Ioq$K zKBKT9j7*Hkku$wQb%7*BP+)QUYNCkX5~^QbZ(0ybx|PyK{~DhS1S{L%r-W{&Dj|G0 zduRi3X?C~0H(A67mTCW`Hp8!7yR-30;f}{Y4uiB4o`gdg@-YE)x*c9aV=n;G^2nv2X4pBUdR zS$;S_2rl36G4wgMl$=guK4J;JPl(*J*6LfKn1V#aCRg_a{?|C^zB*86>(0wco7O(& z^NHey1WPQV$br2N+E-8?g&>`x=58*G?Abiq3v7?Cq4?+?e%Wl`BG`fKbNd?SG!G{6 zFF(#y;CVJ&r-0)#n!~)}LC|g=?s>eZp$@M3TEJo>@f!3!3*4>dQ8w;pbbMJY2@J?9 z3=RNRoK(p?B6w(!ZbbqJe}^kXfRF(G4M?>ljv5n0tpT9x*OynlXn=nJJ^l+K13UjK z0ob{8A(-|#z4_4W#Qw4w{-%K2lD0mkCfD!_B(IP}acaO*q@BmR09xXXl_@*=JNG*5 zgq@+Cof%O>#nCgdEm>*v`jo?@ox0QDL8&SGu_Od<6Z3U#vbB`WUXI@z5Z?wwBC$TR z34N@}$Y=#jRvI&o9C`)pr)u_P@eFL{RK3M?Y~nhH&FZA-Z_y)9I@M$H=<$dk5aqbl z-X5-omIFy^Eunj(@gAc#j#+F|kGQnCa(vxAgPI~}IONYz_P)V6xn z<>J@Z5pzZQO`AlnTyGO8RQLhDa3B1s6yAlMl_?_W8+v$FR#lV-8cjTOw}~w|clMQ} zSiIWy?)W;6#GQDaaceMzAI*A!-X0ON#i0_09uAJ^?q%{rka&Ab{gxet6IiLw#lipV>S+JBz%{B1wZP%>z~q7}G*+V!83D%)_$^<_Gk%9top} z^zP5;VVagrr7-FT=vasi&2|6_Ew^K?nMhmzuzax|Hn-v0->T>NX76)@YYz&^=b9>~ zsH4d*3hLvX({V<5gS?`dXjLyK*GRQMonpy-e<{u8PE20&y-jmIVvB3g8ThX$ZxWqq zJC3E}Wpc%;3>U6bJ5^+wXN_8m_i^G7FQ?z)@cR~=pl5nrmT3~qm!hKf%EPQ));EIfmzHRV?@aZ zImVB_+%$fnPDQT;$9)@)E5a&5yE4_n-8LWvE`Q(9leLq*09WtWAYvYZyAl^Uu@DrNnc850&;u$Oa6)3Ls<+uHhTdDo| zAo-&ymJmwMGv(vElIGJw(|ija{Q_ZSJ#TzO`Alu3uhJE6R(iWDYf%VvNVl@-A~j|xhgEA`kFP9hG(0Q=su_8 zu>52G*_9C*I->#h{HJAkk0eIP;O1^uNnF-)|3PIMG{iax4*~{lr##=FbcBm#DM79< zo?I8Y>t|0=rpC%im>}->`SM6yL8=DG4sj&L@2m3@5f%X2Pxf8(u%DLa8HkXZnHQ!m zqJ*N|kz9TX;i41O<2z*~8X>!d!zQ7NeG@7CbZrYS0Gb)pcOVE`OSSgL+xVHM&f%GW zWlHi%h?($yWko#|8hA?-9Kotq$oNw8W`HsS|IF5jXQJIfBBZ@vOb1YPt zL!3jf4kL4fkp1Ih3Yn4jxG?6wUF>op_6>wKWaY71MHbgwW(9q5k@fBRLddWe z;T&d^g~nRPSbKHe48cZ?R~R}pFbZ!v9BtBJ(Cp^K7Cn2YzGoUcHI>Qy$?~f=Ux)ka z$E7h-Se&pn>Cd)}z8&T}BhFTh@ck;BZvnaz1h-z20nO?|Zpli72)8APG1~NTk{%4# zONzF%A2dQe&}VH>Pkw*XyH1U^W}v)N6iQ)|MNtuB^Ed+9#_oYI&z?OH=hlp?lz$@l zC|<}Dtr32rzdjWW_VK>eCQmtqg!^+>NF~N9z0-(`9MkJlHCF7Ao!6rmvNNHohCGSZ z+h0KX`S*3UVs9h*$P$b6qm*So_9FRzP^%K@IQo<#E_5B8l;C0KQ_3VtcUdQDzD|86vbw3ABagVih3pz?=|dz#Yrt#=W2(CM&p?)`BR%d zA+uvdGk)dNlP05CPZh7y+f?tXbRioGlm#{ZiqpjV@r zKPwF2*>OdkW0;UNU-2h&(#W(_%-jCyv2GW&7X8fheVP*0u1V-xhuxG6&@(d$PZP=v)G-=Jyv z$vY)04vp@Ia&(Pm*57-#@1l%s@jiC)x^|s9qXX>{z-!MGjq~M|^Tph*>7@yBS%VAF z^Q6n9r6yTN7zTH#ob9Yp;UWpc!d#3FfUMNpf_{>j1;wcsJ08Y&Daq4Am(7(B=*aT6HGX)XC~zCvm&B ziN=OrcT-(RsRXi#v8$5}8*hhX@|Snk5-BCLSDE%8k5r z*OX|}ae6gK8I!$l-O{>KgJT9DI|9G(ge@jO$a3Y?1QHQ`nqbB*z##)1taga7DMjHe zhc%L??etSR-Fy~SV+K|u1IP+bsy2(t)8yqRFkzPEvq3{{_99VBe|Qd%m(G+)a{l!k z2R*`X?`LfHpLt3xkD2;7yhc$$UZay{Ec=;ddGKAAMyKl> zsgl9X03Ht6G!z$7TF1#W4{e_l^1i$b%heNWUags|_z=k`IMrGR!g4Y>>8i5j~+wXUBHaD}u#JcV90^>P{LrAeVZPNGI!UN1)UT(`N_OzE>B| zzu5NH-k;XJN!1dsqT(~){^NMm(dTVgiEf-WhTk^#xLK4%P zN32InoJcODjH{&&^{F`2RM}X#EIPRadz1<0^W3fJG7$IM3Abm_-IGbWpYPCh4IF=2 zJD)ebyh6kR19?kQS&MGiu!oTM?4P<|^OVi6JJi-Vi{-W`iVRs$#B4+t8>nTm@I*V$ab1eX&Ea{~gxkH4wH6;_RkLN@jSY8JnO$@?@z8z@jN(b-$d1LG zAF`-8v1O_^FHAL9hnB}1*bvg9^66r8)PfllO0PRN>lti4@EO?SDYV9BE>gu8v>xNT z6g(9k+%cy0e|(WIJ|RyebCzfp)rVA6(nLrlmJ?dhZ*lMJR(u8O-Erc!NT2UIW9^x1 z4(VC9P6o_Qg-OE51PFw2N>z)r%=mRi22o4AL7s)V_GMcF;miCO)r}#1nv&h>R<=5n z#*@g|opAW;#L$#O>>0K$`EOE!W{9ZZ9b9wyjYQ#zK`cTjGeauWDHwh~XMWK%VqUW{ z25|33p>5;t+do!zDs?T#+e@%~9StZHEL11iAHitq`eY?~^raf!(u@Y=#V4dIx?#r= zy3)OAm8ATx$3?#YhiYGL8#9&Rvs=Zu6q*X$TawuJ38cesya>eSsr5)`ujdWc%(k@O zyfel$u%)MD(-kYx7L(Q!GGJKml$kd7P;n>=ieBw3 zl4rdU(J}}2{TdWgsv0@HX($6Hw#r6X{63&Y8LQf~Ytx>Pm!VOUT8Q0nH=CY9ZN9%6 zI>?0#v5E108eyjFjw%asfh%0IYUiGG_iKo5aKQl5+KJEDK>>|OhKv419-R{lw&Z1H%!8%$=k1YAtO=5W<_#$m|PlY)C)>;|F}8M(XI;7aU*c6TmF z@v5jTDMVf_;!!03g9x;Gl@n-Mzi2_d4uwmc}7SV!oxsKVv9E43Im(S2g>7HRU5RVPpw*^i@@Ls*9^b z4@xeMeUmrPD|61|sm&61Ff94lx#0DPU9E4KS!wwpRj#mlLTF+1*Fttr2YAcwuLYDY zOV+2jarA9!>?z3P=j2 zf$SJtx*S5H0>B*r&B4=hKNvh>w5XCfwldvy{xXl$kU+v}7G5J4GhBFFP6&Yl0Xw(n z+eSkv84wcU;tA=EHZkI6K8q+n-&w;Ax0F_&o{;A_Gwf)CR*p8M(s>T|7#;ey&mSKj z+Xi@(r3s_Vv}%s6PQGJ&g3`AW6cpUCT5XpYdRSnLY^~(az)cK${i5ACzW3Y2#FyTU z`DLAX>;GQC@Bd_?Bb?&{Xjm^kNRU^FqfU_~+_djo5CY(BU^@Z-c&YILFBO(Y1!gqx z4d07{0rFx7u=5zEGbl6n6^Ql~=m#qiD>I01_a)N>VWa{Ue2jP$v3XPcHqY|@%i{Hq zwZkbE#6YS3dD5kyoYUX<{1<54xjxe= z!i}{2fX?G=J#_EF4dh5Yi@YO`@Tzp9U}WnFd{4CEd4z%OQ z^#ji+Z!_Q0#d*xs9ja?V~3R*B8XVg#v9@9?Zs~YrN_VF8meWn?5my*>YJtc9PJiWV`e(h9XcRwZ4$vudfq&w8-|daR&c;rDw7!Z zLCx3Uo?Ur2B9xu@TsN4F-@v6~ywT~M!b}K7N+tbpYMIHmQn)_*lw!8qL*@H8jJed* zo5CB;LWeg|s<*{{w(99&r+F;e{~p^|z(Lt=(v2JeriWG$WrO?HjSCiJ(ALVdJwa$K znnWYkZO{CH%L@ zb`poVn?rrdD0eBhvWIEgPchx7n9`PKYmLuk5K~%dXUdTK>oTpF-kE_wsWqfxmou?` zdF#NWner(tgxu)wNJhibNSLAru5G{hW>kdH{W0kaI^tf;vk+lMcJHS@Di&8V*osyg?#FUx|iwCAi<{>WBV@o27tty98*XYITRLQsjxExDGz+bLGI%Ei^I1-U7!va~AL{vLd&im$`;c#1}=}Qh-S7X#8 z{#8(;g{#9_(UnoBNL8Or&8V_+3)M+<>)aQ-rI{cQsLt!8ae?}m4h6Q5A1Zi7Tnp_9 zEo~X{ZQ$tT+EzFwDye~~YofzPnPXyIC5R3=0r__t{f310!`@0^@BA3_UV*QJQ3)Wc z3Baa(WitdnN7-enBhMWZuRI@${;HLZt2IGE3*f!`mN-|F;IKvt%ycY$kzNy6^Im6> zOx}>=#B83Z9yAD~Z@1$vlF5?34`dGjwz)jsT>{v))arhJw8(kYd&beE!bAf3O3}hA zp6rXei%r@9|F_m=dC4Ej^NN#!#|n5f(eDZkF-7uSW`=asSgnPyCMCV`A}wda`dsG* zql+ChtC42lb+tH|3cXp3lnxc<`{bu~%HwqRibQRw%8Wzl{tdK&-{UJd?u^wHab5rz z0Rh6#8lRl(ivMWcsfL-=iIhPVNT2ggZ?^Mg<4;0Uddoze=vI znm}Q8#x!l9EGV*XsF*n*fvh~;C+Pksz+$MmWcIX^MmlMIqYSJOm0v1u~&&Xcco(TUb@m+1{k;Y;pA|235h?8?kJG zkT~xpyUn^>at{+IJ2#i>Wb};T#wvlF_OjsZ{X-&_T4E3aPxjJ9QT_h}Z%MbBN^7jU zGD+y);2=Opnok$IZ4sw_Xpv=f}@tVr1m^hlaPX*)mE9 zyog2RU|jz8;v@1w+Np${jVWj~TFLXI0D(TRqVFtB15;o(0^rIEn3Z4BnoahvCY6ss zfS>@qhyeJRtwO-YAdvTqwf_gafr>}LemGvs1pf>oe8D;|OLB;(!QMf5kaQzp)`R#2 zx4T2JNDTKw*;#luuNyhkUpDoIYx3K^+@BU%v1uR{xy$psBb!>?8cenWdQBjZs1jUY zz>`!kAihRypl@%F@jR{{pKqU^9=4y&ulzTj@1Ad-@5-K*;iA-uWj_WXhQmv^kpS_7w`AYPjgw}_G&TY}-qEA${+`X}B~R>~fk)%pHm57C($*WgWzMB% z&Yq!Df%@x%-1O{kBdbb0?&`0VZz}Iu3D(IjHi?!R?+!_dPJt_I0tp1lp$c4z&%S<^ zq-5{yW0`q=x@~(NuI8m{b9r2bkbJ0GPPrO)-AxxInG@NWYZ-_TPif_MCF=oZwuz{l z%Seb4655l}vorm9ye{V`z{)B{;xLH}n;bYA0b+pD zI#n+KN9jJY^M0)L{CfTzEQ&DxbV`OdCUr-NNJG8A$!+uK)^Ixe=wCDea2gC8c*IA?=UdN{yXQ~5 z&%94_%dUGpKleNzwc0M9g`N*QAJXlbmB&KKchXZP=y6-636q2S1=SfN%;@qFGXqq6 z3pTGys5S)+sFRg3688Jzq5*J&g&&B_Nf`4V)R@7~>a#884F(516$9u`mF&WlPLjs@ zaC0RTq6^MQ*K&R%gsKmOjt$c9i8`{`xvhId#pxR>I}kssNw#&T)CsYJcQeZr|6oYW z8{)_K}f6Uv8M>$PciBk2nMP7?hPbcj^!?)khu zp8i0`8Sr=YMhphX0UG|hXHk;7@TU&Xr^DyfwwtS^X9M>`t>@#dH1^aSvGj*)v1b9z z^keSF=#JYoho5H%%wzvv(n0kxV*H`$wvtVEehL|8@$xJfvDnnwYOkZnVenv7e3plS zIscNi7sh2sIfpGH{cOMPKNE0BScqAXSbI`^$5o_deromU0G&0ticu$gJIKA|-QnIf zdHHSV4S;^$(;}vzRzkAc3p%`0q)CbfA5~b;cRP|twI1HbBBf`EH4}JtQP1Z#=acZ~ zVWsC)&y(fb^arxM9rwON2Tts;>*GF)P)UO8&i@LBVwit}L&_oUDb}A~wVT9K2C<9n z35+qBx9GV_f@x~L(tHfX$(hw}$YtT6n>-Q>9Z)$K5jG>>LEY|~#g#nTeVgbV*;?PL z_kFRdtsK@TOzIeosr@;nOo+u)nFa!wRS_KuHm&z{&s&z^&Mr+&qGN4D@#~&b*I53^ zeta9&h>@S7M1SkT${m*qq|Nu6Z<$yce&Y z_jBBaOP@Cg)!tp~qyBHqJoEn(GvE6BiJ9*SCK%1O%S)2$_115~wh)60$|ywwnsX@w|0>-o3wm1_q6oW?6DCO+~Kk zZi{qNgn2+&ghfxCC6dxJHso2P9-39M&y)-K~cfx(Np02DI!EuAV@`;|dTW61o6YokS+1{EyMmtjptV%)<+V-{$jW zE5?mZVO^_hpS#*_&?lPzP>-9N_+FP84V$Yeh1Ca({npoKc~a>P_83hY=eJK!Pg+~) z66A;?EM+WYU%C-qVWh6E?%UO$tdJUcoFxitsbolpi$g+JiwBh&pw7_%YLag)v^r4O zt+7Jmax&}vju&mejArAW7&_b@QO^%(hf6JoKlNM%OD%Uzt!azP#w(nNO@bQw?6ER% z6y|GzoI3!hQIlqBSmA)cQF~u488Nn9|h9bgV6<;O8yh6Dik(oZlD zX4vNgF(tS4fTdTN0zxmsQkEyw|Kp(YZ*Uf1;ZiObwNPqYTa6rPQ29fzG6eIY&UfXl zu~>c-gaj2I!w~-vB?YnR0-*l^K=vEMjV(w}eF51EQZsU}S}c$!)}p>*#VqMrUDf$J zyxYFOyW`D!EZ1h|b5a~0;Kg2Ju^Ysh$7r}7btg{iMji~$LWlmm+;^w`c+U^56E}5o z`~Oayj$Vy;iM<90%Jz5O^R55vs9vYPII3Yg$>}`jpD80~H{K-@+$y=X35|dkEo;8B zeV)j<*YqW{iu&l_4a>pn3?gpSm>`YlBN3NIX?;}4TM zi^zPt6CB(XL5=*-*rxucw0z7-xW$oh^KdO$;?X4n?t5br$v|~lf5c5EZq4wHZF|>+ zze!1(;aM8g^nXF-W?}t*(vnWDM7ASFx>&ZtTU}_@zP~QM<=LO26qaMiu^H&3v4E4- z&@>>lmV{zq9WX3lC2KA}O&pYOlCPou3o<|Tqtf!%P}TC_tjoPoRjzk**|>8iG zhEHGgtXGwK@q(a0>Lt!iu>L-7=9=N-n+}{R0qcM^YI_UjX83y)CjJh1#4W2=R5$U#e`6!pc6hVKc^bz}7W}Nn0JV>m6FO z^IkS4T3fFMElPL5=*{>Ueiqf5OeYmJwgnAh(l2AZpi?(@YYPev>-1QOm6J*4FNKnmOJc0ZwpW<3<=?m5FkjR$Iu52nW_Tkr-c3fsB zn%Y&KHgE1DR~Ou6H(E`)C?FnNEbTNa)8WakFMJ1n2y3ZtFpOw2dvvXkxz~*HG*L7aS`>S2tb}qY`Sn*Kan`pS z!M!x_GHle4x6&rs>P3@;CMPJJ3|Pr|GdjbKNRA=-@&OWu@MNBL1Rv7J2O1SDeXp`l zsUQITC??M(qBovr^1qOeYq)=Sqxt#!YC%N%~NtBmn z9v9}<=x~6WZw%y|%XfJ95a8C~Aigwin5M=Fh{cn|K~>z@3J40oF(no|OA<_3TrK8U zG^4FjFR_?B(eK3Rq9UdJH!||SIHVx2u3nm~q9QR}-%YmW90pNp#KtHnxkCCl2^e@^ zSCUNG{1itSd1g$>v{aHU-8I!O4tsGd*_2qWgUFW^I0ltW{Sd1vL4d>m{7)vS{5i@E zVm}so*16}5@jyu)^^lynJz$y|LcSQEL2Z?;C%PYm9Y){a>3?U{Xs`%cBa41q4cNFb za9FF7Q7Cbs4V4sZhPqOM`A_yJmuUBdfLR(mE?0m6p}@t%?KzXtkhBjeDd_-UbcvGI zwp+Z@@niGf)>N8va*7#iepjXS<1S|Q%t}(h>e>dvkRd7uDH$kU%D9L)f{cOWJazS0?4TCBIu(vKoG zo^RpubA73yfnKG4^81^0x)2@0z0~X+4TlG;|HvyPCPQ?uJ2`3c>%rnZ55DC!;eFU0 z4d;Eh*}f(rD)$oQ_vBCQ0 z(IakAXC98SL0q$Lzs&PdC@`cubuG|)B1&MP%kGGh`5Qd*bo5|#H#ZUd(*>AfTgwFR zDSGDEZX~25@8Neta4&M9sO+~ma`(7jSZp)R>nO0h;RyxP_9MNlgC2z! zRdU^m33$VTTXvr?y?)8&ripgKHb2))GQJc`d{w8Kemc#|M|0JoM?I&S?0bc-RhVsUM9 z;>YtjndsfYwmMK!m~qJGhV_oWv7Y!Mf^5StL(B1JXpxPWAWdn+ zk_1E9VWjr|8o<>w$q?D1F;9F<`PA>7exY#33<7CMs~2fdYXmY=KNXH(CbsR?x-wCC(RO8$ zP|=@}l%5`!p8rEd4(*z>z(j0)G$N(I+D+(?%7iwgHCzeEsUax7LNfLEJ2-@wZrqK$ z8G5ZbM1@ZXTnnAZ#FlM~+wIw8ky4pfo5%Uq;C!9sa*JyZu8L+}1q@bMED9i~W({5h zRpvGd;lGX8oGbnsv5B808M3xo-Ej`6WN%{b{n#E+4UQ!En_3d6zIuF2hrDkrFnD3T z8X6i%MASX2G@&xOfg`a339^0wBXYuDpi*&0XVxXvoA|=!>=2g_9B7&`Tc9={HOrrLK`UjI&OA;h_(*{WqvzYh z!zt{aV3QIO=y~lo$rEQFnkalx*Ra!EHH_C+Wkk>UVOlk$cgpENf0^~m28m4q#H+4$ znD^Ih#$fOSNv|0>h=_=OYZ}L)yOEmzCK`(ZjH(ysuaYYp?VG#__k$w*70wlqP622D zXcUc^!uSqmox&HP4y*x2A~5Pf(v_x>m`BSWelL3IBSXA3&zU0YI;lnDja5)L@XXV z?oHCb+bV~c8Cqcff8}6;(P@l7fa=B_*%QC~i#|Qd!+9|gy@$G0vH$yo>)vDemrvgB zcn^O2rr`1JaTv&xTkGt=`p zaaWq_lttOoJ~Ea5T0!%LUKrFo2o*iX;b4I+sEXahU$pC(vBn}*es!#jknW_l4F39> zW{5)h;+9UT=u#Q)k{SHu(6&?#seOIUph+C^*?&**5z2o}sVH&WL0%zYsGV%s8>Z(j zDYSL-ef-#Q{T2UH`=Y1ikM;$sW>1E2oU)2Pbyp0J+0jo342d+oM-{-9v!hXaA2s+< zw%t|~5JeUeGHXN8_34yOVxh$%aZZT^cYoIpRf=aJsjZV4j1@^ZH`uCJ#ih;o93r`4 zKSWGOUXE^>T&dyzqyvQG`tW}XfxOGEhMW<<@Bu+jxB6kT4YTbZ-4wZuZjAiFIQMep zc;g;v%zfT`8aRc+?Rdi*?`Z1jp#YXYp$eSju+Es?T|3P7(EimA6)0hsy|SE&Q$7D` zkoogZ7qr!}qqQ+16W$t$k;xRMoWw{389|mPEiAb|Y>ra$Vyo}!1tgj4UqOc*RHL8E) zL7&c1m}h_?zYnHax@J(U*mv|l))=hAB?R*f7qbDTE=vEx)KR$e5O({;HeZL-m@A~- zXkLyo7JN6!jr64qImE8DM|P~1IRwb>?YF~(=Db0!E)JznFDJ^8f$_Cung@%ut#`mw zYuod=wiYWG2#u&Nq_mVa5HW83B(9shLSRRfP`u!$G7AG2!clC1Xok(wXPL?We!3Pj z1msXzlObPE|I>tJp5%Jt(RtS0wex`I@RDl=pBGnPn*``W?nyNs+r&!+G0{yt#!uD8HLR85T`8bGq? z>Dfjs(zeoOsowV>=cE5n!K*H3`f&GwW`#f?norP3U*8uF9d}`4NCof5)F0#;ct-Ul znfXUnGxi=>fwJR^^Pl(`Axh)Byw~3P=^PxyCn9EMG(WW$c~)zz7Chs;431Or7nKq zPW=RiP$U`p=2MO1Y8h@S9}xRw3&y{jamRLl20LSQRp}(MQ1%sEc$G;3aBTcdTNEDP z3D27$zG8sO>wL7nyc*1*syN?L^2>v@0+c~3hBF@6_k^zWpu?ZFgZL$?|1}(nPQXJx zvbWC%J{myp9iWHzr^}AZuaf`4)&Cb`-01fhw~FvNc-&dlG=1epI>_sJKW^;ytr@VY z@JHCQsj`7V{tP^^MJAc@h1Z%3zYbCgLh=n~i)NX?u?l3e*UC!>34Yd4#2;v3bY;y_7o&%U>x%tGo;V& z+jA0w&q8T5DfMy}JmmkPbAa#H+7DIHQm6i=uaeML#`=7@o04J>&q}qOI~|%=w{vZh z-9FBaxiT96h@98zd=am^<@n+B_ORxqDDfh8V%bP+8n6Xp)_+$OrVp(-e=~T^U{a&H z35he2smc-=EIeTvk*Mc7@rMgtm7qCTThiqMwm;Z(R?Gb~j^6}$G`A@_pXOctD|AIVM;Gk08|j{g=D1uuzU0&$(Y{+g@tpY~HSk=JOfdC%rz;mNffEu3#2@t&B$ z?v$>0tcboR2QzJ?J*?iiBcrwFTEyHS@F~WP+S#I5U=CO*-ioFv4*=owDJ$$_9kJytb zXzoq@sH!?{{9trAs@;^7@JVVOpOgL&-eYAc7%h?iNr>4PQPGQ_SDC1*&C(QfQFt{gnby+sF8pIk;2d%hh1*_-y3?bf#hB__@B`T zb-8>ZY>|fDN%4E5bY41jB{pFy%d}iCN>2AJ&|FwbSpQUsTK2kVo6Yyrc|yV6#g$h$ zbvHR!mOhb;)dx=FH-uwmK!~nFyjL_;qBv?IE_DSrBuil@Av|_)XcyEdNj(4HV5W&m z))8pb!uf(&i@&|Emuq;_Ny7qdvm7NX>t~R+a=+#=l$N?C*%@-yewR&*o}%o#=*pTF z@uu(jjz|?$KC2Xj`!u}#%qO4br7V}p^@_6%QVxDN{U|oKCkf#g9a=6jmq)6lS1S&!BmcA8KZQ{P$9gRU~BX~O2C|Fx<8&y3wX2@XjTDj zhGzHstHmbAgGd8MGe!<(vCp41mSr=P)6-JOs^T)}=wyICNB2T)q2!;26z{fy*3F2` zR7PDP4>uM|boFAL%>qza_%*iDoEx|(us_Z}YC@Msq)C{CqI_A`G2A#;R2yATJc>Bv zqV#X%MPIqYJ<{_?{Y;*VUjIw!0{HJKZrtVA*Z!h3ykhl=n}abKq8Us+sMG5FyQ-cO zPPSm-cQ%9QGa29A*%=-YzXRjGB>{u9Q9H>BM%KTn4d>6N(2KROXQ&#?XXM156YP$g zWt>-_Ww-OIZ6lOrnj|ut*n@ra=;Q3Nglj5tS%1Y$t(R^x37A*) zEd*yGg6aR>j-oz52&TTT|AqQjaS~6w8-IUoPKPtV%PhQ=zBP7pX{`F= zQvm6I^`!9h{`92&1vVL3{|jt3p5weqminmqHq3E?!zMo{gB`$F#(zt zFNErMN1#{=#SF3K(w8om z8PM(LGt#38le1wXIdfXkshi$+5QeBkY;-7#aFxB4LB0Fjd)lY9FQNK3%o8DU zJzTuAlN_oPONzA}-|rs(qpwGS&Hbm!xf5eJ=S;eJxKaf&8bJ`-j-wjjwiQ$kp62lz zz2>;I`8S<(M|+&EnBh1~QJy~4T4s}V@B)$oHs)T;=v(vHtly1vDNCS{ZnAo~X5E$b ze%>&bn5BhQa@eF`K;KD~j0agKN}lwHBrPjHD!ZcbE%>{5hEGaG5P-j4j$^uPBhWM( zR2I}0V`3CDK{@Sq-@8A~@KnuEUT$@K(R+C=F!9oP;Awics!8LS#7c$*Wn%Z~GmD~P zZKA&zCEj6!IgV_-(_4?<2e0dT=AO2EYTbi-7X; zFhz}=#4L31mJD^U*2WO(y9U61ws$!giA@ymHdtdqBo#sZsW~|;ll{_Q$Ei{?;QQTC z|H1DI)>5~9N)v?95p*DxF=fyYtt^@}nl@A1VLO==2GHHS>ed$YTGD=> z7ZfH7s9kti zF83w@3cd^^w^xVrj>k(CLUD@~eLEA>s4rE88r|Pjg+`#>Cjg{U?``J`IZj*lvJ7PZ zA8ThFRb|?}f4~4y8l*u9X%LVurMo+omXwr6N03HoX%Ug`kVff{k`C!k=@fqVb5O^c zdEfWDe*7_O&EXNxFlXKS-q-$I*S^!IeOX`ceD}9{=pa+D#I@<}eJATGMr?$9(J**B zQ4Q3mLmx_pGk3%8ZMGOD6k{vt$t=%al^NO6H$;l#{bDgShk%g{AvN!-tyr=?Ro4sL zV%$w1b9w-G*WiLpwqw4%%FqPgL8hPyVe^8$gM*4rW&6*#-%TxrzlFF`?T*qHrB`F( z%TrL&TN`z^gxxK~qE|l0hzAwjv1z?An~c;`nC~8ntfH_*bYMhd4dDezw#eP~RwJgG zo4-Ts14>93TGPCgArR^}r0Tq5mc61poKYVg4;4nyHX!0{nk!-ptX}vN=|{o|hh12o zs$bF0C@7WudWkDV@c<{s@Fe{X%jwNxF?798Mqc|9@1KZM2nu&53JBQEU12lT*RMV9 zjYu}sCtP`h-apI3yI20Pu`W5>_@0mYgP|szT)5vm&63lXL-vESYbd8jqk#l9{ErI4 z`TmC8*Wz|UEZmK}1^HNrFM-MfddjF-Y9^hXl*?k2c0j%R4g~Uy-yxH&;RMe>!ktCc zWvw0C(i`+euu%-07b@JNiYSOhhvdE=argZ-elrDih4bJ?!+l0+cvpj8b^s69KJXA2 z){K_g2$g=JsiDevkegWt{dx3-JS`{P8jtw%vDW830pZT=20fZW*CHW2&cJ(YHM!B) zd8~i(Y#7bcWqTS;;N-x)MSMyA8~^wI4r;+(vX5)frO(ks+sE)~Fs*GYI-1aDd|klf zcpoIn49gLrHLt!8d#vmJN=((um$9{K{Ea_*Z-y431Y^(#BgwbH0=C)ac(z99p@)947`cEC_agK^n{S9gy& zw`tjCzmk5!269^6C@@IeoE$=GJ=5{r0Cj&R@~g_ zXjs%>h=>M~e!U5qbSQ0o$lH~a&U#wbN!Mt;1Dni;)Ad3Dtn*&*VZ(FU;zn98c6U>! zcpLP@`syf$bdM=Z+WJ{D*rS)o*X_S#>g4Y%zUVtx_y>X@8wFSwFpClBd~Klmw!^7o z^)}3#lRnCT(zfzn`ScR|ud|zTc6>v&w$!01laILyu$2z;$}STc-f|A!F$t+(_*iUl zPn;c5;sUI|W!cSkeVD>6YxAyE&tA+whUdAJC~-i;TuV{5N{%%yRlz3W$0Ij&!f?HL zp|xas(+Xj-tIwpGuND6$V~oB?WDBoDsCenMK)1Y-VI-o=^J9(bQSR1p>_1CW-kOg(52v0?&P-{` z9WVM|+Llv>-rJyo190mAHPA^WM|OaL1|RR+Ir~a0n8gX8zXnB>kDo$oLsCAQ8Q#N` zgmp;TI%>ap3N!4H0$eCHXH0z2)W!SkV6s7vxuddvqaeDhD=F!IfLw#KExS*ctBYW| zPYgi_F0Mw=>#ngOy+PHD@4erV_$yjT$4`=#5dW}pIk&C-6;WiZjj}p3`cJbX^kG%nSO zhcw{0`$Dn{&hm^yru#MReDWZ*cqg`{-h*K7Bjx+Nhj4HKA(Sq9p=s^&E(e>lV2%XN zoiBht26Lop*S%oAf|X!MmJ1 zz{O2!XBn*WA);ZAxk@3UAk^_s^v5A670$!N9T`#`b1ZFrOR8X`KdMlvpIv~*_3NCe ze_7!i^SK0 zyO4d0rPGu`QXtF(Fit-Q-%cPClJkmo-^1zu(9~bTGxwzxdSueVhv+LE=1vk!rdNrIp;Mj z*_b$-EM6kAP!*My{XYz<@(h$7uMB8KA@`>)Mf%uf*eb8<23JH0xE~f}whdAycJA%% zNl^@CeHvO8cvN{xa_Vlyf>NXRo1FRqjU8)|jt+Y%B)#QPq(padmSFa|*LpMYc;JKh zox+Q`VRx?b?%T|9V08eMOoK%6vXEKf7zZ4TyK@JG0VrdSvU%=h%B7)}$^%M1&(Y_t z)<{3g(3#|VpoR)&Th^0skEok+;>CFTFV-C)^|U6c&SeP+yf)(I?kSx{uB6HTT9C!7I(}m@!V?^~3E4ob1VA6W0)j zj=Jlr`p?%#53Z|B_myAtGOiGYel@S_bUE$!znn}rJxk=YdG)1!K6-0kXQde6lCWW_9AEDddDLgk zsKYpJd;MSVdA^f(7h!xJ$1SXC+?8c(QWEze0h^^*F;5y}4>7F7aotStkwgM-RMSt1 zEUN9EFxT10>=Vh`!t8b}met~m_Ks3_s1gksMhJ>G0JxzXM_?G#a$M4?VBzwnpsiHY z=!XvSjK9N8H7Qm$X5r1oO7y!aL5sDA*_nUQ{f4mv)K0(iGc0hFUfZ zj|)?ip%zRhm?I*k!nKAO&nkP^avdA`Qw>z-`~RV#)Ix_V)!YjEf{J)BTuGAJw(3}b z-ZX2g;YXA^fMoxzdmPf%W}gauZ0LF?2wkLCP?n)aM2Cih7I>W|H`eff4gvkfyeqGA4gi3+)%K>&$-IGXtcZf7{ z+}n!{L-q0_i@tLeFbN$KI7Pta=V+8MvWBaF&WM-f*$4n_y^ezX)LZ|tyhemRhq=K% zxsjs$sk%DC8nz-?;0zli>9s21wV)N{K&S>rW^oGb^C#hG0NXpp@%16pH{p(L!%7xN zpxfP{Ey~o(c{k?|dBV*5%Kk@gFXtz2PZ$n#NEuT;bIf7w+q)enLA}Ms>?CCnu1;o8iSb7H9(^nx3DTbA_j>t{2%q^CvK!Y+r^01g z#W3EO7#vaHWW1W=+H6xCE5(aH6`I9ZjIRHs& z5Ye$GXKnUB@OzM8Du!4gijyT5&44zqoPx9VTaAor8%?>mW?RVgMQSdQfMQFI6-!Ru zt(fZ$>r?dRg}}hTuF2Xbv2h32O~}srK{og<7Mk)%71KRX9Uh}D6cEj(WLDcx4s?z_ z0@k<>QxD-?JAk124NhM>=9=LorjYL)#fm@$f+y4nmaKVY^Cxjn2wpch4?0P>&sRa8 z2s1|i&?i2UyAKc7zW{f;$4%|JD$AE)=&ysDAdEf$?r4EOxua7-vnT}7e&3o!cOTc# z{3c*T{5T2qkkmT==6@Dd^dWd9hvs9z%6$pd_IVX4-zX4vI%htA823;Ghjb%@-T zNweOX4g)?4Zidap*YJ%lV}Gk(4?A-|Rbw9=@0L|~4#)z8UZw4UWIY1mvjO)HuviYJ z%T95YmSds!bJ<=N&aynGJgZK_a#+^=!u(_`4{lx%X2E~?o_kq zHZ9s##M9T`Dqe^v}L7j_$9%uE`X9e?vbNvt~u<#kx60i|5@lT>Xh6 zn8{KD1>V<(h$wJ)Q+s9E@;f4gSb^Bdh>L7c{HDp4WTngP#%yXmQrJw%Gif)b)qZTs zHD13Xj;KccWV#X1R9*5CQcEmrU))m49D3Y2+5Gr>hbPgF1g8*8Awftuh4|`#QP9ND z-oh!!Hsa@j-m+%Tf7R&yVoc7z!G%8I!+7y2XyvvEn#8W=ap3~HRssGYwm0Ze*;h;$ z6RItJhV4E#v6j_#tK*$dok2x-q-V~RWm!?xSVv%JFaC49hQGDCSyOq|PEI$5H#cND zMqgBkyeXD$^Of$~e{Ru0cc-}V{C<-22Se5>ohkBwHhl!qB*|A3rj8%|WnT{g!%l&C zuUb`X+WTmZ;X844AqWDCnZ2LxAi~2P#5M{=OBz33uT9iv-XwAUKCLS+$TG@}DlM&) zouLvP2#6KnQ+^Siy=pXkL8L0oR|o%!9EJjoJwvRYJj!v`ZqEouD<0i_d@3Hm`I&10 zGgWk{=e!lNO+|w96XJR2?8Tac597zqwt4Sm3DT(x{k&f7ltv)MU{d--yOdZoV_ zo3OC3=2CNrD6vNFa(L%4j!u>hM1VAglv`*#pLblQ7DpbM68)Nq(Z1Pf3`0^*?wkG5 zJUpM(sk{tpp%%r#DGOk~a(Xf6#SA7LPTFWlJ^TiEH&me#@P4V%1APUQd+{AV>7|Dq z?GXJ3#$r$}1i^q%34#6zEW~hbCf8K4*>K>_V3D%)pOnI6LriO&8>7oh^3WeW&;7NH znM^QT+4#XV92(|Zt>v`;sdhRj@u1RG^F?be*X{@eeu^5BExkt zv^`BMbQArW0aO$Fcd3nNV3arUs^8!rVZTRre+|8mdGL4WMV3iP81^3Km!*O8zl2<% znqB%nDa)$??MCOSO&Jm6u0YFecEN!)%OKh92=`KkS@@5*xB*EdWl7PWt70y#jkkQy zWm-EZ9*NRV9Or+yw?2Fc*s9I&W&PCePJ`ShXPD2(2>#h0dYJ!91^A_fktiM-PGm`} z8BCfZ0xe2q9R~d6%X_lVv<2jZS4llLCkv0z)D{=cfiZQ~wZ>oY?TF?Lm!R8C?{%&4 z(DbN7+8d0>8S%wSaC?yygc)XfHwl*_Y?E0cWwJiApokRIXRsU6yxG2Ihs)kxw%DOP`vzN!hD1^RN`(PIg+-|esR zGO#lnBtR(O)8V;Ov)#;L^I#T1aYUbgFayV=w!xyBY4{NO$^R;wmBJ2ZdgyS*iTwL; zKC|)sO-=NO?}}VyFd=ryTU z+QKi_b|onUxchA==rJU*^I%;ESqKsapXbRjNJ;N~>F0N8OGzy_)Xy?6R#5$V$M=Ky zGLPox%v}pPXVTnD|9BD~-(Ql`@guHRi^clcc@tmAua}*hC7&kth8#K!f4HBg8Pb3k zfTl%{mhOEWXO9nE&N(p`9M3<2*i*2R7(yF>Bm|y^OKdE#G#Qyv%CG4vTV#dlNRSyN z2xVDeMXz`(HxiuA;Bd_M9jxB7UVuEI@=-bFE;q zESg|-L{cp_ak#I{Oz35u)ui*6LkCQYj@VDYu(Jzs6b3qRpLmbE-P>&0g# zEN{H+nRMXsI2su*csYM}tqkSJ?Z6Vq`9J`6B-N?#=2=@jh2S$E&fBI{ z7`0t-i9btPj+32;H4KG!`Q6*LOG&mB-}3clXSzyDxC}x*DB&DXjPN~V#M*;W0@W!` z!+X6nRE+g4UZlPgOtX}Gn?O9y!Oj;p!|;uzwZN{kYXZh8^3s}kFj5FbzilOlz zF*P#m<)I9{)^e=fF*nN8AR1(hY^Dwd5g+oR2&h%OC{|eZ*N1Z#$dz9eC@#b>_m=pf zEYw-(t3D6^phVS|cP2E61~w+Dc34qDMZy3TO6fEEko|&1RJGkN2>3}wVM$d{6p1RA;-} zkXOBH<^^v?v}Hgzh$!KhB`n;FVA{pAV7qPqFk}|%MV?w4fk|WZ16QiC8poNB}{lOV<_S&Vl0}vY7sjhud)4mCP!_1ckGYloq&%x6!aYsa@qEqco_GJ!f z8mGm0iFl9!~_G{35aiiIaMHGn}H8v zZ53v;AYc6%Mb6uKs2zCmzMpXAv*J-I4=w^(5Gl~d_&7viNfvTqM)>JS&x>zdF3hlg z4#IjUE0U>CT!4Htz)!P*IfR)z0pnKO1&MXn@u?ir;2+66ZG4lT z4v#=Qk?2)G<&oweeDx>{0q*%yjtcyDo#r}^yd^lip?|OR1}nMVBtYjil=<`Ro_;q7 zob9a7;pn1a)uS38e>`w>8~QXu&zzm;EE1tbtGWrbRXM1Th3EFyGkk}5O`;JtZ2&I< z6aQDfO^6K9nzbw*HFsoVWc(!Z0$&lDg_Sj`YmF6nOg;JRBL0u?nooRf_=D0t`cwRb z{&e^$)BNc8i*VW;|0S8-w#juCDMvSx5bk+n+IITkmr)T-LBeM;xk_zQ1KEA={>M<% z8)h%qt&Ci1^Cw?KTTEymR_n+jMT~r#BhXX%G#0nx2N))>D>Xii%Kgm0(_^9^ajc|> zWvmkImwzt-;c{vT-zOJGxADPk>Cn!~VK61g9i~!Q#`Gf}sJ60r*DjV7Si?_T$W7|; z4`YI7{BZ9Gh<_QyGe)&Z&Nx+xzMOu*Nq}}klt!nSW;TU_Cxx;=dGRF_5EtPYqEzV`jdQC_R@RW~Tl% zOGk8Cj?Uz5X!G0@3jj$l=*P$t`eK|UKYY|!o%RzMZ3eN>*$F9FNq=}|bJ zNyp?X8=6l3pa4vJ4Cvs&$LJ3b88lz_A_@dJMPP!GDbq0@?q7vvyv&D?!QQ%W60lg; zqux+R6@_PVRr*F^(eZ$^AAV;4G&3(V8c1~6FJfsn$`nl9-tAry3X;A)#2p8l7*w@R zKCKVSc*1EbqY9nY-Nq+QPxXR?(16^JvIhciCni`gm#k8Xx|xlau^ZY`yb+d7?Lo5A zMoslgd62dLG{rGX>i%0%6LWFE1$QU3@bM+}3dsaDiw@drq(^WQ+3d|!${i`6 zS~GSg^E*416v((!prfiyzuvvSD*G-iO9H~kD3!zzk6-61J`_uKcQWWfxE)R|@v-sg zj=Bjz9@+mU#2RjAH4MMhdkjstyReqC6sGPu#MN8qwbEbN*xTn^&H8?lw^(GOEbb7= z@}|4L3e2aC#n?p&L_{_~CPsPpqp(kc2RAW`QQ>%Whv2XONPuBX$rB3RNfksr560rk zx(R~X#r%~n5gIv~Q{9bJJnOuZ>r*IlA2gH6KV;ph*NC|L{l&wdZ;N*wBmadIO-lmpaMfqy9^zyH4unOwH*2uE;%jb1; zdY6{);u;Y9GYC8GJsi;aIj z-~;G@STRxaZs2&O5AxQhNfd8OOs>uTLTPyx9v5n`oc3PB_e6E!rx>a>>zPD{XZAuL zX|S{rvX~!HPgbf43BfSa)x04xP=L(F78lM3Qep&nsnf?gmT6TJ+vO~INDFQw?rTol z-xF_?AifSnaN~_sH-l$#X#8F9lVS1ze>|tWn8&#f&V86FWAW*dmb;+CJMUM*2(ka&Q7OfT%i!; zHJjK{I{H~hV2^;?bh?o+y9#Fd3H#6rWNp4Gks38}Wm0#We7sO2?hmk==w#`5x#>B2 zD^^eQ^o8Sv{zr0Bz}|!CtEMQ$=D8kST4S7X<2Wx$#K+9gAg!f?XHNGarc_Iiy4d1s zYNW=OdURZDJXCHt+1pCoiN!1v#~y}s(~ z7ND=cnT|;(Pi8L7PaH=eK9}trIe+7IR*{xcc%CA*+l_|su?jv7Oa+aAh?Z-1>It~{ zjJ;&$S!~yE)VMvZb*>t`)7+XFc)s2Se341Ar;UBGQJEqKS{8BRXf2h3V%??>>`e8q zP}2ImE+)rh2&3(w^5PdHZl7Ae!oaXx#0t5LaDc~X2l5zQf-;PC!RW}*xoX9lD!@8U zmMZ!z0zBuCa10y&P|=$?C622!t7}c;v@Ef8R)tcLv6OnGE<{1`vUl??t$N&feZ-Q{ znGKabxjxe}Xa5YFGHtn}Zoq0Oq}_-_1)f&T%FwsyVU%{}+#)lUsU`G*SV;1%oT@?a zt}ZjJ)pL)^+j&Kn>7<0?i-t%=T~F_RnVJbA3dAthNy#;iGBru6CytC|E@V;zA++>( zn7OYFzv$HlN+Rlqw|{;>%YG9_dY;9t@dU0ynQr;@{*WVYSb!4B4-w*lz%J`6!VV%} zSI;;#zH)8GuNmSgp{_T`t9xv&4qkRg^&yWQY(l!Y9gMu(x4 zwWgNq?a#eVj%I}XkekZcJsTd_m0;1Uf9q&bAmKp&8U$zO-ac6nG^I^#;MVwL#wmyZ zE=mgRY~0X2$*Hz6C(AKFpSGPMh%(>9-Nj8I)v_-QB;XYO`IXB$dlK>3%s{QT$G)m<;ozfkl^|ehJ`V^Y_e&qp+aT#46 zd1SA9DdZjw!T)c$<3(obD2$>dv^4biVicj5+pqMVHFqGzF$qE|uQOx|NY zJMK&VS#p{>K}V}p)(*h&lpu}i8MrF;l1)AkAR^%b8w{9kXy77dnh%2Q&Wja>*%(Ny z+|=5oQ|XUFKZ~LJ%)4v{p=p>K{Qbkh`?IE;T!bnrBP{-cJ6)lA-F*^6(zp&CI$W`@ z6qP?EoSzD#+BHs8A$K&`y>ZsUk;P}ogA^Y|Dk&H;HzYWblzF@q-P9^m{PJ^>Je%-0g__NR)w>^r@6$wOGvU&3uB67_ zX-a)qqFjBT{rg7+M_G*`dM@XNV0>)&;6zMV5n!tUfS;{Jzc#xJ1s-r z9L!+|h`T-@h-o%Ez9Shpg`9-FhJg-U@9X=J;Njj)wl2V(QiStu2&t5E*4#3puVN8u zr+Tq}R4VNXt`XqY5WbJjM(8Xa)Du$o&14Kiz2SEGpeYXlY_bEx(x9i|UJAF1ydpn0 zo@+3o%VIfpRnx0OJ^375&D6t-`XUNnfIC?{w8;4hU%!jWf;JlXbC0Y=MUllULUy}I zZ&#*-4pu*dMn=G&Oxd<}73<>dlczo`C>Mp?a8Hz-igl5`ii%SKdds5gz={m?#sHD} zsqo^e0Zp85rsA->c8@`t`2OTU{supF_#x16W+0uyyFVO9W`Z`p1WF|a51RChPF4+WbOuIIM6eX(xT zdyTLtnA26n9Q}n&8}wwzI{V^dhZWPfUTsuw(F*wE>EC{)(>U;x$;G0&g0qIQwJfb! zP>E|D?(_7C(%V}Zm$N)vX?nlJ%EO|Op(26?;`4C`<;;r*T>R2cdQlOGb&o;5P^vH# z2h{2MVScy3O;!h&`D}T}F)Mx)VRinjl^~*}wv%0PF@Jnmp+%?$SJSSMoOSnlA5xzf z%+VE%%KBwPJKvgf?JeU3T)@bOaZOrofpWHqp3s(|RrslhUd8rt*BfiO(HWNnR*brn z2!`;?3bumF2IA`#ZOQvV{+cn>vY*Z5A05xx=iwe)MoJY1@khS4l_a@MlUwC{Rwi1p zZw-eX)?RZE5e7$>!6)3G7@2+jSDEDxx0aDe7lpG%JE$j>)!spTj9I4Gxi+FKKRjYz zw?heAbsqHDwnrK>L09h$=50)%4lx_Yhr|8()&ffhjL1lWsEBn$ z%jz1w{#_2zBKObl5wlEZ9V>>&m%$=*0zF%1N!5~Tu8;kB-q`K)q_H%XNX_!TkMHhs zlbya0WoqqJqNq&H!K&eRv7S3d{{05zV$MT7=VIMCt%Z#hCKsXp7*oSwb8({gHj8z8 zAuq>uqZHuz@``vh;T)hZx&A4E-Y+eyq1Es?7ky`dI<8p=TR*{bf4caZw~PVIce9;0 z&71dTLGGG-s^_#>YFpo{V+Qt)br2Aelx%vdlc6io(IXx=qL{hsGE14w1(^jz#-=XJmTKpuc7g8Qtl;DI2IV)SO^h0~toR6A=r@B^ z?A|4iI4fPP_eglP6G1sVhn7r_EOGJ}0p6J$kyXU6re;{8M9`0CWQu)5QnELSR#}jl zu76S^ldi2U)?D`lj;Aof!JH={z3S?}2J`_TrS-74Ow>d=-4NBZ6JUDimsz~>BcTz=k8Xk&8)2%-adsV)4$(78o%B?^iw`) z;uyLC2}^@krN%YFn?FO5^?G=(FRd6yFiKbqy~XvE zpVu$oJx7~BEM-NkmE_3b$fsVV;k^y`w+{!IU_7Dx)<+mWh~)9!NG`00nQ|@ljecLr zs|>+xARL(6-)6l`bl*II_H3ee!S}%xfO_M)8T;mQf>d&!pO>#da0x_`oQWKe)(qLR!QTgW_vqms1|qPc zK`&`85&A#&WVHpMDd9QL1JAq5Y^Ft9C?r0XxH=<)gnDJ@)o%&)4@;@=VG*{gq+M@J zX7>3<7omW{|0HFstP@v4(Sf^nlsco)*tiG6_b}(Fkf56rDl@Cy^uNW}uHe1#a_!tq zoV;J<@K-`rV(;P9s3M5`-rNn~%IRi5nAyG4pBh%_U9{0&<2$&`ZBr{hIrf01^Px=S z-c-4G=|m=t$9{37@9a?isFFFT9xxqFv|E{7iZu=s}w*vFzX*cF(v8T~d9W7XX)(V6}?U$T>E`58@l96Eeg)PKTRmKT+( zY@%+H`GNlnT-tG%`R^L19Z0uaDoK1g+Ym@#wf@z`jq^gB>=rn8ob;bqN7>=cmF&pY zKvp>Ktf$=!(bg|lFz0BH&G%p>J?}tLYCY2LQc&%qt6x;JhI!wvwaNK|MjZG9AT2_$ zK>A`CtGJZ;;oN5bO22vRcQGQ5+C=(#aCp9C@6>wPyJu3ZWu`VZ3aQ9ro=ykI0?X$v z{?5L9efz_k+mF%{V>c`TZ^PKI1|wiksNLX)UXy6Wrc|=*vS=azQ!rP z1W!ilMhZpiW-Ocq>pJDVRNg`aB>IyHwpJBJXv%815!CZ-%381D=^0NZq~~vRxz*1f zj93#Qbi`*jGcaie9xjmtrw9Qq=4$Q?L%m_kXpAg|^GJTAw+#ZkBwuf@_;;bf1?)33 z)4q|pCY0P*&C}uHZseC1#(q?1x=xx!M`Jy6H}K{%tvg$VFwbSk_%(~%d%HmA%G09J zO2d=jtfj%*fdyH;4N{s)@9i1uOjgkHq>2k<{S$>Z<=@<_zvw4Jh{)G@ce*BLv|sj$Cm!B5U(WbQsmRmX)yN9_J-8r-Y_`mmqYtx|7Ni;nFcBw=QXL$&+ddwyFnehDIe&Zneti8Zip1kL@3J_YoL=W zznrRbSG^$F8{tc%x|ca12(m>mOGg*uW+Y-^Y9A@Mk9q@C`c(zr&{P@>1tr9@Tai7>B@!weR90=MEUD7G(=>8{aW&j zL`o9|DSCfaUZ`Y+<*j7sG9@(_2ccpSwaYdJ;gmv~(b5azyzwX_k#r=y<~0%ny00;W z`0nLLhSoEQ)wK+zWrV)FF@75wA)qfRd%w!)e!!(+3jv{RR}s*3W>bae^O}vxcF@F+ zv)bMJ#CO7m%j0~h9*5`K7Y(d5Zl_!ha@W_R(j-{rlX|MC%uxTW#)q%)@kkzrxAjK_ zU=!^IJTb&R?7RI3kzpDh0q!~(#xR;c#Y{*HpP<|4i8~aS*I$8M^od+{PYG@@GvD)A zYE@v#M{!g_TK>2WQb_c@P1W>@46-wINXC5hgT7eo5ud8Y&V2|T>_mCU)byz>k>7o| z&uAsIbN=Y)D0VinJ@g>;q8~*?-+Ra0;fHzao?ee%una0KX6*Jb5Eh^9nrWA6d%d8k znw0FDD-;tKOk*R!hLc%>^GO73NQ0|DI&2th7|z+*{_MGge5)`abgm_W{Aunf16U4` z-h#LM@`+z2#xO3hz#S4D%IVyhPHe)ciIBBC99oNKiPViwn!}PlcGrHRhYANrMwk$Y zF(R`QmBaqfYV9`SZ9g=H!VsTcPGX$10f&5(_p2vgJ#ix|ikTO{h#QK;e|HC}?>|nr zCv?@|@~p@4#Sx&S`!nsK5m*oif3YBp@K^jXaMI=pEU9c4$Fzsl_Bg6~2$CPZX$pVF zQQL`U&=%fIK|Cru>d2LY>SQ|^=RI2wQP_-Je%!Eca_FNR zuV;Bja(iq+UW*@pjnDk#v-;};15_Jakc4gGq$!YhDGR_i-i&S()?nyxLw9MlE=P{a z`SShg*iJI`s_HFkhPV$~I$^U_PRYEth~mmq6nY;2>bo<@ga}(gbDOx|a`C%Riwteq zGx%v{60mzs^K{+_(b=z(@C0mj8fse|TfMBP=q^8T${FM!+S3YYy-oX^eg3(B$Fmz- zBTQ`3PU?1)#mZasAYH3nS!Vy9^>sCQazY^)$1&!;au7RWRnIMHJ-+f9JwN)3Gqyw5 z|C)k^)t6UYAebe`6BL%c{V(SBHgH8B&9F`O?LY)(s_Bnjg*|Y3A2L z{=S)`wa4tb_@09q)1NI+#@RWtxGdryacbE}Ld#KIWRv`#(}&$zyYlg4Om$f$TZMyu znca}^bAl57FW&sxcuKzHMp>9R2d<2tr$cQSHMO;S)BoBd)vd0TTfO#sDyfAMSSm>`R*kS? zfx54L|6B|KHOD4}@NVs^zBE`@e;1$zv^n-CV}lQG8KRhaV}~~reERsl^--%jI|h9| z^Fg(%`fC=+#m&*QQUh+ECL%Y4*`c{xy083qtrA14D-A{b`>Pjii>W;W;)mCLW?H4I z#T9N5j1rkC3-DaMyQ(eP%aT6jCb&S}+f9Gc(e<%FmJCSVEv;d^F*A4OtNWSn{SXLq zJo^YXpNk&=q18I{o_1O7ZBD!-Z^7b44V7$SDfY$cAq8^RdtN+_(U%g~(VHK`we$CW z&;i#1Q7vy5ml*~cLbtB(ibfP z^4G3`tH2xTjXgD<7FB8+u`85ZTdyRb{{EE^9nqv;(YOA-VvufGIf6I*-V^!Ii2T+D z9^Iq1Xz$7|@ToJwqDP+_`w_rV@XK&tEUHbV<8Vb7pLJ|9@Ih)Lfo{@A;OZj_q4#n6 zES$U>@K>7(Yjv(Wv7~kiU5*vL5^dSlVb-!#s(P|K?z$V6ZuTWa-lI}kfiVick(Hsy z8Em+ty=PO02lBs_|E$!RCb~eV{NMh&{QLj5_wB0rlNA~ehv}~{_uO2R3kpuCeQjaM z6u`GV6*+PL!vgzF66(MfWgW;9*twVO_e=s&`lo3H50u#MqA}$AT=8tcAPjB!6fe4k zmr(wqBOQ4akxo!jCT9^l=!D8OlsYS+Z5vig8@{uD?`sZH{NH@($}jj*JY|j8|7Q6q@(yX z@R%nlf)&N|ZHhD(KV{N?QHY4SbUo9>R0rK4J*b#?`T)mKQB~tPX>FipD8VU%#c@o1 z>u|r^{U93qiEF?4>HiR{22sT1CBBnwZrp5%H_o-)syE7j!bMBtqG5?KMwwPVIgz+c z(ij-7xShsi5f<f9mj}ut&2sN+o*PvpfwPx-j)n%{g1tm==3EK1=LXwALCV#wd&Go%*j6CACX7Mb>W-bX~~ z+8K;_$`F1wR=`DUq26A8^ou3L4O(Fmc^>X#B;mDNeC(b7?gJ5wbFUe|$u(iysqL%k z44YLB6sgWoG)QTKJFR?(m7hrXyKNBG;cv;Igl?F)o?0?YWx7(JI#K*>8azRO<^CI` zitzr>%JMrqHDKo=HygeIvHeXOHbE3X78u$;@>HHT?FjSCPcR#~ z|8Jv(vkd{~9e&slFv^0E2N-1V1?oBY`fee4vIT80wnUd;-FnNeUQXZpP`ie{<(VGa2>IbLU|}Gvh8Q2t-rKOCi!4JCfNJ}+@oU@ zHgS3#W|fhRjm=MA`2Q`3)F+sCC$anapkf zv@3uwlHk5~te@F*euVmswWc67&+jQ~KV?bpLWPM}9$Lq zVfwrcknVP-z85@d8tR{8h$cWq3Orpic{VvVxLw|-PwC;rf7=v03^9N4*#3hgc940I z?hr`=<6Z~VkP^S(j*z)TrkoKG9mBmGsQCgk}JHuTvAR_27+;ke7`7MBZ) zYpkZcGD#S@NamQLeWd36ux==ADSkFLYIpn^d?UqDbKpC>(LUaN^2Y5SvPS{X^qiJG zq2Fx$fD-0J)R+D-g0#+-tG{^bt1o5rYnaRdpOZa|JtkklgA6L-JB``?>7J#}+xeJz zC~E1FBUZb$4obVZUR|{{JNUALO!}B~80qrYEptOuz>$cq;Km|l@u{UzVf&r|k=@J; z*FA!{Zj&b~3m2jhksG!6BS89n3DdoMCLDLKWUAj$WRZ&pAL{m#a+UbJ2c^ZrV5S^I z)3^l%PA@zF08}u&b+sy};`s&nx?)l{Xl&+N-p{@L8F;n;@zxbluE43-wru3d^ND`Y zhPwrL=9l(oVmA`^l?)f8a2msH4eoMcT@Q0K&%je*h3yFs;_vN6QZZLH&6JmWHU#cB zk?fW|P)8ok4lP+#YBL1!Vq?=nxF@>oNA*5OieYYIj1+AY!5?~LlV4v&4k^#%Iu6Gv z5LS-ZUi5rvwr{aqVP#uuSAsjM@Hosk%*2Fl1Q-?buj?CA(vl35A}QLe<&$u* zqL(=%XRxq|<4et}J3KYAzcIawPt4f6n9EUO`nlY%z7FE?!twDK7_TOSU|Y=!tedpv zm>U6h=wFlAfTvyyOz)DXZ40S=W^IXZRIk))W}yrx19ymJrq->o(znm}aADzV!m#Dx zwV1LI4=4nKlz`2-Pdgb)<+9o9j-4_{RX=6&__WOpt-yJorrW^n{K*Uq#j{$CwT~Zf zJPP?RqV_X$2Qt$en*Y`0m`%{HTO;NZ0j@^5?5gPInmdi6fF!}Th~g-T>bJ*)cHy`y zHs>eSCh!wnRTx65LK`BO8U8D9J= zRQ*IF@XF(`)I^z4?Q5@!*Vj*Z2M1&>?%tvOWemU3nE_U*?jDYRIg1MoO_9g;1aAhW zUeob>U!oduzVfhefCw|zPBi^A{2Ov70IkmH#Ja#F`lP6+ZCQ2wY@dz0adL(v0%iXM zSjcnq1AO=RpK6>|jd$K+{(p{+Df_zP;H|WG!{N-&UKX3s!^mHAnN}iA*qe4J<8& zwixq7f|+|5_9R@M1C_ z#n0u$HD6Y(HM)ev0{QuPZ-PBES6V0#wCQf&wFlaG5E!C@1vdYj+~VkuR|^)zfbbRq z;(JJdamJ7LQ2E^^^T$BYA8j%q0~?u5fQw%vja4KmsOil>y3vMtAI1ON=dpPfVdD-WSSsbt;8p_t!hhRH~g9WmoCkZOG@}nl2Ymw z;m=sYW^$3k^CxHNrlfWORM=^2+2O5R;ypC1$6-^ef)+)DwiWfEj&iI1Qdqh(&3W1c_GbIPq=jVAApE4f;Im;Sui zbaT!;1>(X9mmP`>LopvF)PJ#m^n2X_YZd;`y{RfF<$=4{_l-&(w zNm{XO?@Ja4OO?eGrfX6uJ7yK~q&}y7h5SD3=Ez}=*3P8>5ZZ!k$R0%{3YD5=mF9#m zDHB;xsYz}>-nddjaCG7CL>I`DRFS zy31*LjDJ@f=BLM`S&A24X}#-|ff+2EcF%ay0zhn6pYFT5#W|`%QQ4Hf%rcF#!?UMF-vVc&&=t$CA*WeXX)&8T0MmH2NiWYu^ls{DDevy9EsqqQC-(3 z0&8SlcVN38f+@i6ht@>A0odvXrM9yWmW6?HpnV9k#3oZ!@Irc{8gwBbhy4(qElH9-pj&Fy(l0U`#|Jg%tT6S# zpw|?n3Se4#s4R@0|5~WzKTOG)zvbw{fBOj3D;WO$O)-4{(!}09#L=h3g87Bq$nCb= z{xD4S=-i&HhOP4Xp;qC+a;{&C!oze@wJJoQlY$_2F298eZyylxIkq3I_u*9GXj1N( z$MIy7Kn>GIg)cGjS^5~q)^=@`+f$##g3n2!^J$BqckuWNdRLnBWB-8%*V-JC5s(Oa zRAjSN5cmsa^&CGG%{=dK82pst_^$_FN363~Jt*k}z_NrXuOxN*=3LhMEt|TP3M2%m zvY$RKJka_-?SX*Rz_Qqzf`lAnrmNX<^E31n1OTl%EQD=<@LEcSqF@T7eWJffskoN! z0!I?CZGWS|PthX%j?CYf)uOp-*r$oIKaE+bG+1+>$`2p)bqF7;9%>Pa?{(fbI;~H) zCi!o-mG(ZkeOLMRVDe7l1aIB@HfH_g7dL%n=2Hy_qaW?G?tU)nIK6yAPntBGbl};) z6^OueB?4Af*IqC*$76y2q{SZma&C%&4?Y_QS`24V+@^7F_I0bdM6SzL_Zv+jP6bUp zGCE}NXm4=dT-HuV{qKmY`VbaXKYw5V+P9J5!ewA&T#6tzIDU=l=E z{#97p4pz;W&$xbkpAMfHe2pC$^nfqNqgdhnKC4Bnrt~so+6gnHhOALEQOPCi>8#MFz}e2$RQ(k;A~DkATRTD4PgFw+|h?s`?L?mhyEYe2|l zS9?_WMorr2R&2}VD3NQ32y^-SkEYn>HPDZo{rlA-O=ATD3#cg$5RuOVnEV4a<;jT| z)eth}nnl1!JspjLUWWXohAed-lk6ONH0vDagL5k%RQt16ot~Z^q6R71!pu_U@IX=j zCDl8*ZML9*-yx?PA1f2*Do9uB@C@vbVk01IVx@bMPRaZrf9xY{58gYnK}Mx2C&9l$ zD|L;dx-kM&T?&jz6Lz1^%JVJzgGH+W4;^%`29vfKzvF8Us|PswS6z4Dj+8E_im}`; zk-;J)d}jL%2G_k2@;$xHw@;%W z8i`F7%;S~qf@GB$(n4%~(WwXzKfqGHZ$;J@kPZKgcJ<>r;2;|`wxGhuE-S{%0+C-H z?QRvNg1~_70>O(wq7MJ);BIUiNpY3G1CzWP^XP((^!fmc<2U7ZQGWV=v-(C3!0rw^ z!Qbx=-I1l}^{rj%BYka(nm2Hi8xWMH$!H0a_U<`b7FX@u*DcBjj(V&<-{L%#`S60^ z>V2jtk+uzk4S2%%)Z(aUo=GP%nXGUX{}G64Am>#{X9*zSCp#qFFs#L14Djb6F%GP+VIqp zgp7}bWI;x)fX9C-cWe*|T4ZjkIst8Tjm&l;R+PADzBB2UQWYmIn&e{IlDm)*qICTr zxucBEL`m5{!+U?XyTI>WiLpjOfs9$b)rT?RSz(wsJm9X86B(tr@gZ^*{O*-u`vIL2 z0(Y1VTKi{(c`wzQd3Ng-681zf-nweFBrIj&j>g>2w!O|N%#oozo+A>ylU(0%(|P;S~(758uOq947u>X=fe})!xVP(L#$< zin2tyXh_N~JC!WiWlfewh?-<6#E1}$Wvn5D&{(stGb)sQCk9y}dzQkC2G8$|d!Ozt z_dd__dgc!=!+CM$oZtDL-}(MNpZACTkR<$PO&6GRP&8e9^MM`m=1^YX5eX?GXzN0* zGf&`21|nc+7V<+&4&`vrz=-!&+8$N~oSe zBO}GB23V+}FK(?YO4V)>C+abr{>XVca#u{8t^6-m<#MRUE9Gt0!QWFWZWh?gwn<3k zz<3u&_pAGTm?h34QRU^T=yDhEM87B&$|=H3+ojSqug~&OM53F^;h!F;XFfp<-b_+h zCmmdSH;D3(cm(^aSZj4g_0u{P%qGnD?QeCQ{PnqPq>Mmdt`oYhUN;_BT`1E=}>bRMu zujm{LaDGL0T>NCj)p=BDGjmEPIw!_>#CzBK!qs{GrRbv?moR7dJroqJc;KUv$^qL- zL6v_dkcJv|-y&7+Ww>p_^x#iz}=A9mCo)+15jK-~$5wgook#LutjDI+g z8>rrc+js1fh8J9JG@-LQg>LYsej8R$r?`-tt#u(xMa&aBfLzLT7MjSV?)A7D(?}13 zAN=o9qZb$~peTaTLf(!Z6;N-pnTOk~bx-SVll*NN0#_Jyl~VniB2?!JogVq^assON z%XHk%#~qyL`3eO<{nUkp(@^(WrW*^Kede$0o<0!6tJsA;7x^c8L^tuSRmkUVM~grw z%yudjCU5v#do}X&*mkWKTwx=^hv{q2N52h;MDQd5cG}=epBgMb46Is0|Nc6-?S*H9 zWlO$1DBS!<`0Es$i$7~pw>X6Fg9mRDcNTqnZ<~w%^5w|$Zy!R7;{t)|=f#91UgW|3 zq8h8yqjy2k;PEow+X1fm4{XpMcBe2_3emgfqC1?w<0Hshn%QOlqJwS16*EJT6^W#A z2tKj)@5P53&gXSv+Ng#sf4io>Ns0L0djA^~HvSFIsTJF@v^drP7~43Ib^}bIfU)hq z^5vKt!sS>wItU06OjP#UWi~dQG!(4jWnplNdkWg%VC;4IZ+eKuV-!Ue7Vc4UL;#Zq z-Xt>`rtx_;Eiq8T`J;>WQJt6euwR;)lt;}pd=2!`1ULEF+35+*yXIWctJg-U_Tnyj);PQBqEkk#>4ccaijSIX4~|<6XMz* zOh5wt;(}djBHHpWf$NusrL_BU3Y37v*{_v^{m&iCnFl$i9*hZW(V`4n&o?|F5#mDi zgZ?80O49GP8ieEXC7Cs#hlK>KJ!OZARv*pC748J48StKh+63NR@cOgJ<$pjp_$^%1 z2i?kF+l-vxhkz_i+^QNjc(F;K?}RykO)}dAC>YJZx9Ga}9{?5@5mYFF>LM>Bg7G^5 zMWreXRPJ{2<99DNqSUFsZ7H5V){D_SZUSW->(-C$e~*(zVH|@f>>X;@)TkK@ED0UV9RO|wcKnfoR1<$j#r5D7?l=(l98qCgoNTSd{ zE2FTte@9$aTa#_h4IMR6MmX3<7a->3@^EJFE`!X}tF>5!a1eJ3Qy{chr0sxFn;=Mc z-=>!CKHe9s8fIu=>&UCs>?we^sNt`Zs+!Y+eM9|*_bH7nSa1p#r=Wx8&wF(lu7 z$ErFxn+(}W1>$`Wwhw^578pr$-<5%Nh!nK^;o%Z)k5;uwczdX_J#&5c-7YxRM*-n> znor${3MBP(c7TIoyccQ(2yj_o0^fhKFK1Ohq&jR6%vY!bgct}LwX`xHL@7i{wuuO7 z2B_o$t2|bEI!=&b;EzQy*Bitb_yM`JQC(xv=bfPEwmE*3q4-xy&OpN-IRh^lp*gV8 z)lR<=!C4dik>(<Rl*mbg!&j;$E2I`ft^wRS5ZUTB0vW37DbKM zCbS||OYH$U4szqh>&(!p_~jP!(4&7uEbWPxJ_+`4Wm%>{-O5I1yO9HH@TRms(~)QNqS}US@PaB z`}LE`5^-PJWn)jab7k#)bucN}Ip>i@c`u#w;BckH_uOP5Y3ZyDCXi^Fu$ORaWZ@!v zEYeQQ)T$Zs7Y47ejf)c8+x&ziCf>E=Q^8)L9L%*B5}qs}yPg?moS1-F$4T16$+Xo} zpHX3_l}j_MHZ2o8y^JwWaJFitdR=)3RwABB+&|`soCGm%A$E3%bL9i#IpSlo5i`^M zJLN$$PO~wuc)Zv+ukPKTN1zN7*b`5PxUdVV**hTLq!*-Ykf$lEk&`)8dxjCrXkDjH z9dEsJEh6;`Qd|p6PF3`e`RqP9E{vNEvr|)a5Ej) zrGB5w>2qmCG4)n?B0@&bUrj9W%qa0PvNhwn7F#}J#h$xQxs@Un9j2G;#Dm1J$nsjc ziG;UgPfHg z7Sx*eZl>L7PPW;k#4OW*#mrLIh3dZiws<_LysGnKKu2fwK#I@$8z1&29U(KPMiGrD z#+cxIk--LcA>Xi;0epmBiz}(u=m9pIwk~wHRStDOYISAJu(MZ(Prr%yh1gd7B`Pa^ zx+*1Y%r_exSh$G~G7vkT8ec)m`23;JL|0)>m~;i6xlFK(rhS3aHq(e7_C1^)<&c|o zp2-`N%Iy_O=V#G!OJRzgc=dFmQYE@$JNJmH`I+c_&83p+op^EuQ&ruigC`GltlSpm zR9$@AoBRrWXHlKl$YY^Bf5RYM)gK=M?uipurQh_0xfU6+Y1%m}^kEmLG#%`?;n=3- z4*E~dhb}r-j=J=OKhqm!LO)1t?uq(tRlrPxOz|)|4^DhpUROrx)a%Q-0Uu*C@#Lz` zLz4yMloSIk8p!J6OYYE$u*RI7Qlt56H87rxS#o*<-I9; zO=J4Z9-KQLQm(5ZqedtV44?KZNDw>p4f$AkQtxHH^C^kxpm7Tl8r``X*6Tm&ok*^F z9Vsk@R4Qq9_kDk1NTOx zD+0E0$YuW}!5FoSiLHN0#~WcVqzX+h}?9_X;tqYm$%7kYJkgPN=vw?RaTqn>KY zqVTf=0taC*+HJY3VgrN;`J|ysqMs#MQzxL{0FSkhSLVPQ2)IzmTn9=JhYsZ&xz_