Download MetaTrader 5

CHARTEVENT_MOUSE_MOVE and OnCalculate in Indicator

To add comments, please log in or register
GmA
33
GmA 2015.09.28 11:35 

Dear experts!

I have created an indicator what is using CHARTEVENT_MOUSE_MOVE event. It was recognized that after OnChartEvent has processed  CHARTEVENT_MOUSE_MOVE,  OnCalculate is called with prev_calculated equal to zero (irrespective of what  OnCalculate has returned on the last its run). Is it normal behavior? If it is normal, could you please clarify why prev_calculated  is set to zero? If it is not normal behavior, what could cause it

Thank you very much in advance and

Kind regards

GmA 

Vladimir Karputov
Moderator
49415
Vladimir Karputov 2015.09.28 12:15  
GmA :

Dear experts!

I have created an indicator what is using CHARTEVENT_MOUSE_MOVE event. It was recognized that after OnChartEvent has processed  CHARTEVENT_MOUSE_MOVE,  OnCalculate is called with prev_calculated equal to zero (irrespective of what  OnCalculate has returned on the last its run). Is it normal behavior? If it is normal, could you please clarify why prev_calculated  is set to zero? If it is not normal behavior, what could cause it

Thank you very much in advance and

Kind regards

GmA 

Processing events CHARTEVENT_MOUSE_MOVE not affect the prev_calculated:

 

//+------------------------------------------------------------------+
//|                                        CHARTEVENT_MOUSE_MOVE.mq5 |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_plots 0
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- 
   ResetLastError();
   if(!ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,true))
     {
      Print("Error ",GetLastError());
      return(INIT_FAILED);
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {
//---
   Print(__FUNCTION__,", prev_calculated=",prev_calculated);
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//---
   if(id==CHARTEVENT_MOUSE_MOVE)
      Print(__FUNCTION__);
  }
//+------------------------------------------------------------------+
GmA
33
GmA 2015.09.28 16:15  

Hello Vladimir!

 

Thank you  very much for the fast response. 

I have made further investigation and found that the call of  OnCalculate is caused by CopyRates or CopyTime function what I am using to define on what bar mouse pointer is. 

Hence again the question:  is that a normal behavior when  CopyRates or CopyTime are calling OnCalculate with prev_calculated parameter equal to zero?  Is there any way to block it or is there any way to find on what bar ID the mouse pointer is without calling CopyTime/CopyRates functions?


With kind regards

GmA 

Vladimir Karputov
Moderator
49415
Vladimir Karputov 2015.09.28 16:20  
GmA :

Hello Vladimir!

 

Thank you  very much for the fast response. 

I have made further investigation and found that the call of   OnCalculate  is caused by CopyRates or CopyTime function what I am using to define on what bar mouse pointer is. 

Hence again the question:  is that a normal behavior when  CopyRates or CopyTime are calling  OnCalculate  with prev_calculated parameter equal to zero?  Is there any way to block it or is there any way to find on what bar ID the mouse pointer is without calling CopyTime/CopyRates functions?


With kind regards

GmA 

Understood nothing. Sorry, I do not know how to read thoughts. Where is your code?
GmA
33
GmA 2015.09.28 17:00  

Sorry. Here is relevant  part of code:


          case CHARTEVENT_MOUSE_MOVE:
               {
                bTemp      = ChartXYToTimePrice(0, (int) lparam, (int) dparam, iSubWindow, dtBarTime, dPrice); 
                iBarID     = iBarShift(NULL,0,dtBarTime);
		.........	

                break;
               }             

 

int iBarShift(string sSymbol, ENUM_TIMEFRAMES eTF, datetime dtTime, bool bExact=true)
{
 datetime   dtTime_Array_0 [];
 datetime   dtTime_Array   [];
 
 int        iResult                          = 0;
 
 if(dtTime < 0) 
   {
    return(-1);
   }
 
 
 iResult                               = CopyTime(sSymbol, eTF, Bars(NULL,0)-1, 1, dtTime_Array_0);
 if (iResult <=0)
      {
       return (-1);
      }
 iResult                               = CopyTime(sSymbol, eTF,dtTime_Array_0 [0], dtTime, dtTime_Array);     
 if(iResult>0) 
    {
     iReturn                           = ArraySize(dtTime_Array)-1; 
    }
 return(iReturn); 
}

 As soon as I am commenting parts of code

iResult                               = CopyTime(sSymbol, eTF, Bars(NULL,0)-1, 1, dtTime_Array_0);
 iResult                               = CopyTime(sSymbol, eTF,dtTime_Array_0 [0], dtTime, dtTime_Array); 

 OnCalculate is no more called.

 

With kind regards

GmA 

Vladimir Karputov
Moderator
49415
Vladimir Karputov 2015.09.28 17:19  
What is dtBarTime? What is the significance of taking this option?
Assemble a workable code. It is not clear how many items you copy via CopyTime. For example, just type your variables:

//+------------------------------------------------------------------+
//|                                        CHARTEVENT_MOUSE_MOVE.mq5 |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_plots 0
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- 
   ResetLastError();
   if(!ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,true))
     {
      Print("Error ",GetLastError());
      return(INIT_FAILED);
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {
//---
   Print(__FUNCTION__,", prev_calculated=",prev_calculated);
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//---
   if(id==CHARTEVENT_MOUSE_MOVE)
     {
      Print(__FUNCTION__);
      int      iBarID;
      //bTemp    = ChartXYToTimePrice(0, (int) lparam, (int) dparam, iSubWindow, dtBarTime, dPrice);
      iBarID   = iBarShift(NULL,0,dtBarTime);
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int iBarShift(string sSymbol,ENUM_TIMEFRAMES eTF,datetime dtTime,bool bExact=true)
  {
   datetime    dtTime_Array_0[];
   datetime    dtTime_Array[];

   int         iResult=0;
   int         iReturn=0;

   if(dtTime<0)
     {
      return(-1);
     }

   iResult=CopyTime(sSymbol,eTF,Bars(NULL,0)-1,1,dtTime_Array_0);
   if(iResult<=0)
     {
      return (-1);
     }
   Print("iResult=",iResult);
   iResult=CopyTime(sSymbol,eTF,dtTime_Array_0[0],dtTime,dtTime_Array);
   if(iResult>0)
     {
      iReturn=ArraySize(dtTime_Array)-1;
     }
   Print("iResult=",iResult,", iReturn=",iReturn);
   return(iReturn);
  }
//+------------------------------------------------------------------+
GmA
33
GmA 2015.09.28 23:57  

I've been able to find an issue. 

Here is the code tested:

//+------------------------------------------------------------------+
//|                                                         Test.mq5 |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+

double   sgPlot [];

int OnInit()
  {
   SetIndexBuffer( 0,sgPlot,INDICATOR_DATA);
   PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_LINE); 
   
   if(!ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,true))
     {
      Print("Error ",GetLastError());
      return(INIT_FAILED);
     }
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
  Print(__FUNCTION__,", prev_calculated =",prev_calculated);
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
   datetime dtBarTime                  = 0;
   double   dPrice                     = 0;
   int      iBarID                     = -1;
   int      iSubWindow                 = 0;
   bool     bTemp                      = false;
   
   switch (id)
      {
       case CHARTEVENT_MOUSE_MOVE:
            {
             bTemp    = ChartXYToTimePrice(0, (int) lparam, (int) dparam, iSubWindow, dtBarTime, dPrice);
             iBarID   = iBarShift(NULL,0,dtBarTime);
             Print(__FUNCTION__," iBarID = ",iBarID );
             break;                        
            }          
      }
   
  }
//+------------------------------------------------------------------+
int iBarShift(string sSymbol, ENUM_TIMEFRAMES eTF, datetime dtTime, bool bExact=true)
{
 datetime   dtTime_Array_0 [];
 datetime   dtTime_Array   [];
 
 int        iResult                          = 0;
 int        iReturn                          = -1;
 
 iResult                               = CopyTime(sSymbol, eTF, Bars(sSymbol,eTF)-1, 1, dtTime_Array_0);
// Print (" Time of ZeroBar = ",dtTime_Array_0[0], " dtTime = "+dtTime);
 if (iResult <=0)
      {
       return (iReturn);
      }
 Print ("Bar [0] time = ",dtTime_Array_0[0], " dtTime = ",dtTime);      
 iResult                               = CopyTime(sSymbol, eTF,dtTime_Array_0 [0], dtTime, dtTime_Array);     
 if(iResult>0) 
    {
     iReturn                           = ArraySize(dtTime_Array)-1; 
    }
 return(iReturn); 
}

 The problem comes from that part:

      case CHARTEVENT_MOUSE_MOVE:
            {
             bTemp    = ChartXYToTimePrice(0, (int) lparam, (int) dparam, iSubWindow, dtBarTime, dPrice);
             iBarID   = iBarShift(NULL,0,dtBarTime);
             Print(__FUNCTION__," iBarID = ",iBarID );
             break;                        
            }          

where I did not check the result of the ChartXYToTimePrice function. When cursor was moving  out of the chart,  this function has returned "false" and  dtBarTime variable has not been updated. The value 1970.01.01 00:00:00 has been transferred into  CopyTime function and, finally,  OnCalculate with prev_calculated  =0  was called as the quotes were updated.

Lesson learnt.

Thank you for the provided direction and fast responses.

Kind regards

GmA 

Vladimir Karputov
Moderator
49415
Vladimir Karputov 2015.09.29 04:03  
GmA:

I've been able to find an issue. 

Here is the code tested:

 The problem comes from that part:

where I did not check the result of the ChartXYToTimePrice function. When cursor was moving  out of the chart,  this function has returned "false" and  dtBarTime variable has not been updated. The value 1970.01.01 00:00:00 has been transferred into  CopyTime function and, finally,  OnCalculate with prev_calculated  =0  was called as the quotes were updated.

Lesson learnt.

Thank you for the provided direction and fast responses.

Kind regards

GmA 

Glad to help you.
To add comments, please log in or register