Referência MQL5Elementos Básicos da LinguagemFunçõesFunções de Manipulação de Evento 

Funções de Manipulação de Evento

A linguagem MQL5 fornece processamento de alguns eventos pré-definidos. Funções para manipulação destes eventos devem ser definidas em um programa MQL5; nome da função, tipo de retorno, composição dos parâmetros (se existir algum) e seus tipos devem estar rigorosamente em conformidade com a descrição da função de handler (manipulador) de evento.

O handler (manipulador) de evento do terminal cliente identifica funções, manipulando este ou aquela evento, pelo tipo de valor de retorno e tipo de parâmetros. Se outros parâmetros, que não correspondem às descrições abaixo, são especificadas para uma função correspondente, ou outro tipo de retorno é indicado para ela, tal função não será usada como um handler (manipulador) de evento.

OnStart

A função OnStart() é o handler (manipulador) do evento Start ,que é automaticamente gerado somente para execuções de scripts. Ela dever ser do tipo void, sem parâmetros:

void OnStart();

Para a função OnStart(), o tipo de retorno int pode ser especificado.

OnInit

A função OnInit() é o handler (manipulador) do evento Init. Ela deve ser do tipo void ou int, sem parâmetros:

void OnInit();

O evento Init é gerado imediatamente após um Expert Advisor ou um indicador ser baixado; este evento não é gerado para scripts. A função OnInit() é usada para inicialização. Se OnInit() tiver o tipo int de valor de retorno, o código de retorno não-zero significa inicialização sem sucesso e é gerado o evento Deinit com o código do motivo da desinicialização REASON_INITFAILED.

Para otimizar os parâmetros de entrada de um Expert Advisor, é recomendado usar valores da enumeração ENUM_INIT_RETCODE como código de retorno. Esses valores são usados para organizar o curso da otimização, incluindo a seleção dos mais apropriados agentes de teste. Durante a inicialização de um Expert Advisor, antes do início do teste, você pode solicitar informação sobre a configuração e recursos de um agente (o número de cores, quantidade de memória livre, etc) usando a função TerminalInfoInteger(). Baseado nestas informações obtidas, pode-se tanto permitir usar este agente de teste, ou rejeitar usá-lo durante a otimização deste Expert Advisor.

ENUM_INIT_RETCODE

Identificador

Descrição

INIT_SUCCEEDED

Inicialização bem sucedida, teste do Expert Advisor pode continuar.

Este código significa o mesmo que um valor null = o Expert Advisor foi inicializado com sucesso no Provador de Estratégia.

INIT_FAILED

Inicialização com falha; não existe motivo para continuar testando por cause de erros fatais. Por exemplo, falha em criar um indicador que é requerido para o funcionamento do Expert Advisor.

Este valor de retorno significa o mesmo que um valor diferente de zero - inicialização do Expert Advisor pelo Provador de Estratégia falhou.

INIT_PARAMETERS_INCORRECT

Este valor significa a incorreta definição da entrada de parâmetros. A seqüência de resultado contendo o código de retorno é destacado em vermelho na tabela de otimização geral.

O teste para o dado conjunto de parâmetros do Expert Advisor não será executado, o agente é liberado para receber uma nova tarefa.

Depois de receber este valor, o testador de estratégia com segurança não vai passar essa tarefa para que outros agentes tentem novamente.

INIT_AGENT_NOT_SUITABLE

Nenhum erro durante a inicialização, mas por alguma razão o agente não é adequado para o teste. Por exemplo, ausência de memória suficiente, sem support ao OpenCL, etc.

Após este código de retorno, o agente não receberá tarefas até o fim desta otimização.

A função OnInit() do tipo void sempre indica inicialização bem sucedida.

OnDeinit

