ChartNavigate during initialisation

 

I have come across a problem with the ChartNavigate function. Doing something wrong or is there really a problem with the function. Write back if you have used it often enough.

So here is the crux of the problem: ChartNavigate does not shift the chart When starting the terminal if the function is called in OnInit(). I have purposefully read the documentation several times. Nowhere does it say that the function cannot be called during initialization.

Code indicator for playback:

#property indicator_chart_window 
int OnInit()
{
   if (ChartNavigate(0, CHART_END, -1000))
      Alert("Успешно");
   else
      Alert("Ошибка №", GetLastError());

   return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
}
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[])
{
   return(rates_total);
}

Steps to play:

  1. Turn off chart autoplay.
  2. Attach indicator to the chart. ChartNavigate will trigger by moving the chart to the desired position.
  3. Unload the terminal.
  4. Load the terminal. ChartNavigate will not work by displaying the chart without an offset.
OK, if the function would give an error. But it doesn't. All calls are successful, but it is when the terminal is reloaded that the chart offset does not occur.

 
You apply a function that works with the chart. For an indicator, the chart creation guarantee is the first entry in OnCalculate, for an EA it is the first entry in OnTick(). But not before.
 
Vladimir Karputov:
You apply a function that works with the chart. For the indicator the guarantee of the chart creation is the first entering in OnCalculate, for the Expert Advisor - the first entering in OnTick(). But not before.

No problem. If there is no graph yet, have the function return false and the corresponding error code. But this is not the case, the function proudly reports successful execution. Note that the documentation does not say that this is an indication of successful sending of the message to the graph. It clearly says: successful execution of the function.

Also, this is code for playback. In fact, even before the ChartNavigate call, I have a call to the timeseries. And all of them are filled correctly, as it turns out. That is, there is already a chart, there is its data. Moreover, it is possible to read from the chart the graphical objects that have been placed to it before the terminal is closed.

Thus, by all indications, the chart already exists.

 

That's weird. It works for me without any problems.

And one more note: You must disable its automatic offset CHART_AUTOSCROLL before offsetting the graph

 
Ihor Herasko:

No problem. If there is no graph yet, have the function return false and the corresponding error code. But this is not the case, the function proudly reports successful execution. Note that the documentation does not say that this is a sign of successful sending of the message to the graph. It clearly says: successful execution of the function.

Also, this is code for playback. In fact, even before the ChartNavigate call, I have a call to the timeseries. And all of them are filled correctly, as it turns out. That is, there is already a chart, there is its data. Moreover, it is possible to read from the chart the graphical objects that have been placed to it before the terminal is closed.

Thus, by all indications, the chart already exists.

Chart and data are two great differences.

All functions referring to charts are asynchronous: i.e. one-way - shot and forgotten. And in this case true just means that you have filled in the fields of this function correctly, nothing more.

The sign when all the data is ready and the graphs are plotted is the first input to Oncalculate/OnTick.

 
Vladimir Karputov:

A graph and data are two big differences.

All graph access functions are asynchronous: i.e. a one-way trip - shot and forgotten. In this case, true means only that you have correctly filled in the fields of this function, nothing more.

The sign when all the data is ready and the graphs are plotted is the first input to Oncalculate/OnTick.

Then how do you explain the fact that it works flawlessly for me? In OnInit() exactly as in the first post of the thread... Why are you making up nonsense?

 
Alexey Viktorov:

That's weird. It works for me without any problems.

What build do you have? I have 1861.

And one more note: You should disable its automatic offset CHART_AUTOSCROLL before offsetting the graph

Yes, I pointed that out in the first step for playback.

 
Ihor Herasko:

What is your build? I have 1861.

Yes, that's what I pointed out in the first step for replay.

I have 1861 too. Only managed to reproduce it once. All other attempts have worked fine.

 
Vladimir Karputov:

A graph and data are two big differences.

All graph access functions are asynchronous: i.e. a one-way trip - shot and forgotten.

No, not all of them. The ones that do are specifically commented out. For example, the same ChartApplyTemplate.

In this case, true means only that you have correctly filled in the fields of this function, nothing more.

How did the function determine that the chart ID is correct, if the chart itself does not exist yet?

The sign when all data is ready and graphs are plotted is the first input to Oncalculate/OnTick.

Unfortunately, no. Here's the code:

#property indicator_chart_window 
int OnInit()
{
   Print(__FUNCTION__, ", баров: ", Bars(Symbol(), PERIOD_CURRENT));

   return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
}
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__, ", баров: ", Bars(Symbol(), PERIOD_CURRENT));
   return(rates_total);
}

It works like this:

16:01:31.765    Test (XBNUSD,M1)        OnInit, баров: 0
16:01:33.531    Test (XBNUSD,M1)        OnCalculate, баров: 37026
16:01:34.010    Test (XBNUSD,M1)        OnCalculate, баров: 46484

I run the indicator on a new symbol whose chart has never yet been opened, i.e. no data has been generated on it yet.

In the first line (OnInit) there is indeed no data. However, there is the chart ID and we can create objects in OnInit() that will be successfully displayed on the chart.

The second line already has data, but it is incomplete. The data is complete at the third iteration.

It is reasonable to conclude that the first call to OnCalculate is not a guarantee of data loading. It is simply the first tick on the symbol after opening the chart, which may come either after some amount of data or without any other data at all.

Returning to the problem raised in the topic, we get that the ChartNavigate() function does not check the correctness of parameters. If there is no data yet in OnInit() (0 bars), and the value -1000 is passed to the function, then how can we consider this value correct, if there are no bars? After all, any other function would return an error when accessing the bar with a non-existing index. But it is successful here. What is successful exactly?

 

Here is the indicator - specially put a delay of nine ticks, two types of chart movement and the flag of forced re-drawing (on/off).

//+------------------------------------------------------------------+
//|                                                      ProjectName |
//|                                      Copyright 2012, CompanyName |
//|                                       http://www.companyname.net |
//+------------------------------------------------------------------+
#property indicator_chart_window 
#property indicator_plots 0
//--- input parameters
input bool redraw=true;
input ENUM_CHART_POSITION position=CHART_BEGIN;
//---
long count=0;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
   count=0;
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   Comment("");
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
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[])
  {
   count++;
   Comment(count);
   if(count==9)
     {
      ResetLastError();
      if(position==CHART_BEGIN)
        {
         if(ChartNavigate(0,CHART_BEGIN,100))
            Print("Успешно. redraw ",redraw,". position ",EnumToString(position));
         else
            Print("Ошибка №",GetLastError(),". redraw ",redraw,". position ",EnumToString(position));
        }
      if(position==CHART_END)
        {
         if(ChartNavigate(0,CHART_END,-100))
            Print("Успешно. redraw ",redraw,". position ",EnumToString(position));
         else
            Print("Ошибка №",GetLastError(),". redraw ",redraw,". position ",EnumToString(position));
        }
      if(redraw)
         ChartRedraw();
     }
   return(rates_total);
  }
//+------------------------------------------------------------------+


Preliminary:CHART_BEGIN isstable.

Files:
Test.mq5  6 kb
 
Vladimir Karputov:

Here is the indicator - specially put a delay of nine ticks, two types of chart movement and the flag of forced re-drawing (on/off).


Preliminary:CHART_BEGIN works steadily.

But what if there are no ticks, it is weekend? Then the timer will have to be connected.

And there is only one question to solve: how to determine whether ChartNavigate has been successfully executed? The fact that it returns true, it just "ticks", it does not help in real work.

Reason: