OrderCalcMargin() always returns true and margin 0 - page 3

 
amrali #:

Can you make short sell orders manually through GUI? I suspect that short-selling may be disabled for that symbol.

Please check the symbol specifications dialog:

 

I am not using fancy symbols. For the test I used EURUSD. All types of orders are allowed for that.

 

You can calculate the margin required using a custom function:

#include "Functions.mqh"   // https://www.mql5.com/en/code/28029

//+------------------------------------------------------------------+
//| Calculate the required margin for the trade operation planned.   |
//| The OrderCalcMargin() function is prohibited in indicators.      |
//+------------------------------------------------------------------+
bool  OrderCalcMarginCustom(
   ENUM_ORDER_TYPE       action,           // type of order
   string                symbol,           // symbol name
   double                volume,           // volume
   double                price,            // open price
   double&               margin            // variable for obtaining the margin value
)
  {
//--- https://www.metatrader5.com/en/terminal/help/trading_advanced/margin_forex
//--- https://www.mql5.com/en/docs/constants/environment_state/marketinfoconstants#enum_symbol_calc_mode
   double initial_margin_rate=0.0;
   double maintenance_margin_rate=0.0;
   if(SymbolInfoMarginRate(symbol, (ENUM_ORDER_TYPE)action, initial_margin_rate, maintenance_margin_rate))
     {
      double initial_margin=0.0;
      if(!SymbolInfoDouble(symbol, SYMBOL_MARGIN_INITIAL, initial_margin))
         return false;

      long CalcMode=-1;
      if(!SymbolInfoInteger(symbol, SYMBOL_TRADE_CALC_MODE, CalcMode))
         return false;

      //--- fixed margin is specified
      if(initial_margin > 0.0)
        {
         switch((ENUM_SYMBOL_CALC_MODE) CalcMode)
           {
            case SYMBOL_CALC_MODE_FOREX:
            case SYMBOL_CALC_MODE_CFDLEVERAGE:
               margin = (volume * initial_margin * initial_margin_rate / AccountInfoInteger(ACCOUNT_LEVERAGE)); //in margin currency
               break;

            default:
               margin = (volume * initial_margin * initial_margin_rate); //in margin currency
               break;
           }
        }
      else
        {
         switch((ENUM_SYMBOL_CALC_MODE) CalcMode)
           {
            case SYMBOL_CALC_MODE_FOREX:
              {
               const double contract_size = SymbolInfoDouble(symbol, SYMBOL_TRADE_CONTRACT_SIZE);
               margin = (volume * contract_size * initial_margin_rate / AccountInfoInteger(ACCOUNT_LEVERAGE)); //in margin currency
              }
            break;

            case SYMBOL_CALC_MODE_FOREX_NO_LEVERAGE:
              {
               const double contract_size = SymbolInfoDouble(symbol, SYMBOL_TRADE_CONTRACT_SIZE);
               margin = (volume * contract_size * initial_margin_rate); //in margin currency
              }
            break;

            case SYMBOL_CALC_MODE_CFD:
              {
               const double contract_size = SymbolInfoDouble(symbol, SYMBOL_TRADE_CONTRACT_SIZE);
               margin = (volume * contract_size * price * initial_margin_rate); //in margin currency
              }
            break;

            case SYMBOL_CALC_MODE_CFDLEVERAGE:
              {
               const double contract_size = SymbolInfoDouble(symbol, SYMBOL_TRADE_CONTRACT_SIZE);
               margin = (volume * contract_size * price * initial_margin_rate / AccountInfoInteger(ACCOUNT_LEVERAGE)); //in margin currency
              }
            break;

            case SYMBOL_CALC_MODE_CFDINDEX:
              {
               const double contract_size = SymbolInfoDouble(symbol, SYMBOL_TRADE_CONTRACT_SIZE);
               //const double TickPrice = SymbolInfoDouble(symbol, (action == ORDER_TYPE_BUY) ? SYMBOL_TRADE_TICK_VALUE_LOSS : SYMBOL_TRADE_TICK_VALUE_PROFIT);
               const double TickPrice = mTickValue(symbol,(bool)action); // fix for non-forex symbols
               const double TickSize = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE);
               margin = (volume * contract_size * price * TickPrice / TickSize * initial_margin_rate); //in margin currency
              }
            break;

            // not implemented.
            default:
               return false;
           }
        }
      //--- converting into deposit currency (common step for all calculation types)
      const string MarginCurrency = SymbolInfoString(symbol, SYMBOL_CURRENCY_MARGIN);
      const string AccountCurrency = AccountInfoString(ACCOUNT_CURRENCY);
      if(MarginCurrency != AccountCurrency)
        {
         const double CrossRate = GetExchangeRate(MarginCurrency, AccountCurrency, action);
         margin *= CrossRate; //in account currency
        }
      //---
      margin = NormalizeDouble(margin, (int)AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS));
      return true;
     }
//---
   else
      return false;
  }

To calculate margin for the affected symbol:

void OnStart()
  {
   double margin=0.0;
   double margin_custom=0.0;

   if(OrderCalcMargin(ORDER_TYPE_SELL, Symbol(), 1.0, SymbolInfoDouble(Symbol(),SYMBOL_BID), margin))
      Print("margin = ", margin);

   if(OrderCalcMarginCustom(ORDER_TYPE_SELL, Symbol(), 1.0, SymbolInfoDouble(Symbol(),SYMBOL_BID), margin_custom))
      Print("margin_custom = ", margin_custom);
  }
 
amrali #:

You can calculate the margin required using a custom function:

To calculate margin for the affected symbol:

  Thanks man. But i'd prefer to negotiate the bugfix than to workaround core components. Functions affected by this bug are cascading and ruining a lot of things including test results calculations, balance calculations, etc etc.

 

This bug reappeared in the latest update I got  (MT5, version 5.00 build 4270, 5 Apr 2024). I get reqMargin=0.

   PRINTVAR5(ordType,g_symbolName,short_lot,atprice,reqMargin);
   bool marginCheck=OrderCalcMargin(ordType,g_symbolName,short_lot,atprice,reqMargin);
   PRINTVAR5(ordType,g_symbolName,short_lot,atprice,reqMargin);

the output, before and after calling OrderCalcMargin, is (ordType is a ENUM_ORDER_TYPE variable):


ordType = 1, g_symbolName = GBPUSD, short_lot = 6.63, atprice = 1.24438, reqMargin = 0.0

ordType = 1, g_symbolName = GBPUSD, short_lot = 6.63, atprice = 1.24438, reqMargin = 0.0


and the boolean marginCheck is true.


 

Unfortunately, I am getting again the reqMargin=0 when calling OrderCalcMargin(). The current version I am running is MetaTrader5 version 4462 from July 29, 2024.

this is the call:

double reqMargin;
PRINTVAR4(g_symbolName,short_lot,atprice,reqMargin);
bool marginCheck=OrderCalcMargin(ORDER_TYPE_SELL,g_symbolName,short_lot,atprice,reqMargin);
PRINTVAR2(marginCheck,reqMargin); 


this is the output of each PRINTVAR:

2024.07.31 09:04:18.693 2023.07.28 02:30:00  : g_symbolName = USDJPY, short_lot = 21.0, atprice = 139.137, reqMargin = 2.6553274137e-314

2024.07.31 09:04:18.693 2023.07.28 02:30:00  : marginCheck = true, reqMargin = 0.0

It seems to be a lingering bug that is present in some versions of MT5...

any help?

thank you

 
better.trader every.day #:

Unfortunately, I am getting again the reqMargin=0 when calling OrderCalcMargin(). The current version I am running is MetaTrader5 version 4462 from July 29, 2024.

this is the call:



this is the output of each PRINTVAR:

2024.07.31 09:04:18.693 2023.07.28 02:30:00  : g_symbolName = USDJPY, short_lot = 21.0, atprice = 139.137, reqMargin = 2.6553274137e-314

2024.07.31 09:04:18.693 2023.07.28 02:30:00  : marginCheck = true, reqMargin = 0.0

It seems to be a lingering bug that is present in some versions of MT5...

any help?

thank you

Strategy Tester issue or on a live chart ?
 
Alain Verleyen #:
Strategy Tester issue or on a live chart ?

coming back again to this issue that has not been resolved, it seems. It is in the Strategy Tester. Can you elevate this issue to be fixed soon?

thank you

 
better.trader every.day #:

coming back again to this issue that has not been resolved, it seems. It is in the Strategy Tester. Can you elevate this issue to be fixed soon?

thank you

As people don't answer questions, the issue is not even clearly identified (reproduced), so don't hope a fix.

Can you provide ALL details, including some code to reproduce it ?