A função OnDeinit() é chamada durante a desinicialização e é o handler (manipulador) do evento Deinit. Ela deve ser declarada com o tipo void e ter um parâmetro do tipo const int, que contém o código do motivo da desinicialização. Se um tipo diferente é declarado, o compilador gerará um aviso e a função não será chamada. Para scripts o evento Deinit não é gerado e portanto a função OnDeInit() não pode ser usada em scripts.

void OnDeinit(const int reason);

O evento Deinit é gerado para Expert Advisors e indicadores nos seguintes casos:

  • antes de uma reinicialização devido à mudança de ativo (symbol) ou período do gráfico no qual o programa MQL5 está anexado;
  • antes de uma reinicialização devido à mudança de parâmetros de entrada;
  • antes de descarregar o programa MQL5.

OnTick

O evento NewTick é gerado para Expert Advisors somente quanto um novo preço (tick) para um ativo é recebido pelo gráfico no qual o Expert Advisor está anexado. É inútil definir a função OnTick() num indicador personalizado ou script, porque o evento NewTick não é gerado para eles.

O evento Tick é gerado apenas para Expert Advisors, mas isso não significa que Expert Advisors requer a função OnTick(), uma vez que não são apenas os eventos NewTick gerados para Expert Advisors, mas também são gerados os eventos de Timer, BookEvent e ChartEvent. Ela deve ser declarada com o tipo void, sem parâmetros:

void OnTick();

OnTimer

A função OnTimer() é chamada quando o evento Timer ocorre, que é gerado pelo timer do sistema somente para Expert Advisors e indicadores - ela não pode ser usada em scprits. A freqüência de ocorrência do evento é definida na subscrição de notificações deste evento através da função EventSetTimer().

Você pode desfazer a subscrição de receber eventos de timer para um Expert Advisor particular usando a função EventKillTimer(). A função de ser definida com o tipo void, sem parâmetros:

void OnTimer();

É recomendável chamar a função EventSetTimer() uma vez na função OnInit(), e a função EventKillTimer() deve ser chamada uma vez em OnDeinit().

Todo Expert Advisor, assim como todo indicador funciona com seu próprio timer e recebe eventos apenas a partir dele. Tão logo um programa MQL5 para de funcionar, o timer é destruído de forma forçada, se ele foi criado mas não desabilitado pela função EventKillTimer().

OnTrade

A função é chamada quando o evento Trade ocorre, que surge quando você muda a lista de ordens postadas e posições abertas, o histórico de ordens e histórico de operações (deals). Quando uma atividade de negociação (trade) é realizada (abertura de ordem pendente, abertura/fechamento de posição, definição de stop, disparo de ordem pendente, etc.) o histórico de ordens e operações (deals) e/ou a lista de posições e ordens correntes são por conseqüência alterados.

void OnTrade();

Os usuários devem implementar de forma independente no código a verificação do estado de uma conta de negociação quanto tal evento é recebido (se isto é requerido pelas condições da estratégia de negócio). Se a chamada da função OrderSend() foi concluída com sucesso e retornou um valor de true, isso significa que o servidor de negociação postou a ordem na fila de execução e atribuiu um número de bilhetagem (ticket number) nele. Tão logo o servidor processe esta ordem, o evento Trade será gerado. E se um usuário lembrar valor da bilhetagem (ticket), ele/ela será capaz de descobrir o que aconteceu com a ordem usando este valor na função OnTrade().

OnTradeTransaction

Ao realizar algumas ações específicas em uma conta de negociação, seu estado muda. Tais ações includem:

  • Envio de uma solicitação de negociação a partir de algum aplicativo MQL5 no terminal usando as funções OrderSend e OrderSendAsync e sua posterior execução.
  • Envio de uma solicitação de negociação por meio da interface gráfica do terminal e sua posterior execução.
  • Ativação de ordens pendentes e ordens de stop no servidor.
  • Realização de operações no lado de um servidor de negociação.

As seguintes transações de negociação são realizadas como resultado destas ações:

  • tratamento de uma solicitação de negociação
  • mudança de ordens de abertura
  • mudança de histórico de ordens
  • mudança de histórico de operações (deals)
  • mudança de posições

Por exemplo, ao enviar uma ordem de compra de mercado, ela é tratada, uma ordem de compra apropriada é criada para a conta, a ordem é então executada e removida da lista de ordens em aberto, e então ela é adicionada ao histórico de ordens, uma apropriada operação (deal) é adicionada ao histórico e uma nova posição é criada. Todas estas ações são transações de negociação. A chegada de tal transação no terminal é um evento TradeTransaction. Ele chama o handler (manipulador) de evento OnTradeTransaction.

void  OnTradeTransaction(
   const MqlTradeTransaction   trans,        // estrutura das transações de negócios
   const MqlTradeRequest&        request,      // estrutura solicitada
   const MqlTradeResult&         result        // resultado da estrutura
   );

O handler (manipulador) contém três parâmetros:

  • trans - este parâmetro obtém a estrutura MqlTradeTransaction descrevendo uma transação de negociação aplicada a uma conta de negócio.
  • request - este parâmetro obtém a estrutura MqlTradeRequest descrevendo uma solicitação de negócio;
  • result - este parâmetro obtém a estrutura MqlTradeResult descrevendo o resultado da execução de uma solicitação de negociação.

Os últimos dois parâmetros, request e result, são preenchidos por valores somente para uma transação de tipo TRADE_TRANSACTION_REQUEST, dados sobre uma transação podem ser recebidos a partir do parâmetro do tipo da variável trans. Note que neste caso, o campo request_id na variável result contém o ID da solicitação de negócio, após a execução da transação de negociação, descrita na variável trans, ter sido realizada. O identificador da solicitação (Request ID) permite associar a ação realizada (chamada de funções OrderSend ou OrderSendAsync) com o resultado da ação enviado para OnTradeTransaction().

Uma solicitação de negociação manualmente enviada a partir do terminal ou via funções OrderSend()/OrderSendAsync() podem gerar várias transações consecutivas no servidor de negócios. A prioridade de chegada dessas transações no terminal não é garantida. Assim, você não deve esperar que um grupo de transações chegará após um outro grupo ao desenvolver seu algoritmo de negociação.

  • Todos os tipo de transações de negociação são descritas na enumeração ENUM_TRADE_TRANSACTION_TYPE.
  • A estrutura MqlTradeTransaction descrevendo um transação de negociação é preenchida de diferentes formas dependendo do tipo de transação. Por exemplo, somente o campo de tipo (tipo de transação de negociação) deve ser analisado para transações do tipo TRADE_TRANSACTION_REQUEST. O segundo e terceiro parâmetros (request e result) da função OnTradeTransaction deve ser analisado para dados adicionais. Para informações adicionais, veja Estrutura de uma Transação de Negociação.
  • Uma descrição de transação de negociação não entrega todas as informações disponíveis relativas a ordens, operações (deals) e posições (por exemplo, comentários). As funções OrderGet*, HistoryOrderGet*, HistoryDealGet* e PositionGet* devem ser usadas para obter informações adicionais.

Após aplicar transações de negociação em uma conta de cliente, elas são consistentemente postadas na fila de transações de negócio do terminal, a partir da qual são consistentemente enviados para o ponto de entrada OnTradeTransaction na ordem de chegada no terminal.

Ao tratar transações de negociação por um Expert Advisor usando o handler OnTradeTransaction (Manipulador sobre Transação de Comércio), o terminal continua manipulando as transações de negociação recém chegadas. Portanto, o estado de uma conta de negociação pode mudar durante uma operação OnTradeTransaction. Por exemplo, enquanto um programa MQL5 manipula um evento para adicionar uma nova ordem, ela pode ser executada, deletada da lista das abertas e movida para o histórico. Mais adiante, o aplicativo será notificado destes eventos.

O comprimento da fila de transações compreende 1024 elementos. Se OnTradeTransaction tratar uma nova transação por muito tempo, as transações mais antigas na fila podem ser substituídas pelas novas.

  • De forma geral, não existe um proporção precisa entre o número de chamadas de OnTrade e OnTradeTransactions. Uma chamada OnTrade corresponde a uma ou várias chamadas OnTradeTransactions.
  • OnTrade é chamada após apropriadas chamadas OnTradeTransaction.

OnTester

A função OnTester() é o handler (manipulador) do evento Tester que é automaticamente gerado após um teste de histórico de um Expert Advisor no intervalo escolhido ter terminado. A função deve estar definida com o tipo double, sem parâmetros:

double OnTester();

A função é chamada logo antes da chamada de OnDeinit() e tem o mesmo tipo do valor de retorno - double. OnTester() pode ser usado apenas no teste de Expert Advisors. Seu principal propósito é calcular um certo valor que é usado como o critério max customizado na otimização genética de parâmetros de entrada.

Na otimização genética, a ordenação descendente é aplica aos resultados de uma geração. Isto é, do ponto de vista do critério de otimização, os melhores resultados são aqueles com o maiores valores (os valores do critério de otimização max customizado retornados pela função OnTester são levados em consideração). Em tal ordenação, os piores valores são posicionados no final e posteriormente jogados fora e não participam na formação da nova geração.

OnTesterInit

A função OnTesterInit() é o handler( manipulador) do evento TesterInit, que é automaticamente gerado antes de iniciar a otimização do Expert Advisor no Provador de Estratégia. A função deve ser definida com o tipo void. Ele não tem parâmetros:

void OnTesterInit();

Com o início da otimização, um Expert Advisor com o handler (manipulador) OnTesterInit() ou OnTesterPass() é automaticamente carregado em um gráfico separado do terminal com o ativo e período especificados no Provador de Estratégia, e recebe o evento TesterInit. A função é usada para inicializar o Expert Advisor antes de iniciar a otimização para posterior processamento dos resultados da otimização.

OnTesterPass

A função OnTesterPass() é um handler (manipulador) do evento TesterPass, que é automaticamente gerado quanto um plano é recebido durando a otimização de um Expert Advisor no Provador de Estratégia. A função deve ser definida com o tipo void. Ele não tem parâmetros:

void OnTesterPass();

Um Expert Advisor com o handler (manipulador) OnTesterPass() é automaticamente carregado em um gráfico separado do terminal com o ativo/período especificados para teste, e obtém eventos TesterPass quando um plano é recebido durante uma otimização. A função é usada para tratamento dinâmico dos resultados de otimização "no local" sem precisar esperar pela sua conclusão. Planos são adicionados usando a função FrameAdd(), que pode ser chamada após o fim de um passo único no handler (manipulador) OnTester() .

OnTesterDeinit

OnTesterDeinit() é um handler (manipulador) do TesterDeinit, que é automaticamente gerada após o fim da optimização de um Expert Advisor no Provador de Estratégia. A função deve ser definida com o tipo void. Ele não tem parâmetros:

void OnTesterDeinit();

Um Expert Advisor com o handler (manipulador) TesterDeinit() é automaticamente carregada em um gráfico no início da otimização, e recebe TesterDeinit após sua conclusão. A função é usada para um processamento final de todos os resultados da otimização.

OnBookEvent

A função OnBookEvent() é o handler (manipulador) do BookEvent. BookEvent é gerado para Expert Advisors e indicadores somente quando a Profundidade do Mercado muda. Ela deve do tipo void e ter um parâmetro do tipo string:

void OnBookEvent (const stringsymbol);

Para receber eventos BookEvent para qualquer ativo (symbol), você apenas precisa fazer uma pré-subscrição pra receber eventos para este ativo usando a função MarketBookAdd(). A fim de desfazer a subscrição de recebimento de eventos BookEvent para um particular ativo, chame MarketBookRelease().

Diferente de outros eventos, o evento BookEvent é por difusão (broadcast). Isso significa que se um Expert Advisor subscreve para receber eventos BookEvent usando MarketBookAdd, todos os outros Experts Advisors que tem o handler (manipulador) OnBookEvent() receberão este evento. É portanto necessário analisar o nome do ativo, que é passado para o handler (manipulador) através dos parâmetros const string& symbol.

OnChartEvent

OnChartEvent() é o handler (manipulador) de um grupo de eventos ChartEvent:

  • CHARTEVENT_KEYDOWN – evento de uma teclada, quando a janela do gráfico está com foco;
  • CHARTEVENT_MOUSE_MOVE – eventos de movimento de mouse e eventos de click de mouse (se CHART_EVENT_MOUSE_MOVE=true é definido para o gráfico);
  • CHARTEVENT_OBJECT_CREATE – evento de criação de objeto gráfico (se CHART_EVENT_OBJECT_CREATE=true é definido para o gráfico);
  • CHARTEVENT_OBJECT_CHANGE – evento de mudança de um propriedade de objeto via janela diálogo de propriedades;
  • CHARTEVENT_OBJECT_DELETE – evento de exclusão de objeto gráfico (se CHART_EVENT_OBJECT_DELETE=true é definido para o gráfico);
  • CHARTEVENT_CLICK – evento de um click de mouse no gráfico;
  • CHARTEVENT_OBJECT_CLICK – evento de um click de mouse em um objeto gráfico pertencente ao gráfico;
  • CHARTEVENT_OBJECT_DRAG – evento de um movimento de objeto gráfico usando o mouse;
  • CHARTEVENT_OBJECT_ENDEDIT – evento da edição de texto finalizada na caixa de entrada do objeto gráfico LabelEdit;
  • CHARTEVENT_CHART_CHANGE – evento de mudanças de gráfico;
  • CHARTEVENT_CUSTOM+n – ID do evento do usuário, onde n está na faixa de 0 a 65535.
  • CHARTEVENT_CUSTOM_LAST – o último ID aceitável de um evento customizado (CHARTEVENT_CUSTOM+65535).

A função pode ser chamada somente em Expert Advisors e indicadores. A função deve ser de tipo void com 4 parâmetros:

void OnChartEvent(const int id,         // Evento ID
                  const long& lparam,   // Parâmetro de evento de tipo long
                  const double& dparam, // Parâmetro de evento de tipo double
                  const string& sparam  // Parâmetro de evento de tipo string
  );

Para cada tipo de evento, os parâmetros de entrada da função OnChartEvent() têm valores definidos que são requeridos para o processamento deste evento. Os eventos e valores passados através destes parâmetros são listados na tabela abaixo.

Evento

Valor do parâmetro id

Valor do parâmetro lparam

Valor do parâmetro dparam

Valor do parâmetro sparam

Evento de uma teclada

CHARTEVENT_KEYDOWN

código de uma tecla pressionada

Repita a contagem (o número de vezes que a tecla é repetida como um resultado de que o usuário pressiona a tecla)

O valor da string de uma pequena máscara de descrever o estado de botões do teclado

Eventos de mouse (se a propriedade CHART_EVENT_MOUSE_MOVE=true está definida para o gráfico)

CHARTEVENT_MOUSE_MOVE

a coordenada X

a coordenada Y

O valor de string de uma máscara de bites descrevendo o estado de botões de mouse

Evento de criação de objeto gráfico (se CHART_EVENT_OBJECT_CREATE=true, então é definido para o gráfico)

CHARTEVENT_OBJECT_CREATE

Nome do objeto gráfico criado

Evento de mudança de uma propriedade de objeto via janela de diálogo de propriedades

CHARTEVENT_OBJECT_CHANGE

Nome do objeto gráfico modificado

Evento de exclusão de objeto gráfico (se CHART_EVENT_OBJECT_DELETE=true está definido para o gráfico)

CHARTEVENT_OBJECT_DELETE

Nome do objeto gráfico excluído

Evento de um click de mouse no gráfico

CHARTEVENT_CLICK

a coordenada X

a coordenada Y

Evento de um click de mouse num objeto gráfico pertencente ao gráfico

CHARTEVENT_OBJECT_CLICK

a coordenada X

a coordenada Y

Nome do objeto gráfico, na qual o evento ocorreu

Evento de um objeto gráfico arrastado usando o mouse

CHARTEVENT_OBJECT_DRAG

Nome do objeto gráfico movido

Evento da edição de texto finalizada na caixa de entrada do objeto gráfico LabelEdit

CHARTEVENT_OBJECT_ENDEDIT

Nome do objeto gráfico LabelEdit, cuja edição de texto foi concluída

Evento de mudanças de gráfico

CHARTEVENT_CHART_CHANGE

ID do evento de usuário sob N número

CHARTEVENT_CUSTOM+N

Valor definido pela função EventChartCustom()

Valor definido pela função EventChartCustom()

Valor definido pela função EventChartCustom()

OnCalculate

A função OnCalculate() é chamada somente em indicadores customizados quando é necessário calcular os valores do indicador pelo evento Calculate. Isso geralmente acontece quando um novo preço (tick) é recebido para o ativo, de cujo indicador é calculado. Não é necessário que este indicador esteja anexado a qualquer gráfico de preço deste ativo.

A função OnCalculate() deve retornar um tipo int. Existem duas possíveis definições. Dentro de um indicador você não pode usar ambas as versões da função.

A primeira forma é destinado para aqueles indicadores que podem ser calculados com um único buffer de dados. Um exemplo de tal indicador é a Média Móvel Customizada (Custom Moving Average).

int OnCalculate (const int rates_total,      // tamanho do array price[]
                 const int prev_calculated,  // barras tratadas na chamada anterior
                 const int begin,            // a partir de onde começam os dados significativos
                 const double& price[]       // array a ser calculado
   );

Assim como o array price[], uma das série de preço ou um buffer calculado de algum indicador pode ser passado. Para determinar a direção da indexação no array price[], chame ArrayGetAsSeries(). A fim de não depender de valores default, você deve incondicionalmente chamar a função ArraySetAsSeries() para aqueles arrays que você espera utilizar.

Uma série de tempo necessária ou um indicador, para ser usado como o array price[], deve ser selecionado pelo usuário na guia "Parâmetros" ao iniciar o indicador. Para fazer isso, você deve especificar o necessário item no lista drop-down do campo "Aplicar a".

Selecionando uma série de tempo para calcular um indicador

Para receber valores de um indicador customizado a partir outros programas mql5, a função iCustom() é usada, que retorna o manuseio do indicador para operações subseqüentes. Você pode também especificar o price[] array apropriado ou o manuseio de outro indicador. Este parâmetro deve ser transmitido por último na lista de variáveis de entrada do indicador customizado.
Exemplo:

void OnStart()
  {
//---
   string terminal_path=TerminalInfoString(STATUS_TERMINAL_PATH);
   int handle_customMA=iCustom(Symbol(),PERIOD_CURRENT"Custom Moving Average",13,0, MODE_EMA,PRICE_TYPICAL);
   if(handle_customMA>0)
      Print("handle_customMA = ",handle_customMA);
   else
      Print("Pode abrir ou não o arquivo EX5 '"+terminal_path+"\\MQL5\\Indicators\\"+"Custom Moving Average.ex5'");
  }

Neste exemplo, o último parâmetro passado é o valor PRICE_TYPICAL (da enumeração ENUM_APPLIED_PRICE), que indica que o indicador customizado será construído baseado em preços típicos obtidos como (High+Low+Close)/3. Se este parâmetro não for especificado, o indicador é construído baseado em valores de PRICE_CLOSE, isto é, preços de fechamento de cada barra.

