OrderCalcMargin random failures

 

I have an EA that uses OrderCalcMargin(...) at the beginning to print me some stats in the console.

Once in a while it returns margin=0, even though the function returns true. And margin=0 is not right because I have actually plenty of margin.

It can happen on any pair (for example XAGEUR or Bitcoin...), but if I re-run the again EA, it works.

Sometimes it fails multiple times in a row, before working again.

What do you think is the cause?


Thanks

Marco

 
Marco Fiocco:

I have an EA that uses OrderCalcMargin(...) at the beginning to print me some stats in the console.

Once in a while it returns margin=0, even though the function returns true. And margin=0 is not right because I have actually plenty of margin.

It can happen on any pair (for example XAGEUR or Bitcoin...), but if I re-run the again EA, it works.

Sometimes it fails multiple times in a row, before working again.

What do you think is the cause?


Thanks

Marco

Hello Marco , on MT4 ? 

 
Lorentzos Roussos:

Hello Marco , on MT4 ? 

MT5, sorry forgot to mention that.
 

I found a possible explanation , a colleague of mine was having similar issues and they were not providing the correct open price to the function when

they wanted to perform calculations for pending order types . consult this code and test around .

int OnInit()
  {
//---
  double lots=2;
  double OCM=0,cOCM=0;
  double ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
  bool cm=OrderCalcMargin(ORDER_TYPE_BUY_STOP,_Symbol,lots,ask,OCM);
  if(!cm){Print("Default OCM error");}
  if(cm){Print("OrderCalcMargin="+DoubleToString(OCM,2));}
  bool ccm=CustomOrderCalcMargin(_Symbol,ask,lots,cOCM);
  if(!ccm){Print("Custom OCM error");}
  if(ccm){Print("Custom="+DoubleToString(cOCM,2));}
//---
   return(INIT_SUCCEEDED);
  }
//Lot 
bool CustomOrderCalcMargin(string WhichSymbol,
                           double OpenPrice,
                           double Volume,
                           double &Result)
{
//A.Collect necessities
  double Leverage=((double)AccountInfoInteger(ACCOUNT_LEVERAGE));
  double ContractsOneLotBuys=((double)SymbolInfoDouble(WhichSymbol,SYMBOL_TRADE_CONTRACT_SIZE));
  double TickValueForOneLotInDepositCurrency=((double)SymbolInfoDouble(WhichSymbol,SYMBOL_TRADE_TICK_VALUE));
  double TickSize=((double)SymbolInfoDouble(WhichSymbol,SYMBOL_POINT));
  if(Leverage<=0||ContractsOneLotBuys<=0||TickValueForOneLotInDepositCurrency<=0||TickSize<=0){return(false);}
//B.Ratio of Base Currency to Deposit Currency 
  //...when one tick moves this much is gained or lost in the base currency for a one lot order 
  double gainOneTick=TickSize*ContractsOneLotBuys;
  //...and we know how much is gained or lost for one lot in the deposit currency 
  //so the ratio is the Deposit Gain divided by Base Gain :
  double RTD=TickValueForOneLotInDepositCurrency/gainOneTick;
//C.Margin Required For One Lot in the Price provided in the base currency 
  //is the open price ,multiplied with the amount of contracts ,divided by leverage 
  double MROL=(OpenPrice*ContractsOneLotBuys)/Leverage;
  //this is in the base currency , adjust it to the deposit currency : 
  MROL=MROL*RTD;
  //this is for one lot ,adjust it to the desired volume
  MROL=MROL*Volume;
  Result=MROL;
  return(true);
}
 
Lorentzos Roussos:

I found a possible explanation , a colleague of mine was having similar issues and they were not providing the correct open price to the function when

they wanted to perform calculations for pending order types . consult this code and test around .


Thanks Lorentzos. The problem is that 

AccountInfoInteger(ACCOUNT_LEVERAGE))

always returns 1.0, for any pair. Maybe this is a problem with my broker.

In fact I use OrderCalcMargin() to compute the actual leverage, which should be 2.0 in this case. And my computation is correct. The problem is that occasionally  OrderCalcMargin() returns margin 0.

I cannot use your CustomOrderCalcMargin because it is based on AccountInfoInteger(ACCOUNT_LEVERAGE))

 
Marco Fiocco:

Thanks Lorentzos. The problem is that 

always returns 1.0, for any pair. Maybe this is a problem with my broker.

In fact I use OrderCalcMargin() to compute the actual leverage, which should be 2.0 in this case. And my computation is correct. The problem is that occasionally  OrderCalcMargin() returns margin 0.

I cannot use your CustomOrderCalcMargin because it is based on AccountInfoInteger(ACCOUNT_LEVERAGE))

You dont have a static leverage in the account ? Is it scaling with the account size ?

 
Lorentzos Roussos:

You dont have a static leverage in the account ? Is it scaling with the account size ?

It is static, but AccountInfoInteger(ACCOUNT_LEVERAGE)) is simply wrong.

I have found that retrying  OrderCalcMargin() automatically after 100 milliseconds returns me the correct value at the second trial. So that is a good enough solution for me.

 
Marco Fiocco:

It is static, but AccountInfoInteger(ACCOUNT_LEVERAGE)) is simply wrong.

I have found that retrying  OrderCalcMargin() automatically after 100 milliseconds returns me the correct value at the second trial. So that is a good enough solution for me.

Great , that will help others with similar issues  . 

If the broker wont scale your leverage (look up terms of execution) you can manually provide that value ,or store it once acquired .