Skip to content

Commit

Permalink
3.10
Browse files Browse the repository at this point in the history
1. Added support for Strategy Tester backtesting in MetaTrader 4.
2. Added panel translations to the MT4 version of the Position Sizer.
3. Added an input parameter (CapMaxPositionSizeBasedOnMargin) to automatically limit the calculated position size with the maximum position size available based on the account's free margin.
4. Added a button to switch between ignoring no trades, ignoring trades in other symbols, and ignoring trades in the current symbol to the Risk tab.
5. Added an option (via input parameters) to let the trade open even when its execution would lead to the max volume/risk values (set via the Trading tab) being exceeded. The trade will be reduced in size to fit into the given max values.
6. Added a user-contributed Chinese (traditional) panel translation.
7. Added a max risk fuse to the Trading tab to prevent a trade from executing when the risk exceeds the given value.
8. Added support for the new swaps type in MT5: profit currency.
9. Changed messages for 'autotrading disabled' situation. Now two distinct messages will be used: one for the EA's properties, the other one for the platform's options.
10. Changed the TP line to be non-selectable when the TP-locked-on-SL mode is on.
11. Changed the description of the SettingsFile input parameter to correctly state that a custom settings file should be put in the \Files\PS_Settings\ folder.
13. Fixed the bug that caused changed edit values to reset when the panel got refreshed at the same as the edit was about to save in MT5.
14. Fixed how the TradeSymbol input parameter is used in MT5. Now it will be used in all the calculations to avoid problems with custom symbols' specifications.
15. Fixed the bug that caused ATR SL multiplier to initialize at zero even when SL distance is non-zero.
16. Fixed the bug with ATR TP not turning off when setting it to zero.
17. Fixed the bug that caused the TP distance to be set to some very large value when using the Shift+P hotkey to switch from level to distance.
18. Fixed the bug that caused a delay for the TP line movement when it was in the TP-locked-on-SL mode in MT5.
19. Fixed display of swap values with too many decimal places in MT5.
20. Fixed the bug that caused the take-profit line to appear unselected in MT5 even when lines should be selected by default.
21. Fixed a minor bug when loading an ini-file.
22. Fixed the bug that caused the Entry line fail to re-appear when HideEntryLineForInstant was set to true and you switched from an Instant to Pending order.
23. Fixed the calculation of the automatic TP line placement when UseCommissionToSetTPDistance is set to true. It is now based on Risk Money Result rather than Risk Money Input.
  • Loading branch information
EarnForex authored Dec 6, 2024
1 parent 6278ecc commit 3e5544c
Show file tree
Hide file tree
Showing 21 changed files with 4,030 additions and 673 deletions.
10 changes: 9 additions & 1 deletion MQL4/Experts/Position Sizer/Defines.mqh
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,13 @@ enum ADDITIONAL_TRADE_BUTTONS
ADDITIONAL_TRADE_BUTTONS_BOTH // Both
};

enum IGNORE_SYMBOLS
{
IGNORE_SYMBOLS_NONE, // No symbols
IGNORE_SYMBOLS_OTHER, // Other symbols
IGNORE_SYMBOLS_CURRENT, // Current symbol
};

