OrderCalcMargin() always returns true and margin 0

 
Hi,

Stuck into a problem. Using the standard MoneyManagement modules results in OrderCalcMargin always returns true and margin 0.

in AccountInfo it's that call
OrderCalcMargin(trade_operation,symbol,1.0,price,margin)

which with further execution leads to the usage maxvolume of the symbol. 10000000 lots



As OrderCalcMargin is not debugable i really can't figure out what's going wrong.
I typed in some output just to check:

   double margin, margin_rate;
   double margin_init = SymbolInfoDouble( Symbol(), SYMBOL_MARGIN_INITIAL );
   double ask = SymbolInfoDouble( Symbol(), SYMBOL_ASK );
   
   SymbolInfoMarginRate( Symbol(),ORDER_TYPE_SELL, margin_init, margin_rate);
   Print( "Init Margin: ",SymbolInfoDouble(Symbol(), SYMBOL_MARGIN_INITIAL) );
   Print( "Margin Rate: ", margin_rate);
   Print( "Price is: ", ask);
   Print( "Calc Margin is: ", (OrderCalcMargin(ORDER_TYPE_SELL,Symbol(),1.0,ask,margin)));
   Print( "Margin is: ", margin);

2024.01.16 06:06:30.260 2023.09.01 09:00:00   Init Margin: 15000.0
2024.01.16 06:06:30.260 2023.09.01 09:00:00   Margin Rate: 1.0
2024.01.16 06:06:30.260 2023.09.01 09:00:00   Price is: 95591.0
2024.01.16 06:06:30.260 2023.09.01 09:00:00   Calc Margin is: true
2024.01.16 06:06:30.260 2023.09.01 09:00:00   Margin is: 0.0
The output makes sense except Margin is 0.0

According to the documentation  SYMBOL_CALC_MODE_FUTURES  requires for calculations

Margin: Lots * InitialMargin * Margin_Rate

Lots is 1.0, Init Margin is 15000, Margin Rate is 1. How it results in margin 0.0?

Tried on different symbols - current or previous futures - same results. 
Documentation on MQL5: Trade Functions / OrderCalcMargin
Documentation on MQL5: Trade Functions / OrderCalcMargin
  • www.mql5.com
OrderCalcMargin - Trade Functions - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 
bred_bred1 #:
Sorry, that's just a typo in original post(edited already), was checking if it would make any differece. I send the  ORDER_TYPE_SELL and still get the Margin == 0.

Oh sorry I confused it with the OrderCalcProfit function, you can calculate margin for pending order types, have you used the GetLastError() function to see what error you've received?

 
Le Minh Duc #:

Oh sorry I confused it with the OrderCalcProfit function, you can calculate margin for pending order types, have you used the GetLastError() function to see what error you've received?

I do not get any errors. OrderCalcMargin() returns true as you can see in the output. No errors in the Log.
 
You beginners have to try the variable observation in the debugger you are seriously missing out.
 
Tobias Johannes Zimmer #:
You beginners have to try the variable observation in the debugger you are seriously missing out.

If you were a little less arrogant little more logically developed you'd understand that all requested variables are outputed for the sake of conviniecy of provided information related to the question and not for my personal testing purposes. But thanks for the tip. Anything useful to say on the actual question?

 
bred_bred1 #: I do not get any errors. OrderCalcMargin() returns true as you can see in the output. No errors in the Log.

Please also print out the symbol name and its property ENUM_SYMBOL_CALC_MODE as text using EnumToString.

EDIT: And print out the ACCOUNT_LEVERAGE too just for clarification.

 
bred_bred1: SymbolInfoMarginRate

Also please note that you are overwriting the variable "margin_init".

double margin_init = SymbolInfoDouble( Symbol(), SYMBOL_MARGIN_INITIAL ); // <-- You assign a value here

...
   
SymbolInfoMarginRate( Symbol(),ORDER_TYPE_SELL, margin_init, margin_rate); // <-- and you overwrite the value here
 
Fernando Carreiro #:
Please also print out the symbol name and its property ENUM_SYMBOL_CALC_MODE as text using EnumToString.

Hello, Fernando!

I have read carefully all your answers on similar questions and studied all the links there, really wanted to thank for your contribution.

 Print( "Symbol is: ", Symbol() );
 Print( "Symbol Calc Mode: ", EnumToString((ENUM_SYMBOL_CALC_MODE)SymbolInfoInteger(Symbol(), SYMBOL_TRADE_CALC_MODE)) );


2024.01.16 20:17:25.559 2023.09.01 09:00:00   Symbol is: SiZ3
2024.01.16 20:17:25.559 2023.09.01 09:00:00   Symbol Calc Mode: SYMBOL_CALC_MODE_FUTURES

I tried the default settings of the testing symbols, tried custom settings, changed the symbols to current, tried to change the calculation modes to those that make sense to futures. Changing the init margin does affect the required margin and changing maxvolume indeed changes the maxvolume but not the output of the OrderCalcMargin().


As for

SymbolInfoMarginRate( Symbol(),ORDER_TYPE_SELL, margin_init, margin_rate)

margin_init not overriding anything. It's required parameter to get the margin_rate. What's the difference between assigning to a variable the result of 

SymbolInfoDouble( Symbol(), SYMBOL_MARGIN_INITIAL );

or send it into a SymbolInfoMarginRate directly. I would not bother if the debugger could output the function results.



Overall the behavior is observed in any non-modified generated EA with MoneyManagement enabled.


EDIT: ACCOUNT_LEVERAGE  is completely ignored. It could be 1, it could be 50000 and respective values would be outputed - but it has zero effect on deals. In Profit in pips mode or in Standard mode.

 

bred_bred1 #: SymbolInfoMarginRate ... margin_init not overriding anything.

You are correct. The documentation is misleading.

The parameter is passed by reference, which made me think it was an [out] parameter. But the documentation then declares it as an [in] parameter.

So, I don't know why MetaQuotes has declared it as passed by reference if it then is used as a [in] parameter.

bool  SymbolInfoMarginRate(
   string             name,                     // symbol name
   ENUM_ORDER_TYPE    order_type,               // order type
   double&            initial_margin_rate,      // initial margin rate
   double&            maintenance_margin_rate   // maintenance margin rate
   );

That was the reason for my confusion!

 
bred_bred1 #: I tried the default settings of the testing symbols, tried custom settings, changed the symbols to current, tried to change the calculation modes to those that make sense to futures. Changing the init margin does affect the required margin and changing maxvolume indeed changes the maxvolume but not the output of the OrderCalcMargin().

Are your "prints" from the Strategy Tester or from a live chart?

If it is from a Strategy Tester, what account currency are you using?

Also, can you please print out the SYMBOL_CURRENCY_MARGIN?

 
Fernando Carreiro #:

Are your "prints" from the Strategy Tester or from a live chart?

If it is from a Strategy Tester, what account currency are you using?

Also, can you please print out the SYMBOL_CURRENCY_MARGIN?

That's a strategy tester.

SYMBOL_CURRENCY_MARGIN - depends on Symbol specifications. On SIZ3 - it's RUR. On FUTMNQH24 - it's USD.
To be honest i considered this to be an issue, so i tested in advance. Synced the currency of the deposit and future symbols' - no success. Used USD + USD, RUR + RUR - no success. Pips +  USD, Pips + RUR - no success.

Kinda running out of ideas. Especially taking into account that i can't see how any of these things are related to a simple 3 variable calculation, which OrderCalcMargin() is.