Skip to content

Commit ef6485a

Browse files
author
EarnForex
authored
1.11
1. Added an option to switch the hidden equity trailing stop to percentage points. 2. Added a silent mode to avoid outputting the AP's log messages to the Experts tab. 3. Added a special mechanism to avoid cyclical triggering of daily profit/loss conditions. 4. Changed the default log file name to ap_log.txt. 5. Changed how autotrading status is detected and reported.
1 parent 39684ac commit ef6485a

6 files changed

Lines changed: 137 additions & 72 deletions

File tree

MQL4/Experts/Account Protector/Account Protector.mq4

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
//+------------------------------------------------------------------+
22
//| Account Protector.mq4 |
3-
//| Copyright © 2017-2023, EarnForex.com |
3+
//| Copyright © 2017-2024, EarnForex.com |
44
//| https://www.earnforex.com/ |
55
//+------------------------------------------------------------------+
66
#property copyright "EarnForex.com"
77
#property link "https://www.earnforex.com/metatrader-expert-advisors/Account-Protector/"
8-
#property version "1.10"
9-
string Version = "1.10";
8+
#property version "1.11"
9+
string Version = "1.11";
1010
#property strict
1111

1212
#property description "Protects account balance by applying given actions when set conditions trigger."
@@ -59,14 +59,16 @@ input int DelayOrderClose = 0; // DelayOrderClose: Delay in milliseconds.
5959
input bool UseTotalVolume = false; // UseTotalVolume: enable if trading with many small trades and partial position closing.
6060
input ENUM_CLOSE_TRADES CloseFirst = ENUM_CLOSE_TRADES_DEFAULT; // CloseFirst: Close which trades first?
6161
input bool BreakEvenProfitInCurrencyUnits = false; // BreakEvenProfitInCurrencyUnits: currency instead of points.
62+
input bool EquityTrailingStopInPercentage = false; // EquityTrailingStopInPercentage: % instead of $.
6263
input string ____Miscellaneous = "";
6364
input bool AlertOnEquityTS = false; // AlertOnEquityTS: Alert when equity trailing stop triggers?
6465
input double AdditionalFunds = 0; // AdditionalFunds: Added to balance, equity, and free margin.
6566
input string Instruments = ""; // Instruments: Default list of trading instruments for order filtering.
6667
input bool GlobalSnapshots = false; // GlobalSnapshots: AP instances share equity & margin snapshots.
6768
input int Slippage = 2; // Slippage
68-
input string LogFileName = "log.txt"; // Log file name
69+
input string LogFileName = "ap_log.txt"; // Log file name
6970
input string SettingsFileName = ""; // Settings file: Load custom panel settings from \Files\ folder.
71+
input bool Silent = false; // Silent: No log output to the Experts tab.
7072

7173
CAccountProtector ExtDialog;
7274

@@ -253,7 +255,11 @@ int OnInit()
253255

254256
if ((!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) || (!MQLInfoInteger(MQL_TRADE_ALLOWED)))
255257
{
256-
Alert("AutoTrading is disabled! EA will be not able to perform trading operations!");
258+
string where = "";
259+
if ((!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) && (!MQLInfoInteger(MQL_TRADE_ALLOWED))) where = "in both EA's and platform's settings"; // Both.
260+
else if (!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) where = "in the platform's settings"; // Platform level.
261+
else if (!MQLInfoInteger(MQL_TRADE_ALLOWED)) where = "in the EA's settings"; // EA level.
262+
Alert("AutoTrading is disabled " + where + "! EA will be not able to perform trading operations!");
257263
sets.ClosePos = false;
258264
sets.DeletePend = false;
259265
sets.DisAuto = false;

MQL4/Experts/Account Protector/Account Protector.mqh

Lines changed: 51 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//+------------------------------------------------------------------+
22
//| Account Protector.mqh |
3-
//| Copyright © 2017-2023, EarnForex.com |
3+
//| Copyright © 2017-2024, EarnForex.com |
44
//| https://www.earnforex.com/ |
55
//+------------------------------------------------------------------+
66
#include "Defines.mqh"
@@ -11,9 +11,6 @@
1111
int GetAncestor(int, int);
1212
#import
1313

14-
//+------------------------------------------------------------------+
15-
//| |
16-
//+------------------------------------------------------------------+
1714
class CAccountProtector : public CAppDialog
1815
{
1916
private:
@@ -634,7 +631,10 @@ bool CAccountProtector::CreateObjects()
634631
if (!CheckBoxCreate(m_ChkBreakEvenExtra, first_column_start, y, panel_end, y + element_height, "m_ChkBreakEvenExtra", "Breakeven extra profit value (points):")) return false;
635632
if (!EditCreate(m_EdtBreakEvenExtra, last_input_start, y, last_input_end, y + element_height, "m_EdtBreakEvenExtra", "0")) return false;
636633
y += element_height + v_spacing;
637-
if (!CheckBoxCreate(m_ChkEquityTrailingStop, first_column_start, y, panel_end, y + element_height, "m_ChkEquityTrailingStop", "Equity trailing stop (hidden), USD:")) return false;
634+
string ets = "Equity trailing stop (hidden), ";
635+
if (EquityTrailingStopInPercentage) ets += "%:";
636+
else ets += "USD:";
637+
if (!CheckBoxCreate(m_ChkEquityTrailingStop, first_column_start, y, panel_end, y + element_height, "m_ChkEquityTrailingStop", ets)) return false;
638638
if (!EditCreate(m_EdtEquityTrailingStop, last_input_start, y, last_input_end, y + element_height, "m_EdtEquityTrailingStop", "0")) return false;
639639
y += element_height + v_spacing;
640640
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;
@@ -1160,11 +1160,12 @@ bool CAccountProtector::RefreshValues()
11601160
string account_currency = AccountCurrency();
11611161
if (account_currency != "")
11621162
{
1163-
m_ChkEquityTrailingStop.Text("Equity trailing stop (hidden), " + account_currency + ":");
1163+
if (!EquityTrailingStopInPercentage) m_ChkEquityTrailingStop.Text("Equity trailing stop (hidden), " + account_currency + ":");
11641164
if (BreakEvenProfitInCurrencyUnits)
11651165
{
11661166
m_ChkBreakEven.Text("Profit value (" + account_currency + ") to set SL to breakeven:");
11671167
}
1168+
if ((sets.boolEquityTrailingStop) && (sets.doubleEquityTrailingStop > 0)) m_LblCurrentEquityStopLoss.Text("Current equity stop-loss: " + DoubleToString(sets.doubleCurrentEquityStopLoss, 2) + " " + account_currency + ".");
11681169
}
11691170
if (IsANeedToContinueClosingOrders) Close_All_Positions();
11701171
if (IsANeedToContinueDeletingPendingOrders) Delete_All_Pending_Orders();
@@ -3743,9 +3744,14 @@ void CAccountProtector::HideShowMaximize(bool max = true)
37433744
void CAccountProtector::Check_Status()
37443745
{
37453746
if (sets.Triggered) return;
3746-
if ((!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) || (!MQLInfoInteger(MQL_TRADE_ALLOWED)))
3747+
if (!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
3748+
{
3749+
m_LblStatus.Text("Status: Autotrading is disabled (platform).");
3750+
return;
3751+
}
3752+
else if (!MQLInfoInteger(MQL_TRADE_ALLOWED))
37473753
{
3748-
m_LblStatus.Text("Status: Autotrading is disabled.");
3754+
m_LblStatus.Text("Status: Autotrading is disabled (EA).");
37493755
return;
37503756
}
37513757
else if ((!MQLInfoInteger(MQL_DLLS_ALLOWED)) && ((sets.DisAuto) || (sets.EnableAuto)))
@@ -4462,10 +4468,12 @@ void CAccountProtector::EquityTrailing()
44624468
MoveAndResize();
44634469
}
44644470
// If equity stop-loss should be trailed - update the stop-loss.
4465-
else if ((AE - sets.doubleEquityTrailingStop > sets.doubleCurrentEquityStopLoss) || (sets.doubleCurrentEquityStopLoss == 0))
4471+
if (((!EquityTrailingStopInPercentage) && ((AE - sets.doubleEquityTrailingStop > sets.doubleCurrentEquityStopLoss) || (sets.doubleCurrentEquityStopLoss == 0))) || // Currency equity trailing stop should be moved.
4472+
((EquityTrailingStopInPercentage) && ((AE * (1 - sets.doubleEquityTrailingStop / 100.0) > sets.doubleCurrentEquityStopLoss) || (sets.doubleCurrentEquityStopLoss == 0)))) // Percentage equity trailing stop should be moved.
44664473
{
44674474
double old_value = sets.doubleCurrentEquityStopLoss;
4468-
sets.doubleCurrentEquityStopLoss = AE - sets.doubleEquityTrailingStop;
4475+
if (!EquityTrailingStopInPercentage) sets.doubleCurrentEquityStopLoss = AE - sets.doubleEquityTrailingStop; // $
4476+
else sets.doubleCurrentEquityStopLoss = AE * (1 - sets.doubleEquityTrailingStop / 100.0); // %
44694477
SaveSettingsOnDisk();
44704478
string account_currency = AccountCurrency();
44714479
if (account_currency != "") m_LblCurrentEquityStopLoss.Text("Current equity stop-loss: " + DoubleToString(sets.doubleCurrentEquityStopLoss, 2) + " " + account_currency + ".");
@@ -4958,29 +4966,44 @@ void CAccountProtector::CheckAllConditions()
49584966
if ((!DisableSpreadLE) && (SymbolInfoInteger(Symbol(), SYMBOL_SPREAD) <= sets.intSpreadLE))
49594967
CheckOneCondition(sets.intSpreadLE, sets.boolSpreadLE, "Spread less or equal to " + IntegerToString(sets.intSpreadLE));
49604968

4961-
// Daily profit/loss greater or equal to <value> currency units.
4962-
if ((!DisableDailyProfitLossUnitsGE) && (daily_profit_loss_units >= sets.doubleDailyProfitLossUnitsGE))
4963-
CheckOneCondition(sets.doubleDailyProfitLossUnitsGE, sets.boolDailyProfitLossUnitsGE, "Daily profit/loss greater or equal to " + DoubleToString(sets.doubleDailyProfitLossUnitsGE, 2) + " " + AccountInfoString(ACCOUNT_CURRENCY));
4969+
bool CheckDailyConditions = true;
4970+
if ((DoNotDisableConditions) && (DoNotDisableActions)) // Two main circumstances that could lead to infinite attempts to do something.
4971+
{
4972+
if (((!sets.ClosePos) || ((sets.ClosePos) && (market == 0))) && // Close all, but there is nothing to close.
4973+
((!sets.DeletePend) || ((sets.DeletePend) && (pending == 0))) && // Delete all pending, but there is nothing to delete.
4974+
((!sets.DisAuto) || ((sets.DisAuto) && (!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)))) && // Disable AT, but it's already disabled.
4975+
(!sets.ClosePlatform) && (!sets.EnableAuto) && (!sets.CloseAllOtherCharts) && (!sets.RecaptureSnapshots)) // All other actions (except notifications should be disabled).
4976+
{
4977+
CheckDailyConditions = false; // No need to check daily conditions.
4978+
}
4979+
}
49644980

4981+
if (CheckDailyConditions)
4982+
{
4983+
// Daily profit/loss greater or equal to <value> currency units.
4984+
if ((!DisableDailyProfitLossUnitsGE) && (daily_profit_loss_units >= sets.doubleDailyProfitLossUnitsGE))
4985+
CheckOneCondition(sets.doubleDailyProfitLossUnitsGE, sets.boolDailyProfitLossUnitsGE, "Daily profit/loss greater or equal to " + DoubleToString(sets.doubleDailyProfitLossUnitsGE, 2) + " " + AccountInfoString(ACCOUNT_CURRENCY));
4986+
49654987
// Daily profit/loss less or equal to <value> currency units.
4966-
if ((!DisableDailyProfitLossUnitsLE) && (daily_profit_loss_units <= sets.doubleDailyProfitLossUnitsLE))
4967-
CheckOneCondition(sets.doubleDailyProfitLossUnitsLE, sets.boolDailyProfitLossUnitsLE, "Daily profit/loss less or equal to " + DoubleToString(sets.doubleDailyProfitLossUnitsLE, 2) + " " + AccountInfoString(ACCOUNT_CURRENCY));
4968-
4988+
if ((!DisableDailyProfitLossUnitsLE) && (daily_profit_loss_units <= sets.doubleDailyProfitLossUnitsLE))
4989+
CheckOneCondition(sets.doubleDailyProfitLossUnitsLE, sets.boolDailyProfitLossUnitsLE, "Daily profit/loss less or equal to " + DoubleToString(sets.doubleDailyProfitLossUnitsLE, 2) + " " + AccountInfoString(ACCOUNT_CURRENCY));
4990+
49694991
// Daily profit/loss greater or equal to <value> points.
4970-
if ((!DisableDailyProfitLossPointsGE) && (daily_profit_loss_points >= sets.intDailyProfitLossPointsGE))
4971-
CheckOneCondition(sets.intDailyProfitLossPointsGE, sets.boolDailyProfitLossPointsGE, "Daily profit/loss greater or equal to " + IntegerToString(sets.intDailyProfitLossPointsGE));
4972-
4992+
if ((!DisableDailyProfitLossPointsGE) && (daily_profit_loss_points >= sets.intDailyProfitLossPointsGE))
4993+
CheckOneCondition(sets.intDailyProfitLossPointsGE, sets.boolDailyProfitLossPointsGE, "Daily profit/loss greater or equal to " + IntegerToString(sets.intDailyProfitLossPointsGE));
4994+
49734995
// Daily profit/loss less or equal to <value> points.
4974-
if ((!DisableDailyProfitLossPointsLE) && (daily_profit_loss_points <= sets.intDailyProfitLossPointsLE))
4975-
CheckOneCondition(sets.intDailyProfitLossPointsLE, sets.boolDailyProfitLossPointsLE, "Daily profit/loss less or equal to " + IntegerToString(sets.intDailyProfitLossPointsLE));
4976-
4996+
if ((!DisableDailyProfitLossPointsLE) && (daily_profit_loss_points <= sets.intDailyProfitLossPointsLE))
4997+
CheckOneCondition(sets.intDailyProfitLossPointsLE, sets.boolDailyProfitLossPointsLE, "Daily profit/loss less or equal to " + IntegerToString(sets.intDailyProfitLossPointsLE));
4998+
49774999
// Daily profit/loss greater or equal to <value> %.
4978-
if ((!DisableDailyProfitLossPercGE) && (daily_profit_loss_perc >= sets.doubleDailyProfitLossPercGE))
4979-
CheckOneCondition(sets.doubleDailyProfitLossPercGE, sets.boolDailyProfitLossPercGE, "Daily profit/loss greater or equal to " + DoubleToString(sets.doubleDailyProfitLossPercGE, 2) + "% of balance");
4980-
5000+
if ((!DisableDailyProfitLossPercGE) && (daily_profit_loss_perc >= sets.doubleDailyProfitLossPercGE))
5001+
CheckOneCondition(sets.doubleDailyProfitLossPercGE, sets.boolDailyProfitLossPercGE, "Daily profit/loss greater or equal to " + DoubleToString(sets.doubleDailyProfitLossPercGE, 2) + "% of balance");
5002+
49815003
// Daily profit/loss less or equal to <value> %.
4982-
if ((!DisableDailyProfitLossPercLE) && (daily_profit_loss_perc <= sets.doubleDailyProfitLossPercLE))
4983-
CheckOneCondition(sets.doubleDailyProfitLossPercLE, sets.boolDailyProfitLossPercLE, "Daily profit/loss less or equal to " + DoubleToString(sets.doubleDailyProfitLossPercLE, 2) + "% of balance");
5004+
if ((!DisableDailyProfitLossPercLE) && (daily_profit_loss_perc <= sets.doubleDailyProfitLossPercLE))
5005+
CheckOneCondition(sets.doubleDailyProfitLossPercLE, sets.boolDailyProfitLossPercLE, "Daily profit/loss less or equal to " + DoubleToString(sets.doubleDailyProfitLossPercLE, 2) + "% of balance");
5006+
}
49845007

49855008
// Number of positions is greater or equal to <value>.
49865009
if ((!DisableNumberOfPositionsGE) && (market >= sets.intNumberOfPositionsGE))
@@ -5153,7 +5176,7 @@ void CAccountProtector::Logging(string message)
51535176
}
51545177
else Alert("Unexpected error accessing file: ", filename, ".");
51555178
}
5156-
if (!SilentLogging) Print(message);
5179+
if ((!Silent) && (!SilentLogging)) Print(message);
51575180
}
51585181

51595182
// Creates array of Magic numbers and updates its counter.

MQL4/Experts/Account Protector/Defines.mqh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//+------------------------------------------------------------------+
22
//| Defines.mqh |
3-
//| Copyright © 2017-2023, EarnForex.com |
3+
//| Copyright © 2017-2024, EarnForex.com |
44
//| https://www.earnforex.com/ |
55
//+------------------------------------------------------------------+
66
#include <Controls\Button.mqh>

MQL5/Experts/Account Protector/Account Protector.mq5

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
//+------------------------------------------------------------------+
22
//| Account Protector.mq5 |
3-
//| Copyright © 2017-2023, EarnForex.com |
3+
//| Copyright © 2017-2024, EarnForex.com |
44
//| https://www.earnforex.com/ |
55
//+------------------------------------------------------------------+
66
#property copyright "EarnForex.com"
77
#property link "https://www.earnforex.com/metatrader-expert-advisors/Account-Protector/"
8-
#property version "1.10"
9-
string Version = "1.10";
8+
#property version "1.11"
9+
string Version = "1.11";
1010
#property strict
1111

1212
#property description "Protects account balance by applying given actions when set conditions trigger."
@@ -59,14 +59,16 @@ input int DelayOrderClose = 0; // DelayOrderClose: Delay in milliseconds.
5959
input bool UseTotalVolume = false; // UseTotalVolume: enable if trading with many small trades and partial position closing.
6060
input ENUM_CLOSE_TRADES CloseFirst = ENUM_CLOSE_TRADES_DEFAULT; // CloseFirst: Close which trades first?
6161
input bool BreakEvenProfitInCurrencyUnits = false; // BreakEvenProfitInCurrencyUnits: currency instead of points.
62+
input bool EquityTrailingStopInPercentage = false; // EquityTrailingStopInPercentage: % instead of $.
6263
input group "Miscellaneous"
6364
input bool AlertOnEquityTS = false; // AlertOnEquityTS: Alert when equity trailing stop triggers?
6465
input double AdditionalFunds = 0; // AdditionalFunds: Added to balance, equity, and free margin.
6566
input string Instruments = ""; // Instruments: Default list of trading instruments for order filtering.
6667
input bool GlobalSnapshots = false; // GlobalSnapshots: AP instances share equity & margin snapshots.
6768
input int Slippage = 2; // Slippage
68-
input string LogFileName = "log.txt"; // Log file name
69+
input string LogFileName = "ap_log.txt"; // Log file name
6970
input string SettingsFileName = ""; // Settings file: Load custom panel settings from \Files\ folder.
71+
input bool Silent = false; // Silent: No log output to the Experts tab.
7072

7173
CAccountProtector ExtDialog;
7274

@@ -255,7 +257,11 @@ int OnInit()
255257

256258
if ((!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) || (!MQLInfoInteger(MQL_TRADE_ALLOWED)))
257259
{
258-
Alert("AutoTrading is disabled! EA will be not able to perform trading operations!");
260+
string where = "";
261+
if ((!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) && (!MQLInfoInteger(MQL_TRADE_ALLOWED))) where = "in both EA's and platform's settings"; // Both.
262+
else if (!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) where = "in the platform's settings"; // Platform level.
263+
else if (!MQLInfoInteger(MQL_TRADE_ALLOWED)) where = "in the EA's settings"; // EA level.
264+
Alert("AutoTrading is disabled " + where + "! EA will be not able to perform trading operations!");
259265
sets.ClosePos = false;
260266
sets.DeletePend = false;
261267
sets.DisAuto = false;

0 commit comments

Comments
 (0)