struct Settings
{
ENTRY_TYPE EntryType;
Expand All @@ -137,7 +144,7 @@ struct Settings
bool CountPendingOrders;
bool IgnoreOrdersWithoutSL;
bool IgnoreOrdersWithoutTP;
bool IgnoreOtherSymbols;
IGNORE_SYMBOLS IgnoreSymbols;
bool HideAccSize;
bool ShowLines;
TABS SelectedTab;
Expand All @@ -151,6 +158,7 @@ struct Settings
int MaxSpread;
int MaxEntrySLDistance;
int MinEntrySLDistance;
double MaxRiskPercentage;
// For SL/TP distance modes:
bool SLDistanceInPoints;
bool TPDistanceInPoints;
Expand Down
337 changes: 218 additions & 119 deletions MQL4/Experts/Position Sizer/Position Sizer Trading.mqh

Large diffs are not rendered by default.

81 changes: 61 additions & 20 deletions MQL4/Experts/Position Sizer/Position Sizer.mq4
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,27 @@
#property copyright "EarnForex.com"
#property link "https://www.earnforex.com/metatrader-expert-advisors/Position-Sizer/"
#property icon "EF-Icon-64x64px.ico"
#property version "3.09"
string Version = "3.09";
#property version "3.10"
string Version = "3.10";
#property strict

#include "Translations\English.mqh"
//#include "Translations\Arabic.mqh"
//#include "Translations\Chinese.mqh"
//#include "Translations\ChineseTraditional.mqh" // Contributed by fxchess.
//#include "Translations\Portuguese.mqh" // Contributed by Matheus Sevaroli.
//#include "Translations\Russian.mqh"
//#include "Translations\Spanish.mqh"
//#include "Translations\Ukrainian.mqh"

#property description "Calculates risk-based position size for your account."
#property description "Allows trade execution based the calculation results.\r\n"
#property description "WARNING: No warranty. This EA is offered \"as is\". Use at your own risk.\r\n"
#property description "Note: Pressing the \"T\" key will open a trade."

#include "Position Sizer.mqh";
#include "Position Sizer Trading.mqh";
#include "TesterSupport.mqh"

input group "Compactness"
input string ____Compactness = "";
Expand Down Expand Up @@ -72,24 +82,25 @@ input ENUM_TIMEFRAMES DefaultATRTimeframe = PERIOD_CURRENT; // ATRTimeframe: Def
input bool DefaultSpreadAdjustmentSL = false; // SpreadAdjustmentSL: Adjust SL by Spread value in ATR mode.
input bool DefaultSpreadAdjustmentTP = false; // SpreadAdjustmentTP: Adjust TP by Spread value in ATR mode.
input double DefaultCommission = 0; // Commission: Default one-way commission per 1 lot.
input COMMISSION_TYPE DefaultCommissionType = COMMISSION_CURRENCY; // CommossionType: Default commission type.
input COMMISSION_TYPE DefaultCommissionType = COMMISSION_CURRENCY; // CommissionType: Default commission type.
input ACCOUNT_BUTTON DefaultAccountButton = Balance; // AccountButton: Balance/Equity/Balance-CPR
input double DefaultRisk = 1; // Risk: Initial risk tolerance in percentage points
input double DefaultMoneyRisk = 0; // MoneyRisk: If > 0, money risk tolerance in currency.
input double DefaultPositionSize = 0; // PositionSize: If > 0, position size in lots.
input bool DefaultCountPendingOrders = false; // CountPendingOrders: Count pending orders for portfolio risk.
input bool DefaultIgnoreOrdersWithoutSL = false; // IgnoreOrdersWithoutSL: Ignore orders w/o SL in portfolio risk.
input bool DefaultIgnoreOrdersWithoutTP = false; // IgnoreOrdersWithoutTP: Ignore orders w/o TP in portfolio risk.
input bool DefaultIgnoreOtherSymbols = false; // IgnoreOtherSymbols: Ignore other symbols' orders in portfolio risk.
input IGNORE_SYMBOLS DefaultIgnoreSymbols = IGNORE_SYMBOLS_NONE; // IgnoreSymbols: Ignore trades in some symbols for portfolio risk?
input double DefaultCustomLeverage = 0; // CustomLeverage: Default custom leverage for Margin tab.
input int DefaultMagicNumber = 2022052714; // MagicNumber: Default magic number for Trading tab.
input string DefaultCommentary = ""; // Commentary: Default order comment for Trading tab.
input bool DefaultCommentAutoSuffix = false; // AutoSuffix: Automatic suffix for order commentary in Trading tab.
input bool DefaultCommentAutoSuffix = false; // AutoSuffix: Automatic suffix for order comment in Trading tab.
input bool DefaultDisableTradingWhenLinesAreHidden = false; // DisableTradingWhenLinesAreHidden: for Trading tab.
input int DefaultMaxSlippage = 0; // MaxSlippage: Maximum slippage for Trading tab.
input int DefaultMaxSpread = 0; // MaxSpread: Maximum spread for Trading tab.
input int DefaultMaxEntrySLDistance = 0; // MaxEntrySLDistance: Maximum entry/SL distance for Trading tab.
input int DefaultMinEntrySLDistance = 0; // MinEntrySLDistance: Minimum entry/SL distance for Trading tab.
input double DefaultMaxRiskPercentage = 0; // MaxRiskPercentage: Maximum risk % for Trading tab.
input double DefaultMaxPositionSizeTotal = 0; // Maximum position size total for Trading tab.
input double DefaultMaxPositionSizePerSymbol = 0; // Maximum position size per symbol for Trading tab.
input bool DefaultSubtractOPV = false; // SubtractOPV: Subtract open positions volume (Trading tab).
Expand Down Expand Up @@ -139,11 +150,13 @@ input string ObjectPrefix = "PS_"; // ObjectPrefix: To prevent confusion with ot
input SYMBOL_CHART_CHANGE_REACTION SymbolChange = SYMBOL_CHART_CHANGE_EACH_OWN; // SymbolChange: What to do with the panel on chart symbol change?
input bool DisableTradingSounds = false; // DisableTradingSounds: If true, sound will be off for trading actions.
input bool IgnoreMarketExecutionMode = true; // IgnoreMarketExecutionMode: If true, ignore Market execution.
input bool MarketModeApplySLTPAfterAllTradesExecuted = false; // Market Mode - Apply SL/TP After All Trades Executed
input bool MarketModeApplySLTPAfterAllTradesExecuted = false; // Market Mode: Apply SL/TP after all trades executed.
input bool DarkMode = false; // DarkMode: Enable dark mode for a less bright panel.
input string SettingsFile = ""; // SettingsFile: Load custom panel settings from \Files\ folder.
input string SettingsFile = ""; // SettingsFile: Custom settings file from \Files\PS_Settings\
input bool PrefillAdditionalTPsBasedOnMain = true; // Prefill additional TPs based on Main?
input bool AskBeforeClosing = false; // Ask for confirmation before closing the panel?
input bool CapMaxPositionSizeBasedOnMargin = false; // Cap position size based on available margin?
input bool LessRestrictiveMaxLimits = false; // Allow smaller trades when trading limits are exceeded?

CPositionSizeCalculator* ExtDialog;

Expand Down Expand Up @@ -212,7 +225,7 @@ int OnInit()
ExtDialog.UpdateFileName(); // Update the filename.

// Reset everything.
OutputPointValue = ""; OutputSwapsType = "Unknown"; SwapsTripleDay = "?";
OutputPointValue = ""; OutputSwapsType = TRANSLATION_LABEL_UNKNOWN; SwapsTripleDay = "?";
OutputSwapsDailyLongLot = "?"; OutputSwapsDailyShortLot = "?"; OutputSwapsDailyLongPS = "?"; OutputSwapsDailyShortPS = "?";
OutputSwapsYearlyLongLot = "?"; OutputSwapsYearlyShortLot = "?"; OutputSwapsYearlyLongPS = "?"; OutputSwapsYearlyShortPS = "?";
OutputSwapsCurrencyDailyLot = ""; OutputSwapsCurrencyDailyPS = ""; OutputSwapsCurrencyYearlyLot = ""; OutputSwapsCurrencyYearlyPS = "";
Expand Down Expand Up @@ -269,7 +282,7 @@ int OnInit()
sets.CountPendingOrders = DefaultCountPendingOrders; // If true, portfolio risk calculation will also involve pending orders.
sets.IgnoreOrdersWithoutSL = DefaultIgnoreOrdersWithoutSL; // If true, portfolio risk calculation will skip orders without stop-loss.
sets.IgnoreOrdersWithoutTP = DefaultIgnoreOrdersWithoutTP; // If true, portfolio risk calculation will skip orders without take-profit.
sets.IgnoreOtherSymbols = DefaultIgnoreOtherSymbols; // If true, portfolio risk calculation will skip orders in other symbols.
sets.IgnoreSymbols = DefaultIgnoreSymbols; // Skip trades in other/current/no symbols for portfolio risk calculation.
sets.HideAccSize = HideAccSize; // If true, account size line will not be shown.
sets.ShowLines = DefaultShowLines;
sets.SelectedTab = MainTab;
Expand All @@ -292,6 +305,7 @@ int OnInit()
sets.MinEntrySLDistance = DefaultMinEntrySLDistance;
sets.MaxPositionSizeTotal = DefaultMaxPositionSizeTotal;
sets.MaxPositionSizePerSymbol = DefaultMaxPositionSizePerSymbol;
sets.MaxRiskPercentage = DefaultMaxRiskPercentage;
if ((sets.MaxPositionSizeTotal < sets.MaxPositionSizePerSymbol) && (sets.MaxPositionSizeTotal != 0)) sets.MaxPositionSizeTotal = sets.MaxPositionSizePerSymbol;
sets.StopLoss = 0;
sets.TakeProfit = 0;
Expand Down Expand Up @@ -458,7 +472,10 @@ int OnInit()
ExtDialog.ChartEvent(CHARTEVENT_CHART_CHANGE, lparam, dparam, sparam);
}

if (!EventSetTimer(1)) Print("Error setting timer: ", GetLastError());
if (!IsVisualMode()) // The timer doesn't work in MT4 Strategy Tester.
{
if (!EventSetTimer(1)) Print(TRANSLATION_MESSAGE_ERROR_SETTING_TIMER + ": ", GetLastError());
}

if (DarkMode)
{
Expand Down Expand Up @@ -531,7 +548,7 @@ void OnDeinit(const int reason)
if ((reason == REASON_REMOVE) || (reason == REASON_PROGRAM))
{
if (SettingsFile == "") ExtDialog.DeleteSettingsFile();
if (!FileDelete(ExtDialog.IniFileName() + ExtDialog.IniFileExt())) Print("Failed to delete the PS panel's .ini file: ", GetLastError());
if (!FileDelete(ExtDialog.IniFileName() + ExtDialog.IniFileExt())) Print(TRANSLATION_MESSAGE_FAILED_DELETE_INI + ": ", GetLastError());
}
}

Expand Down Expand Up @@ -566,6 +583,12 @@ void OnDeinit(const int reason)

void OnTick()
{
if (IsVisualMode()) // Visual backtesting.
{
ListenToChartEvents(ExtDialog.Name()); // Check and generate chart events in Strategy Tester.
ExtDialog.UpdateStrategyTesterTrades();
}

ExtDialog.RefreshValues();

if (sets.TrailingStopPoints > 0) DoTrailingStop();
Expand Down Expand Up @@ -619,13 +642,31 @@ void OnChartEvent(const int id,
}
}