Outro exemplo que mostra a passagem de um handler (manipulador) de indicador como o último parâmetro para especificar o array price[], é dado na descrição da função iCustom().
 

A segunda forma é destinada para todos os outros indicadores, na qual mais de uma série de tempo é usada nos cálculos.

int OnCalculate (const int rates_total,      // tamanho da série de preços de entrada series
                 const int prev_calculated,  // barras tratadas na chamada anterior
                 const datetime& time[],     // Hora
                 const double& open[],       // Open (abertura)
                 const double& high[],       // High (máximo)
                 const double& low[],        // Low (mínimo)
                 const double& close[],      // Close (fechamento)
                 const long& tick_volume[],  // Volume de Tick
                 const long& volume[],       // Volume Real
                 const int& spread[]         // Spread
   );

Os parâmetros open[], high[], low[] and close[] contém os arrays com preços de abertura, preços de máximo e mínimo e preços de fechamento da janela de tempo corrente. O parâmetro time[] contém um array com valores de hora de abertura, o parâmetro spread[] tem um array contendo o histórico de spreads (se algum spread é fornecido para o ativo negociado). Os parâmetros volume[] e tick_volume[] contêm o histórico de volume de negociação e tick, respectivamente.

Par determinar a direção de indexação de time[], open[], high[], low[], close[], tick_volume[], volume[] e spread[], chame ArrayGetAsSeries(). A fim de não depender de valores default, você deve incondicionalmente chamar a função ArraySetAsSeries() para aqueles arrays que você esperar utilizar.

O primeiro parâmetro rates_total contém o número de barras disponíveis no indicador para cálculo, e corresponde ao número de barras disponíveis no gráfico.

Devemos notat a conexão entre o valor de retorno de OnCalculate() e o segundo parâmetro de entrada prev_calculated. Durante a chamada da função, o parâmetro prev_calculated contém um valor retornado pelo OnCalculate() durante a chamada anterior. Isso permite que algoritmos eficientes calculem o indicador customizado de forma a evitar cálculos repetidos naquelas barras que não tiveram mudança deste a execução anterior desta função.

Para isso, é geralmente suficiente retornar o valor do parâmetro rates_total, que contém o número de barras da chamada corrente da função. Se desde a última chamada da função OnCalculate() os dados de preço mudarem (um histórico mais antigo baixado ou brancos no histórico preenchidos), o valor do parâmetro de entrada prev_calculated será definido para zero pelo terminal.

Observação: se OnCalculate retornar zero, então os valores do indicador não são mostrados na Janela de Dados do terminal cliente.

Para entender isso melhor, seria útil iniciar o indicador, cujo código está anexado abaixo.

Exemplo indicador:

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
//---- plotar Linha
#property indicator_label1  "Line"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrDarkBlue
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- buffers do indicador
double         LineBuffer[];
//+------------------------------------------------------------------+
//| Função de inicialização do indicador customizado                 |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- mapeamento de buffers do indicador
   SetIndexBuffer(0,LineBuffer,INDICATOR_DATA);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Função de iteração do indicador customizado                      |
//+------------------------------------------------------------------+
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[])
  {
//--- Obtenção do número de barras disponíveis para o ativo corrente e período do gráfico
   int bars=Bars(Symbol(),0);
   Print("Bars = ",bars,", rates_total = ",rates_total,",  prev_calculated = ",prev_calculated);
   Print("time[0] = ",time[0]," time[rates_total-1] = ",time[rates_total-1]);
//--- valor retorno de prev_calculated para a próxima chamada
   return(rates_total);
  }
//+------------------------------------------------------------------+

Também Veja

Programas em Execução, Eventos do Terminal Cliente, Trabalhando com Eventos