diff --git a/Scripts/MyScripts/CalculateMarginSwap.mq5 b/Scripts/MyScripts/CalculateMarginSwap.mq5 index 9c1b42b..dcbe13d 100644 --- a/Scripts/MyScripts/CalculateMarginSwap.mq5 +++ b/Scripts/MyScripts/CalculateMarginSwap.mq5 @@ -5,26 +5,18 @@ //+------------------------------------------------------------------+ #property copyright "Copyright 2025, xxxxxxxx" #property link "" -#property version "6.02" -#property description "Calculates margin for a custom leverage using official MQL5 formulas." +#property version "7.10" +#property description "Calculates required margin for a custom Margin Rate (%) and swap costs." +#property description "Uses official MQL5 formulas for various instrument types." +#property description "Leverage to Margin Rate Conversion:" +#property description "1:1=100%, 1:2=50%, 1:5=20%, 1:10=10%, 1:20=5%, 1:30=3.33%" //--- show the inputs window when the script is launched #property script_show_inputs -//--- Enum for selectable leverage -enum ENUM_LEVERAGE - { - L_1_to_1 = 1, - L_1_to_2 = 2, - L_1_to_5 = 5, - L_1_to_10 = 10, - L_1_to_20 = 20, - L_1_to_30 = 30 - }; - -//--- Input for the user to specify the position size and leverage -input double InpLotSize = 0.1; -input ENUM_LEVERAGE InpLeverage = L_1_to_1; +//--- Input for the user to specify the position size and margin rate +input double InpLotSize = 0.1; +input double InpMarginRatePercent = 5.0; // Margin Rate in percent (e.g., 5.0 for 5% margin, which is 1:20 leverage) //--- Forward declarations string DayOfWeekToString(ENUM_DAY_OF_WEEK day); @@ -49,8 +41,8 @@ void OnStart() string description = SymbolInfoString(symbol, SYMBOL_DESCRIPTION); string margin_currency = SymbolInfoString(symbol, SYMBOL_CURRENCY_MARGIN); -//--- 2. Calculate Required Margin with CUSTOM LEVERAGE (Official Formulas) --- - double margin_1_to_1 = 0; +//--- 2. Calculate the position's full Notional Value --- + double nominal_value = 0; double contract_size = SymbolInfoDouble(symbol, SYMBOL_TRADE_CONTRACT_SIZE); double current_price = SymbolInfoDouble(symbol, SYMBOL_ASK); @@ -60,7 +52,7 @@ void OnStart() { case SYMBOL_CALC_MODE_FOREX: { - margin_1_to_1 = InpLotSize * contract_size; + nominal_value = InpLotSize * contract_size; break; } @@ -69,7 +61,7 @@ void OnStart() case SYMBOL_CALC_MODE_EXCH_STOCKS: case SYMBOL_CALC_MODE_SERV_COLLATERAL: { - margin_1_to_1 = InpLotSize * contract_size * current_price; + nominal_value = InpLotSize * contract_size * current_price; break; } @@ -77,9 +69,9 @@ void OnStart() case SYMBOL_CALC_MODE_EXCH_FUTURES: case SYMBOL_CALC_MODE_EXCH_FUTURES_FORTS: { - margin_1_to_1 = InpLotSize * SymbolInfoDouble(symbol, SYMBOL_MARGIN_INITIAL); - if(InpLeverage != L_1_to_1) - Print("Warning: Leverage simulation might be inaccurate for Futures as their margin is fixed."); + nominal_value = InpLotSize * SymbolInfoDouble(symbol, SYMBOL_MARGIN_INITIAL); + if(InpMarginRatePercent != 100.0) + Print("Warning: Margin Rate is not applicable for Futures. Showing fixed initial margin."); break; } @@ -88,7 +80,7 @@ void OnStart() double tick_value = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_VALUE); double tick_size = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE); if(tick_size > 0) - margin_1_to_1 = InpLotSize * contract_size * tick_value / tick_size; + nominal_value = InpLotSize * contract_size * tick_value / tick_size; break; } @@ -99,18 +91,27 @@ void OnStart() } } - double margin_required = margin_1_to_1 / (double)InpLeverage; - if(margin_currency != account_currency) { double conversion_rate = GetConversionRate(margin_currency, account_currency); if(conversion_rate > 0) - margin_required *= conversion_rate; + nominal_value *= conversion_rate; else - Print("Warning: Could not find conversion rate from ", margin_currency, " to ", account_currency, ". Margin value is in ", margin_currency, "."); + Print("Warning: Could not find conversion rate from ", margin_currency, " to ", account_currency, ". Nominal value is in ", margin_currency, "."); } -//--- 3. Swap Calculation --- +//--- 3. Calculate the final margin based on the notional value and the input margin rate + double margin_required; + if(calc_mode == SYMBOL_CALC_MODE_FUTURES || calc_mode == SYMBOL_CALC_MODE_EXCH_FUTURES || calc_mode == SYMBOL_CALC_MODE_EXCH_FUTURES_FORTS) + { + margin_required = nominal_value; + } + else + { + margin_required = nominal_value * (InpMarginRatePercent / 100.0); + } + +//--- 4. Swap Calculation --- ENUM_SYMBOL_SWAP_MODE swap_mode = (ENUM_SYMBOL_SWAP_MODE)SymbolInfoInteger(symbol, SYMBOL_SWAP_MODE); double swap_long_cost = 0, swap_short_cost = 0; double swap_long_raw = SymbolInfoDouble(symbol, SYMBOL_SWAP_LONG); @@ -124,7 +125,7 @@ void OnStart() case SYMBOL_SWAP_MODE_CURRENCY_MARGIN: case SYMBOL_SWAP_MODE_CURRENCY_DEPOSIT: { swap_long_cost = InpLotSize * swap_long_raw; swap_short_cost = InpLotSize * swap_short_raw; break; } - case SYMBOL_SWAP_MODE_INTEREST_CURRENT: // Corrected from SYMBOL_CALC_MODE... + case SYMBOL_SWAP_MODE_INTEREST_CURRENT: { double price = SymbolInfoDouble(symbol, SYMBOL_BID); swap_long_cost = (InpLotSize * contract_size * price * (swap_long_raw / 100.0)) / 360.0; @@ -135,7 +136,7 @@ void OnStart() { swap_long_cost = swap_long_raw; swap_short_cost = swap_short_raw; break; } } -//--- 4. Display the Results in the Experts Tab --- +//--- 5. Display the Results in the Experts Tab --- string base_currency = SymbolInfoString(symbol, SYMBOL_CURRENCY_BASE); string profit_currency = SymbolInfoString(symbol, SYMBOL_CURRENCY_PROFIT); ENUM_DAY_OF_WEEK triple_swap_day = (ENUM_DAY_OF_WEEK)SymbolInfoInteger(symbol, SYMBOL_SWAP_ROLLOVER3DAYS); @@ -144,7 +145,7 @@ void OnStart() Print("--- Margin & Swap Calculation ---"); PrintFormat("Symbol: %s (%s)", symbol, description); PrintFormat("Position Size: %.2f lots", InpLotSize); - PrintFormat("Simulated Leverage: 1:%d", (int)InpLeverage); + PrintFormat("Simulated Margin Rate: %.2f%% (Equivalent to ~1:%.0f leverage)", InpMarginRatePercent, 100.0/InpMarginRatePercent); PrintFormat("Calculation Mode: %s", EnumToString(calc_mode)); Print("\n--- Required Margin ---");