Issue with CheckOpenLong() returning 0.0

 

Hi,


I am currently trying to use the class CMoneyFixedRisk::CheckOpenLong(double price, double sl) (from the Expert/Money/MoneyFixedRisk.mqh library) to estimate the appropriate volume to open a long position, for a given risk per trade and a given SL value.

My first attempts systematically retuned volumes of 0.0.

After reading related posts on this forum, it seems that such a problem has been met by other traders in the past, but I am not able to manage with the material I have founded.
In addition, it seems that some traders are actively users of this function so it should work fine. I am pretty sure there is something I am missunderstanding.

First, the documentation says that the input parameters are:
- "price", the estimated open price
- "sl", the estimated Stop Loss price.
So my understanding is that these expected values are quotation levels of the instrument; for instance for EURUSD: price=1.1582 and sl = 1.1560;

Second, inspiring myself from this code, I wrote a simple code that unfortunately also returns volumes of 0.0.

//+------------------------------------------------------------------+
//|                                         myTestMoneyFixedRisk.mq5 |
//|                                  Copyright 2025, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+


#property copyright "Copyright 2025, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"

#include <Expert/Money/MoneyFixedRisk.mqh>
CMoneyFixedRisk   m_money;
CSymbolInfo       m_symbol;                     // symbol info object



input double rpt_pct = 0.5; // Risk per trade (%)
input double entry_quote = 1.1582;
input double sl_quote = 1.1560;


//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   m_symbol.Name(Symbol());
   m_symbol.Refresh();
   if(!RefreshRates())
     {
      Print("Error RefreshRates. Bid=",DoubleToString(m_symbol.Bid(),Digits()),
            ", Ask=",DoubleToString(m_symbol.Ask(),Digits()));
      return(INIT_FAILED);
     }
//--- tuning for 3 or 5 digits
   int digits_adjust=1;
   if(m_symbol.Digits()==3 || m_symbol.Digits()==5)
      digits_adjust=10;
 
//---
   if(!m_money.Init(GetPointer(m_symbol),Period(),m_symbol.Point()*digits_adjust))
      return(INIT_FAILED);
   m_money.Percent(rpt_pct); // risk per trade (%))
//---
   return(INIT_SUCCEEDED);
  }



//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   
   Print("entry_quote", entry_quote);
   Print("sl_quote=", sl_quote);
   
   double lots = m_money.CheckOpenLong(entry_quote, sl_quote);
   Print("lots=", lots);
 
  }
//+------------------------------------------------------------------+


//+------------------------------------------------------------------+
//| Refreshes the symbol quotes data                                 |
//+------------------------------------------------------------------+
bool RefreshRates()
  {
  
//--- refresh rates
   if(!m_symbol.RefreshRates())
      return(false);
//--- protection against the return value of "zero"
   if(m_symbol.Ask()==0 || m_symbol.Bid()==0)
      return(false);
//---
   return(true);
   
  }
//+------------------------------------------------------------------+

A returned journal is shown in Capture 01.png.

I tried to change the input parameter values, but the output volume remains 0.0.

Third, I tried to run the code mentioned above and it (surprisingly, to me) lead to the same result:  an output volume equal to 0.0.

A returned journal (for a run on EURUSD) is shown in Capture 02.png.

Would you have an idea of what I am doing wrong?

Is there a bug in CheckOpenShort of CMoneyFixedRisk library ?
Is there a bug in CheckOpenShort of CMoneyFixedRisk library ?
  • 2021.04.26
  • www.mql5.com
I, I think i've found a bug in CMoneyFixedRisk Library. I wrote an EA i try in strategy tester...
Files:
Capture_01.png  27 kb
Capture_02.png  113 kb
 
Carbon13:


i have not tried you code, however, i believe that your result maybe too small, ie maybe the result is less than 0.01??

try this solution. 

Forum on trading, automated trading systems and testing trading strategies

CMoneyFixedRisk keeps returning 0.0 as volume

Vladimir Karputov, 2021.06.28 05:50

1. Increase the percentage of risk. You probably get a very small lot size (all answers are inside the library)

//+------------------------------------------------------------------+
//| Getting lot size for open long position.                         |
//+------------------------------------------------------------------+
double CExpertMoney::CheckOpenLong(double price,double sl)
  {
   if(m_symbol==NULL)
      return(0.0);
//---
   double lot;
   if(price==0.0)
      lot=m_account.MaxLotCheck(m_symbol.Name(),ORDER_TYPE_BUY,m_symbol.Ask(),m_percent);
   else
      lot=m_account.MaxLotCheck(m_symbol.Name(),ORDER_TYPE_BUY,price,m_percent);
   if(lot<m_symbol.LotsMin())
      return(0.0);
//---
   return(m_symbol.LotsMin());
  }
//+------------------------------------------------------------------+
//| Getting lot size for open short position.                        |
//+------------------------------------------------------------------+
double CExpertMoney::CheckOpenShort(double price,double sl)
  {
   if(m_symbol==NULL)
      return(0.0);
//---
   double lot;
   if(price==0.0)
      lot=m_account.MaxLotCheck(m_symbol.Name(),ORDER_TYPE_SELL,m_symbol.Bid(),m_percent);
   else
      lot=m_account.MaxLotCheck(m_symbol.Name(),ORDER_TYPE_SELL,price,m_percent);
   if(lot<m_symbol.LotsMin())
      return(0.0);
//---
   return(m_symbol.LotsMin());
  }

2. I created such an advisor for tests a long time ago:  Money Fixed Risk


 
Also note that there are many threads where moderators have advised to NOT retrieve prices from the OnInit.
 

Thanks Michael for your comments.

Finally, I do not understand why, I have restarted my metaeditor and the code behaviour changed. Maybe something related to the cache management.

To reply to you:

- So I did not need to change the percentage of risk: the default parameters worked fine with a leverage 1:30 on EURUSD;
- The code you cite (from 2021) seems to be yet the reference one. However, that function is overriden by the CMoneyFixedRisk::CheckOpenLong() one from the child  CMoneyFixedRisk class. And this function returns m_symbol.LotsMin() (and not 0.0) in the case you mention, see hereafter;


//+------------------------------------------------------------------+
//| Getting lot size for open long position.                         |
//+------------------------------------------------------------------+
double CMoneyFixedRisk::CheckOpenLong(double price,double sl)
  {
   if(m_symbol==NULL)
      return(0.0);
//--- select lot size
   double lot;
   double minvol=m_symbol.LotsMin();
   if(sl==0.0)
      lot=minvol;
   else
     {
      double loss;
      if(price==0.0)
         loss=-m_account.OrderProfitCheck(m_symbol.Name(),ORDER_TYPE_BUY,1.0,m_symbol.Ask(),sl);
      else
         loss=-m_account.OrderProfitCheck(m_symbol.Name(),ORDER_TYPE_BUY,1.0,price,sl);
      double stepvol=m_symbol.LotsStep();
      lot=MathFloor(m_account.Balance()*m_percent/loss/100.0/stepvol)*stepvol;
     }
//---
   if(lot<minvol)
      lot=minvol;
//---
   double maxvol=m_symbol.LotsMax();
   if(lot>maxvol)
      lot=maxvol;
//--- return trading volume
   return(lot);
  }

- Finally, in the code I have shared, I did not retrieve prices from the OnInit() function: the prices were set in the global space before the OnInit() call.

Hope this help.

 
Carbon13 #:


Rodger that. This is why i do not use those libraries. I assume that they are created by joe public, when they should have been created by a human calculator. The only "standard" libraries i use are Trade.mqh and Positions.mqh; simply due to similar discrepancies in the codes that were found in the past; such as you demonstrate.

However, are you saying in your last comment that your issue was resolved?

The "prices" i mention are in OnInit, including ask bid and refreshrates.

Only few days ago a moderator advised to NOT mention Point() inside of the OnInit due to it not always reporting correct value.

Forum on trading, automated trading systems and testing trading strategies

Issue: AccountInfoDouble(ACCOUNT_BALANCE) returns 0 all the time.

William Roeder, 2025.08.18 12:42

void OnInit()
  {
   Print("OnInit: ", AccountInfoDouble(ACCOUNT_BALANCE));

don't try to use any price (or indicator) or server related functions in OnInit (or on load or in OnTimer before you've received a tick), as there may be no connection/chart yet:

  1. Terminal starts.
  2. Indicators/EAs are loaded. Static and globally declared variables are initialized. (Do not depend on a specific order.)
  3. OnInit is called.
  4. For indicators OnCalculate is called with any existing history.
  5. Human may have to enter password, connection to server begins.
  6. New history is received, OnCalculate called again.
  7. A new tick is received, OnCalculate/OnTick is called. Now TickValue, TimeCurrent, account information and prices are valid.

 

Thanks for those explanations and sharing.

That means this code does not respect the advice you cite in post #4 either. This could explain the unexpected behaviour I observe (volume = 0.0).
Thus, I would say my issue is partially resolved:

- I have been able to get a non null volume; so I can pursue my projects.

- I have not yet got the opportunity to validate the calculation, accuracy and robustness;

- I still do not know why I get null volumes while running this code.

Money Fixed Risk
Money Fixed Risk
  • 2017.03.02
  • www.mql5.com
An example for calculating the lot value in accordance with the risk per trade.