ChartNavigate durante la inicialización

 

He encontrado un problema con la función ChartNavigate. Estoy haciendo algo mal o realmente hay un problema con la función. Escribe si lo has utilizado con frecuencia.

Así que aquí está el quid del problema: ChartNavigate no desplaza el gráfico Al iniciar el terminal si la función se llama en OnInit(). He leído a propósito la documentación varias veces. En ninguna parte dice que la función no puede ser llamada durante la inicialización.

Código indicador para la reproducción:

#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);
}

Pasos para jugar:

  1. Desactivar la reproducción automática de gráficos.
  2. Adjunte el indicador al gráfico. ChartNavigate se activará moviendo el gráfico a la posición deseada.
  3. Descargue el terminal.
  4. Cargue el terminal. ChartNavigate no funcionará mostrando el gráfico sin un desplazamiento.
OK, si la función diera un error. Pero no es así. Todas las llamadas tienen éxito, pero es cuando se recarga el terminal cuando no se produce el desplazamiento del gráfico.

 
Se aplica una función que funciona con el gráfico. Para un indicador, la garantía de creación del gráfico es la primera entrada en OnCalculate, para un EA es la primera entrada en OnTick(). Pero no antes.
 
Vladimir Karputov:
Se aplica una función que funciona con el gráfico. Para el indicador la garantía de la creación del gráfico es la primera entrada en OnCalculate, para el Asesor Experto - la primera entrada en OnTick(). Pero no antes.

No hay problema. Si todavía no hay gráfico, que la función devuelva false y el código de error correspondiente. Pero este no es el caso, la función informa orgullosamente de la ejecución exitosa. Tenga en cuenta que la documentación no dice que esto sea una indicación de que el envío del mensaje al gráfico ha sido exitoso. Dice claramente: ejecución exitosa de la función.

Además, esto es un código para la reproducción. De hecho, incluso antes de la llamada a ChartNavigate, tengo una llamada a la serie temporal. Y todos ellos se llenan correctamente, como resulta. Es decir, ya hay un gráfico, hay sus datos. Además, es posible leer en la carta los objetos gráficos que se han colocado en ella antes de cerrar el terminal.

Por lo tanto, según todos los indicios, el gráfico ya existe.

 

Eso es raro. A mí me funciona sin problemas.

Y una nota más: Debes desactivar su desplazamiento automático CHART_AUTOSCROLL antes de desplazar el gráfico

 
Ihor Herasko:

No hay problema. Si todavía no hay gráfico, que la función devuelva false y el código de error correspondiente. Pero este no es el caso, la función informa orgullosamente de la ejecución exitosa. Tenga en cuenta que la documentación no dice que esto sea una señal de que el envío del mensaje al gráfico ha sido exitoso. Dice claramente: ejecución exitosa de la función.

Además, esto es un código para la reproducción. De hecho, incluso antes de la llamada a ChartNavigate, tengo una llamada a la serie temporal. Y todos ellos se rellenan correctamente, como resulta. Es decir, ya hay un gráfico, hay sus datos. Además, es posible leer en la carta los objetos gráficos que se han colocado en ella antes de cerrar el terminal.

Por lo tanto, según todos los indicios, el gráfico ya existe.

Los gráficos y los datos son dos grandes diferencias.

Todas las funciones referidas a los gráficos son asíncronas: es decir, unidireccionales: se disparan y se olvidan. Y en este caso true sólo significa que has rellenado correctamente los campos de esta función, nada más.

La señal cuando todos los datos están listos y los gráficos están trazados es la primera entrada a Oncalculate/OnTick.

 
Vladimir Karputov:

Un gráfico y los datos son dos grandes diferencias.

Todas las funciones de acceso a los gráficos son asíncronas: es decir, un viaje de ida - disparado y olvidado. En este caso, true significa sólo que ha rellenado correctamente los campos de esta función, nada más.

La señal cuando todos los datos están listos y los gráficos están trazados es la primera entrada a Oncalculate/OnTick.

Entonces, ¿cómo se explica que me funcione sin problemas? En OnInit() exactamente como en el primer post del hilo... ¿Por qué te inventas tonterías?

 
Alexey Viktorov:

Eso es raro. A mí me funciona sin problemas.

¿Qué tipo de construcción tienes? Tengo 1861.

Y una nota más: Debes desactivar su desplazamiento automático CHART_AUTOSCROLL antes de desplazar el gráfico

Sí, lo señalé en el primer paso para la reproducción.

 
Ihor Herasko:

¿Cuál es su constitución? Tengo 1861.

Sí, eso es lo que señalé en el primer paso para la repetición.

Yo también tengo 1861. Sólo he conseguido reproducirlo una vez. Todos los demás intentos han funcionado bien.

 
Vladimir Karputov:

Un gráfico y los datos son dos grandes diferencias.

Todas las funciones de acceso a los gráficos son asíncronas: es decir, un viaje de ida - disparado y olvidado.

No, no todos. Los que lo hacen están específicamente comentados. Por ejemplo, el mismo ChartApplyTemplate.

En este caso, true significa sólo que ha rellenado correctamente los campos de esta función, nada más.

¿Cómo determina la función que el ID del gráfico es correcto, si el gráfico en sí no existe todavía?

La señal cuando todos los datos están listos y los gráficos están trazados es la primera entrada a Oncalculate/OnTick.

Por desgracia, no. Aquí está el código:

#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);
}

Funciona así:

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

Ejecuto el indicador en un nuevo símbolo cuyo gráfico aún no se ha abierto, es decir, aún no se han generado datos en él.

En la primera línea (OnInit) efectivamente no hay datos. Sin embargo, existe el ID del gráfico y podemos crear objetos en OnInit() que se mostrarán con éxito en el gráfico.

La segunda línea ya tiene datos, pero están incompletos. Los datos están completos en la tercera iteración.

Es razonable concluir que la primera llamada a OnCalculate no es una garantía de carga de datos. Es simplemente el primer tick del símbolo después de abrir el gráfico, que puede llegar después de una cierta cantidad de datos o sin ningún otro dato.

Volviendo al problema planteado en el tema, obtenemos que la función ChartNavigate( ) no comprueba la corrección de los parámetros. Si todavía no hay datos en OnInit() (0 barras), y se pasa el valor -1000 a la función, ¿cómo podemos considerar este valor correcto, si no hay barras? Después de todo, cualquier otra función devolvería un error al acceder a la barra con un índice inexistente. Pero aquí tiene éxito. ¿Qué es exactamente el éxito?

 

Aquí está el indicador - especialmente poner un retraso de nueve garrapatas, dos tipos de movimiento gráfico y la bandera de re-dibujo forzado (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);
  }
//+------------------------------------------------------------------+


Preliminar:CHART_BEGIN esestable.

Archivos adjuntos:
Test.mq5  6 kb
 
Vladimir Karputov:

Aquí está el indicador - especialmente poner un retraso de nueve garrapatas, dos tipos de movimiento gráfico y la bandera de re-dibujo forzado (on/off).


Preliminar:CHART_BEGIN funciona de forma estable.

Pero, ¿y si no hay garrapatas, es fin de semana? Entonces habrá que conectar el temporizador.

Y sólo queda una cuestión por resolver: ¿cómo determinar si ChartNavigate se ha ejecutado con éxito? El hecho de que devuelva true, sólo "tilda", no ayuda en el trabajo real.

Razón de la queja: