ChartNavigate durante a inicialização

 

Encontrei um problema com a função ChartNavigate. Fazendo algo errado ou há realmente um problema com a função. Escreva de volta se você já o usou com freqüência suficiente.

Portanto, aqui está o cerne do problema: ChartNavigate não desloca o gráfico Ao iniciar o terminal se a função for chamada no OnInit(). Eu li a documentação propositalmente várias vezes. Em nenhum lugar se diz que a função não pode ser chamada durante a inicialização.

Código indicador para reprodução:

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

Passos a serem dados:

  1. Desligar o autoplay do gráfico.
  2. Anexar indicador ao gráfico. ChartNavigate acionará movendo a carta para a posição desejada.
  3. Descarregue o terminal.
  4. Carregue o terminal. O ChartNavigate não funcionará exibindo o gráfico sem uma compensação.
OK, se a função der um erro. Mas não. Todas as chamadas são bem sucedidas, mas é quando o terminal é recarregado que o offset da carta não ocorre.

 
Você aplica uma função que funciona com o gráfico. Para um indicador, a garantia de criação de gráficos é a primeira entrada na OnCalculate, para uma EA é a primeira entrada na OnTick(). Mas não antes.
 
Vladimir Karputov:
Você aplica uma função que funciona com o gráfico. Para o indicador a garantia da criação do gráfico é a primeira entrada na OnCalculate, para o Expert Advisor - a primeira entrada na OnTick(). Mas não antes.

Não há problema. Se ainda não houver um gráfico, ter o retorno da função falso e o código de erro correspondente. Mas este não é o caso, a função relata orgulhosamente uma execução bem sucedida. Note que a documentação não diz que isto é uma indicação de sucesso no envio da mensagem para o gráfico. Diz claramente: a execução bem sucedida da função.

Além disso, isto é código para reprodução. Na verdade, mesmo antes da chamada de ChartNavigate, eu tenho uma chamada para as séries de tempo. E todos eles são preenchidos corretamente, como acontece. Ou seja, já existe um gráfico, existem seus dados. Além disso, é possível ler no gráfico os objetos gráficos que lhe foram colocados antes do terminal ser fechado.

Assim, por todas as indicações, o quadro já existe.

 

Isso é estranho. Funciona para mim sem nenhum problema.

E mais uma nota: Você deve desativar seu offset automático CHART_AUTOSCROLLL antes de compensar o gráfico

 
Ihor Herasko:

Não há problema. Se ainda não houver um gráfico, ter o retorno da função falso e o código de erro correspondente. Mas este não é o caso, a função relata orgulhosamente uma execução bem sucedida. Note que a documentação não diz que isto é uma indicação de sucesso no envio da mensagem para o gráfico. Diz claramente: a execução bem sucedida da função.

Além disso, isto é código para reprodução. Na verdade, mesmo antes da chamada de ChartNavigate, eu tenho uma chamada para as séries de tempo. E todos eles são preenchidos corretamente, como acontece. Ou seja, já existe um gráfico, existem seus dados. Além disso, é possível ler no gráfico os objetos gráficos que lhe foram colocados antes do terminal ser fechado.

Assim, por todas as indicações, o quadro já existe.

A tabela e os dados são duas grandes diferenças.

Todas as funções referentes aos gráficos são assíncronas: isto é, unidirecionais - tiro e esquecidas. E, neste caso, verdade significa apenas que você preencheu os campos desta função corretamente, nada mais.

O sinal quando todos os dados estiverem prontos e os gráficos estiverem traçados é a primeira entrada para Oncalculate/OnTick.

 
Vladimir Karputov:

Um gráfico e dados são duas grandes diferenças.

Todas as funções de acesso aos gráficos são assíncronas: ou seja, uma viagem só de ida - tiro e esquecimento. Neste caso, verdadeiro significa apenas que você preencheu corretamente os campos desta função, nada mais.

O sinal quando todos os dados estiverem prontos e os gráficos estiverem traçados é a primeira entrada para Oncalculate/OnTick.

Então como você explica o fato de que funciona sem falhas para mim? No OnInit() exatamente como no primeiro poste do fio. Por que você está inventando besteiras?

 
Alexey Viktorov:

Isso é estranho. Funciona para mim sem nenhum problema.

Que construção você tem? Eu tenho 1861.

E mais uma nota: Você deve desativar seu offset automático CHART_AUTOSCROLLL antes de compensar o gráfico

Sim, eu apontei isso no primeiro passo para a reprodução.

 
Ihor Herasko:

Qual é a sua construção? Eu tenho 1861.

Sim, foi isso que apontei no primeiro passo para a repetição.

Eu também tenho 1861. Só conseguiu reproduzi-la uma vez. Todas as outras tentativas têm funcionado bem.

 
Vladimir Karputov:

Um gráfico e dados são duas grandes diferenças.

Todas as funções de acesso aos gráficos são assíncronas: ou seja, uma viagem só de ida - tiro e esquecimento.

Não, nem todos eles. Os que o fazem são especificamente comentados. Por exemplo, o mesmo ChartApplyTemplate.

Neste caso, verdadeiro significa apenas que você preencheu corretamente os campos desta função, nada mais.

Como a função determinou que o ID do gráfico está correto, se o próprio gráfico ainda não existe?

O sinal quando todos os dados estiverem prontos e os gráficos estiverem traçados é a primeira entrada para Oncalculate/OnTick.

Infelizmente, não. Aqui está o 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 assim:

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

Executo o indicador em um novo símbolo cujo gráfico ainda não foi aberto, ou seja, ainda não foram gerados dados sobre ele.

Na primeira linha (OnInit), de fato, não há dados. Entretanto, existe o ID do gráfico e podemos criar objetos no OnInit() que serão exibidos com sucesso no gráfico.

A segunda linha já tem dados, mas está incompleta. Os dados estão completos na terceira iteração.

É razoável concluir que a primeira chamada para a OnCalculate não é uma garantia de carregamento de dados. É simplesmente a primeira marca no símbolo após a abertura do gráfico, que pode vir ou após alguma quantidade de dados ou sem nenhum outro dado.

Voltando ao problema levantado no tópico, obtemos que a função ChartNavigate() não verifica a correção dos parâmetros. Se ainda não há dados no OnInit() (0 barras), e o valor -1000 é passado para a função, então como podemos considerar este valor correto, se não há barras? Afinal, qualquer outra função retornaria um erro ao acessar a barra com um índice inexistente. Mas é um sucesso aqui. O que é exatamente o sucesso?

 

Aqui está o indicador - especialmente colocar um atraso de nove ticks, dois tipos de movimento de cartas e a bandeira de re-desenho forçado (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 éestável.

Arquivos anexados:
Test.mq5  6 kb
 
Vladimir Karputov:

Aqui está o indicador - especialmente colocar um atraso de nove ticks, dois tipos de movimento de cartas e a bandeira de re-desenho forçado (on/off).


Preliminar:CHART_BEGIN funciona de forma constante.

Mas e se não houver carrapatos, é fim de semana? Então o temporizador terá que ser conectado.

E há apenas uma questão a resolver: como determinar se o ChartNavigate foi executado com sucesso? O fato de que ele retorna verdadeiro, apenas "carrapatos", não ajuda no trabalho real.