strategy tester error

 

I am wondering if someone can help me figure out this issue: 

the MQL5 function in SymbolInfo.mqh : Point()

returns

Point: 0.00001000  when I call it via the Comment

(which is correct and as expected .....)

and returns : 

Point :-1998362383  in the strategy tester !!! 

how can that be? 


 
justinmcridge :

I am wondering if someone can help me figure out this issue: 

the MQL5 function in SymbolInfo.mqh : Point()

returns

Point: 0.00001000  when I call it via the Comment

(which is correct and as expected .....)

and returns : 

Point :-1998362383  in the strategy tester !!! 

how can that be? 


Do you initialize the object of the CSymbolInfo class? Show your code (code header and OnInit are especially interested)

 
Vladimir Karputov:

Do you initialize the object of the CSymbolInfo class? Show your code (code header and OnInit are especially interested)

I did initialize the objects. or so I thought 

here is part of the code:

//---
#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
CPositionInfo  m_position;                   // trade position object
CTrade         m_trade;                      // trading object
CSymbolInfo    m_symbol;                     // symbol info object
//--- input parameters

sinput string           _1_               = "Trade settings";     // Trade settings
input double            InpLots           = 0.5;                  // Lots
input ushort            InpStopLoss       = 130;                   // Stop Loss (in pips)
input ushort            InpTakeProfit     = 170;                   // Take Profit (in pips)
input ulong             m_magic           = 108813112;            // magic number
 
  
input int             InpTrailingStop=30;
 
//---
ulong                   m_slippage = 15;                          // slippage

double                  ExtStopLoss = 0.0;
double                  ExtTakeProfit = 0.0;

int                     handle_MACD;                         // variable for storing the handle of the MACD indicator
input int                MACD_open_level;
input int                MACD_close_level;
int            handle_EMA;

double                  m_adjusted_point;                         // point value adjusted for 3 or 5 points
//----
bool buysig, sellsig;
int lastsig;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   if(!m_symbol.Name(Symbol()))
      return(INIT_FAILED);
   RefreshRates();
//---
   m_trade.SetExpertMagicNumber(m_magic);
//---
   if(IsFillingTypeAllowed(SYMBOL_FILLING_FOK))
      m_trade.SetTypeFilling(ORDER_FILLING_FOK);
   else
      if(IsFillingTypeAllowed(SYMBOL_FILLING_IOC))
         m_trade.SetTypeFilling(ORDER_FILLING_IOC);
      else
         m_trade.SetTypeFilling(ORDER_FILLING_RETURN);
//---
   m_trade.SetDeviationInPoints(m_slippage);
//--- tuning for 3 or 5 digits
   int digits_adjust = 1;
   if(m_symbol.Digits() == 3 || m_symbol.Digits() == 5)
      digits_adjust = 10;
      if (!m_symbol.Refresh()) return (INIT_FAILED);
   m_adjusted_point = m_symbol.Point() * digits_adjust;
   double pip =  m_symbol.Point();
 
 double m_macd_open_level =MACD_open_level*m_adjusted_point;
  double   m_macd_close_level=MACD_close_level*m_adjusted_point;
  double   m_traling_stop    =InpTrailingStop*m_adjusted_point;
  double    m_take_profit     =InpTakeProfit*m_adjusted_point;


   ExtStopLoss = InpStopLoss * m_adjusted_point;
   ExtTakeProfit = InpTakeProfit * m_adjusted_point;
   PrintFormat(" Point :%d",m_symbol.Point());
   Comment("Point",DoubleToString(m_symbol.Point()));
 
   
   PrintFormat(" m_adjusted_point :%d",m_adjusted_point);
 
   PrintFormat(" ExtStopLoss  :%d", ExtStopLoss);
   PrintFormat(" ExtTakeProfit :%d",ExtTakeProfit );
   
//--- create handle of the indicator MACD
               handle_MACD = iMACD(NULL,0,27,7,5,PRICE_CLOSE);
//--- if the handle is not created
               if(handle_MACD == INVALID_HANDLE)
  {
//--- tell about the failure and output the error code
   PrintFormat("Failed to create handle of the MACD indicator for the symbol %s/%s, error code %d",
               m_symbol.Name(),
               EnumToString(Period()),
               GetLastError());

      //--- the indicator is stopped early
      return(INIT_FAILED);
     }
 //--- create handle of the indicator EMA
               handle_EMA = iMA(NULL,0,27,0,MODE_EMA,PRICE_CLOSE);
               //--- if the handle is not created
               if(handle_EMA == INVALID_HANDLE)
  {
//--- tell about the failure and output the error code
   PrintFormat("Failed to create handle of the EMA indicator for the symbol %s/%s, error code %d",
               m_symbol.Name(),
               EnumToString(Period()),
               GetLastError());

      //--- the indicator is stopped early
      return(INIT_FAILED);
     }    
     
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- we work only at the time of the birth of new bar
   static datetime PrevBars = 0;
   datetime time_0 = Timei(0);
   if(time_0 == PrevBars)
      return;
   PrevBars = time_0;
   if(!RefreshRates())
     {
      PrevBars = Timei(1);
      return;
     }