// This cannot be done using the panel's event handler because the outside trade button isn't added to its list of controls.
if ((id == CHARTEVENT_OBJECT_CLICK) && (sparam == ExtDialog.Name() + "m_OutsideTradeButton"))
// Some buttons cannot be processed using the panel's event handler because they aren't added to the panel's list of controls.
if (id == CHARTEVENT_OBJECT_CLICK)
{
ExtDialog.m_OutsideTradeButton.Pressed(false);
Trade();
// Outside trade button:
if (sparam == ExtDialog.Name() + "m_OutsideTradeButton")
{
ExtDialog.m_OutsideTradeButton.Pressed(false);
Trade();
}
else if (IsVisualMode())
{
// Button to switch the corner of the outside close buttons.
if (sparam == ExtDialog.Name() + "m_BtnOutsideCloseButtonsSwitchButton")
{
ExtDialog.ProcessOutsideCloseButtonsSwitchClick();
}
// Outside close button:
else if (StringSubstr(sparam, 0, StringLen(ExtDialog.Name() + "m_BtnOutsideClose")) == ExtDialog.Name() + "m_BtnOutsideClose")
{
int i = (int)StringToInteger(StringSubstr(sparam, StringLen(ExtDialog.Name() + "m_BtnOutsideClose")));
ExtDialog.ProcessOutsideCloseButtonClick(i);
}
}
}

if (id == CHARTEVENT_CLICK) // Avoid "sticking" of xxxLineIsBeingMoved variables.
{
StopLossLineIsBeingMoved = false;
Expand Down Expand Up @@ -826,15 +867,15 @@ void OnChartEvent(const int id,
else
{
sets.TPDistanceInPoints = true; // If was in level, set to points.
sets.TakeProfit = (int)MathRound(MathAbs(sets.TakeProfitLevel - sets.EntryLevel) / _Point);
if (sets.TakeProfitLevel != 0) sets.TakeProfit = (int)MathRound(MathAbs(sets.TakeProfitLevel - sets.EntryLevel) / _Point);
// Additional take-profits.
if (sets.TakeProfitsNumber > 1)
{
for (int i = 1; i < sets.TakeProfitsNumber; i++)
{
if (sets.TP[i] != 0) // With zero points TP, keep the TP lines at zero level - as with the main TP level.
{
ExtDialog.AdditionalTPEdits[i - 1].Text(DoubleToString(MathAbs(MathRound((sets.TP[i] - sets.EntryLevel) / _Point)), 0));
if (sets.TP[i] != 0) ExtDialog.AdditionalTPEdits[i - 1].Text(DoubleToString(MathAbs(MathRound((sets.TP[i] - sets.EntryLevel) / _Point)), 0));
}
}
}
Expand All @@ -847,8 +888,8 @@ void OnChartEvent(const int id,
if (id != CHARTEVENT_CHART_CHANGE) ExtDialog.OnEvent(id, lparam, dparam, sparam);

// Recalculate on chart changes, clicks, and certain object dragging.
if ((id == CHARTEVENT_CLICK) || (id == CHARTEVENT_CHART_CHANGE) ||
((id == CHARTEVENT_OBJECT_DRAG) && ((sparam == ObjectPrefix + "EntryLine") || (sparam == ObjectPrefix + "StopLossLine") || (StringFind(sparam, ObjectPrefix + "TakeProfitLine") != -1))))
if ((id == CHARTEVENT_CLICK) || (id == CHARTEVENT_CHART_CHANGE) || ((id == CHARTEVENT_OBJECT_DRAG) &&
((sparam == ObjectPrefix + "EntryLine") || (sparam == ObjectPrefix + "StopLossLine") || (StringFind(sparam, ObjectPrefix + "TakeProfitLine") != -1))))
{
// Moving lines when fixed SL/TP distance is enabled. Should set a new fixed SL/TP distance.
if ((id == CHARTEVENT_OBJECT_DRAG) && ((sets.SLDistanceInPoints) || (sets.TPDistanceInPoints) || (ShowATROptions)))
Expand Down
Loading

0 comments on commit 3e5544c

Please sign in to comment.