//---
   bool  buys = false;
   bool  sells = false;
   if(!CheckForSignals(buys, sells))
     {
      PrevBars = Timei(1);
      return;
     }
   if(buys)
     {
      double sl = (InpStopLoss == 0) ? 0.0 : m_symbol.Ask() - ExtStopLoss;
      double tp = (InpTakeProfit == 0) ? 0.0 : m_symbol.Ask() + ExtTakeProfit;
      PrintFormat("the stoploss used is = %d",sl);
      PrintFormat( "the TP used is =%d",tp);
      OpenBuy(sl, tp);
      ClosePositions(POSITION_TYPE_SELL);
     }
   if(sells)
     {
      double sl = (InpStopLoss == 0) ? 0.0 : m_symbol.Bid() + ExtStopLoss;
      double tp = (InpTakeProfit == 0) ? 0.0 : m_symbol.Bid() - ExtTakeProfit;
      PrintFormat("the stoploss used is = %d",sl);
      PrintFormat( "the TP used is =%d",tp);
      OpenSell(sl, tp);
      ClosePositions(POSITION_TYPE_BUY);
     }
//---
  }
//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
//---

  }

//=============================================================================

//+------------------------------------------------------------------+
//| Refreshes the symbol quotes data                                 |
//+------------------------------------------------------------------+
bool RefreshRates(void)
  {
//--- refresh rates
   if(!m_symbol.RefreshRates())
     {
      Print("RefreshRates error");
      return(false);
     }
//--- protection against the return value of "zero"
   if(m_symbol.Ask() == 0 || m_symbol.Bid() == 0)
      return(false);
//---
   return(true);
  }
//+------------------------------------------------------------------+
//| Check the correctness of the order volume                        |
//+------------------------------------------------------------------+
bool CheckVolumeValue(double volume, string &error_description)
  {
//--- minimal allowed volume for trade operations
// double min_volume=m_symbol.LotsMin();
   double min_volume = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_MIN);
   if(volume < min_volume)
     {
      error_description = StringFormat("Volume is less than the minimal allowed SYMBOL_VOLUME_MIN=%.2f", min_volume);
      return(false);
     }

//--- maximal allowed volume of trade operations
// double max_volume=m_symbol.LotsMax();
   double max_volume = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_MAX);
   if(volume > max_volume)
     {
      error_description = StringFormat("Volume is greater than the maximal allowed SYMBOL_VOLUME_MAX=%.2f", max_volume);
      return(false);
     }

//--- get minimal step of volume changing
// double volume_step=m_symbol.LotsStep();
   double volume_step = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_STEP);

   int ratio = (int)MathRound(volume / volume_step);
   if(MathAbs(ratio * volume_step - volume) > 0.0000001)
     {
      error_description = StringFormat("Volume is not a multiple of the minimal step SYMBOL_VOLUME_STEP=%.2f, the closest correct volume is %.2f",
                                       volume_step, ratio * volume_step);
      return(false);
     }
   error_description = "Correct volume value";
   return(true);
  }
//+------------------------------------------------------------------+
//| Checks if the specified filling mode is allowed                  |
//+------------------------------------------------------------------+
bool IsFillingTypeAllowed(int fill_type)
  {
//--- Obtain the value of the property that describes allowed filling modes
   int filling = m_symbol.TradeFillFlags();
//--- Return true, if mode fill_type is allowed
   return((filling & fill_type) == fill_type);
  }
//+------------------------------------------------------------------+
//| Get Time for specified bar index                                 |
//+------------------------------------------------------------------+
datetime Timei(const int index, string symbol = NULL, ENUM_TIMEFRAMES timeframe = PERIOD_CURRENT)
  {
   if(symbol == NULL)
      symbol = Symbol();
   if(timeframe == 0)
      timeframe = Period();
   datetime Time[1];
   datetime time = 0;
   int copied = CopyTime(symbol, timeframe, index, 1, Time);
   if(copied > 0)
      time = Time[0];
   return(time);
  }
 
//---------------------------------MACD 
double MACDGet(const int buffer, const int index)
  {
   double MACD_buff[];
   ArraySetAsSeries(MACD_buff,true);
//--- reset error code
   ResetLastError();
//--- fill a part of the MACD array with values from the indicator buffer that has 0 index
   if(CopyBuffer(handle_MACD, buffer, index, 1, MACD_buff) < 0)
     {
      //--- if the copying fails, tell the error code
      PrintFormat("Failed to copy data from the MACD indicator, error code %d", GetLastError());
      //--- quit with zero result - it means that the indicator is considered as not calculated
      return(0.0);
     }
   return(MACD_buff[0]);
  }
  
//---------------------------------------EMA
double EMAGet(const int buffer, const int index)
  {
   double EMA_buff[];
   ArraySetAsSeries(EMA_buff,true);
//--- reset error code
   ResetLastError();
//--- fill a part of the EMA array with values from the indicator buffer that has 0 index
   if(CopyBuffer(handle_EMA, buffer, index, 1, EMA_buff) < 0)
     {
      //--- if the copying fails, tell the error code
      PrintFormat("Failed to copy data from the EMA indicator, error code %d", GetLastError());
      //--- quit with zero result - it means that the indicator is considered as not calculated
      return(0.0);
     }
   return(EMA_buff[0]);
  } 
//+------------------------------------------------------------------+
//| Get Open for specified bar index                                 |
//+------------------------------------------------------------------+
double Openi(string symbol = NULL,   ENUM_TIMEFRAMES timeframe = PERIOD_CURRENT, const int index = 0)
  {
   if(symbol == NULL)
      symbol = m_symbol.Name();
   if(timeframe == 0)
      timeframe = Period();
   double Open[1];
   double open = 0;

   int copied = CopyOpen(symbol, timeframe, index, 1, Open);
   if(copied > 0)
      open = Open[0];
   return(open);
  }
//+------------------------------------------------------------------+
//| Get Close for specified bar index                                |
//+------------------------------------------------------------------+
double Closei(string symbol = NULL, ENUM_TIMEFRAMES timeframe = PERIOD_CURRENT, const int index = 0)
  {
   if(symbol == NULL)
      symbol = m_symbol.Name();
   if(timeframe == 0)
      timeframe = Period();
   double Close[1];
   double close = 0;
   int copied = CopyClose(symbol, timeframe, index, 1, Close);
   if(copied > 0)
      close = Close[0];
   return(close);
  }
//+------------------------------------------------------------------+
//| Check for open order conditions                                  |
//+------------------------------------------------------------------+
bool CheckForSignals(bool  &buys, bool  &sells)
  {
 
   double MACDMainCurr = MACDGet(0, 1);
   double MACDMainPrev = MACDGet(0, 2);

   double MACDSignalCurr = MACDGet(1, 1);
    double MACDSignalPrev = MACDGet(1, 2);
    
    double EMACurr = EMAGet(0,1);
    double EMAPrev= EMAGet(0,2);
    
  double m_macd_open_level =MACD_open_level*m_adjusted_point;
  double   m_macd_close_level=MACD_close_level*m_adjusted_point;
  double   m_traling_stop    =InpTrailingStop*m_adjusted_point;
  double    m_take_profit     =InpTakeProfit*m_adjusted_point;
    
//PrintFormat( "MACDSignal  = %s", DoubleToString(MACDSignal));
 
   double Open = Openi(_Symbol, Period(), 1);
   double Close = Closei(_Symbol, Period(), 1);
   if(Open == 0.0 || Close == 0.0)
      return(false);

  if(MACDMainCurr<0)
      {
      if(MACDMainCurr  > MACDSignalCurr && MACDMainPrev <MACDSignalPrev)
         {
           if(MathAbs(MACDMainCurr)>(m_macd_open_level) && EMACurr>EMAPrev)
           {
            //--- sell signal
            buys = true;
            sells = false;
            return(true);
           }
           
        }
      }
   if(MACDMainCurr>0)
       {if(MACDMainCurr<MACDSignalCurr && MACDMainPrev>MACDSignalPrev)
         {if(MACDMainCurr>(m_macd_open_level) && EMACurr<EMAPrev)
           {
            //--- sell signal
            buys = false;
            sells = true;
            return(true);
           }
          }  
       }
           
//---
   return(false);
  }
//+------------------------------------------------------------------+
//| Close positions                                                  |
//+------------------------------------------------------------------+
void ClosePositions(const ENUM_POSITION_TYPE pos_type)
  {
   for(int i = PositionsTotal() - 1; i >= 0; i--) // returns the number of current positions
      if(m_position.SelectByIndex(i))     // selects the position by index for further access to its properties
         if(m_position.Symbol() == Symbol() && m_position.Magic() == m_magic)
            if(m_position.PositionType() == pos_type) // gets the position type
               m_trade.PositionClose(m_position.Ticket()); // close a position by the specified symbol
  }
//+------------------------------------------------------------------+
//| Open Buy position                                                |
//+------------------------------------------------------------------+
void OpenBuy(double sl, double tp)
  {
   sl = m_symbol.NormalizePrice(sl);
   tp = m_symbol.NormalizePrice(tp);
//--- check volume before OrderSend to avoid "not enough money" error (CTrade)
   double check_volume_lot = m_trade.CheckVolume(m_symbol.Name(), InpLots, m_symbol.Ask(), ORDER_TYPE_BUY);

   if(check_volume_lot != 0.0)
      if(check_volume_lot >= InpLots)
        {
         if(m_trade.Buy(InpLots, NULL, m_symbol.Ask(), sl, tp))
           {
            if(m_trade.ResultDeal() == 0)
              {
               Print("#1 Buy -> false. Result Retcode: ", m_trade.ResultRetcode(),
                     ", description of result: ", m_trade.ResultRetcodeDescription());
               //PrintResult(m_trade,m_symbol);
              }
            else
              {
               Print("#2 Buy -> true. Result Retcode: ", m_trade.ResultRetcode(),
                     ", description of result: ", m_trade.ResultRetcodeDescription());
               //PrintResult(m_trade,m_symbol);
              }
           }
         else
           {
            Print("#3 Buy -> false. Result Retcode: ", m_trade.ResultRetcode(),
                  ", description of result: ", m_trade.ResultRetcodeDescription());
            //PrintResult(m_trade,m_symbol);
           }
        }
//---
  }
//+------------------------------------------------------------------+
//| Open Sell position                                               |
//+------------------------------------------------------------------+
void OpenSell(double sl, double tp)
  {
   sl = m_symbol.NormalizePrice(sl);
   tp = m_symbol.NormalizePrice(tp);
//--- check volume before OrderSend to avoid "not enough money" error (CTrade)
   double check_volume_lot = m_trade.CheckVolume(m_symbol.Name(), InpLots, m_symbol.Bid(), ORDER_TYPE_SELL);

   if(check_volume_lot != 0.0)
      if(check_volume_lot >= InpLots)
        {
         if(m_trade.Sell(InpLots, NULL, m_symbol.Bid(), sl, tp))
           {
            if(m_trade.ResultDeal() == 0)
              {
               Print("#1 Sell -> false. Result Retcode: ", m_trade.ResultRetcode(),
                     ", description of result: ", m_trade.ResultRetcodeDescription());
               //PrintResult(m_trade,m_symbol);
              }
            else
              {
               Print("#2 Sell -> true. Result Retcode: ", m_trade.ResultRetcode(),
                     ", description of result: ", m_trade.ResultRetcodeDescription());
               //PrintResult(m_trade,m_symbol);
              }
           }
         else
           {
            Print("#3 Sell -> false. Result Retcode: ", m_trade.ResultRetcode(),
                  ", description of result: ", m_trade.ResultRetcodeDescription());
            //PrintResult(m_trade,m_symbol);
           }
        }
//---
  }
//+------------------------------------------------------------------+

 output from log  file attached  :     Point :-1998362383 <----------------------------------------------- error here

but when I run it in debug it prints a comment as 0.00001000

Files:
Error.log  273 kb
res.PNG  3 kb
 
justinmcridge:

I did initialize the objects. or so I thought 

here is part of the code:

 output from log  file attached  :     Point :-1998362383 <----------------------------------------------- error here

but when I run it in debug it prints a comment as 0.00001000

Read Help:

//---
   if(!m_symbol.Name(Symbol())) // sets symbol name
     {
      Print(__FILE__," ",__FUNCTION__,", ERROR: CSymbolInfo.Name");
      return(INIT_FAILED);
     }
   RefreshRates();
//---
   ***
//--- double value output with variable number of digits after the decimal point
   double point_value=m_symbol.Point();
   string format_string=StringFormat("%%s: point value  = %%.%df",m_symbol.Digits());
   PrintFormat(format_string,m_symbol.Name(),point_value);
 
Vladimir Karputov:

Read Help:

It did actually format it as a string and printed it as 0.0001 in the log file.

so I am using the StringToDouble to read the 0.0001 as as double so  I can use it in calculations

it returned the same wrong number!!! 

so i was wondering if this a MQL issue or C++ issue

 
justinmcridge:

It did actually format it as a string and printed it as 0.0001 in the log file.

so I am using the StringToDouble to read the 0.0001 as as double so  I can use it in calculations

it returned the same wrong number!!! 

so i was wondering if this a MQL issue or C++ issue

That's a Justin Mcridge issue.

PrintFormat(" Point :%d",m_symbol.Point());

Read the documentation please. You are using %d all over to print double value. %d is for an INT !

 
Alain Verleyen:

That's a Justin Mcridge issue.

Read the documentation please. You are using %d all over to print double value. %d is for an INT !

Nice one. ;)

Reason: