English Русский 中文 Español Deutsch 日本語
Sincronização de Expert Advisors, scripts e indicadores

Sincronização de Expert Advisors, scripts e indicadores

MetaTrader 4Exemplos | 18 fevereiro 2016, 11:15
3 123 0
Сергей Ковалев
Сергей Ковалев

Introdução

Há três tipos de programa escritos no MQL4 e executados no terminal do cliente MetaTrader 4.
- Expert Advisors;
- scripts;
- indicadores.

Cada um deles tem como finalidade a resolução de um certo tipo de problema. Vamos descrever brevemente os programas.

1. Breve descrição dos programas de usuário do MQL4

1.1. Expert Advisors
Expert Advisors (EAs) são o tipo principal de programa usado para executar estratégias lucrativas de transações. Os aspectos distintivos de um EA estão listados abaixo:
1. Possibilidade de usar funções integradas que suportam transações.
2. Possibilidade de modificar configurações externas manualmente.
3. Disponibilidade de regras que regulam a execução da função especial start(). Ela é executada de acordo com os ticks. No momento da chegada de um novo tick, os parâmetros de todo o ambiente disponível para essa função são atualizados. Por exemplo, variáveis como oferta e preço de venda ganham novos valores. Tendo completado a execução do código, isto é, tendo chegado ao retorno do operador, a função start() finaliza a sua operação e entra em estado de repouso até a chegada do próximo tick.

1.2. Scripts
Scripts são bastante semelhantes aos Expert Advisors, mas os seus aspectos são um pouco diferentes. Os aspectos principais dos scripts estão listados abaixo:
1. Scripts também podem ser usados como funções de transações.
2. Parâmetros de configurações externas não podem ser alterados em scripts.
3. O aspecto principal dos scripts é a regra segundo a qual a função especial start() de um script será executada apenas uma vez, imediatamente após ter sido anexada ao gráfico e inicializada.

Os Expert Advisors e os scripts são anexados à janela principal de um símbolo e não podem ter sub-janelas especiais.

1.3. Indicadores
Os indicadores possuem uma finalidade diferente dos Expert Advisors e dos scripts:
1. O aspecto principal dos indicadores é a possibilidade de se desenhar curvas contínuas que exibem um determinado princípio de acordo com a ideia implícita nele.
2. As funções de transações não podem ser usadas em indicadores.
3. Indicadores são executados de acordo com os ticks.
4. Em relação aos parâmetros implícitos, o indicador pode cumprir a sua função na janela do símbolo principal ou em sua própria sub-janela.

Nós listamos acima apenas as características principais dos programas personalizados, isto é, aquelas necessárias às nossas especulações futuras.

Como podemos apreender da descrição acima, nenhum programa personalizado possui as propriedades de todos os programas: Expert Advisors e scripts não são capazes de desenhar, indicadores não são capazes de realizar transações, etc.

Caso o seu sistema de transações precisar usar todas as propriedades de programas personalizados durante a realização de transações, a única solução será usar simultaneamente um Expert Advisor, um script e um indicador.

2. Descrição de problemas

Vamos considerar os critérios que criariam a necessidade do uso simultâneo de todos os programas personalizados.

2.1. Pontualidade
Qualquer controle por parte do usuário deve ser executado imediatamente. Um programa baseado em um Expert Advisor nem sempre é adequado para essa finalidade. A principal desvantagem de um Expert Advisor é a sua não susceptibilidade a ações externas. A razão para essa limitação é bastante simples: O código básico do Expert Advisor é executado de acordo com os ticks. O que acontecerá caso o usuário enviar um comando ao EA para que este feche um pedido, e o EA estiver esperando pelo próximo tick? A resposta para essa questão depende da forma com que o Expert Advisor foi escrito. Em alguns casos, o comando será executado, mas com algum atraso.

O programa pode ser organizado de tal modo que o código principal do Expert Advisor seja executado continuamente, sem paradas entre os ticks. Para este fim, é necessário organizar dentro da função especial

start()

um ciclo infinito, no qual todo o código principal do programa será inserido. Caso a informação ambiental seja atualizada forçosamente no inicio de cada ciclo, todo o complexo pode funcionar com sucesso. A desvantagem de um Expert Advisor com ciclo é a impossibilidade de se abrir o painel de configuração. Caso você tente realizar um ciclo em um EA, você não será capaz de configurá-lo.

O mesmo conceito pode ser implementado com sucesso com o uso de um script. Isso significa que um ciclo infinito pode ser organizado em um script. Mas não há parâmetros a serem configurados em scripts.

A possibilidade de personalização do sistema de transações e a pontualidade da execução de todos os comandos do usuário no modo de operação contínua podem ser obtidas apenas através do uso simultâneo de um Expert Advisor para a configuração e de um script para a execução instantânea.

2.2. Consciência
Em alguns casos, é preciso obter algumas informações sobre as transações. Por exemplo, todo trader gostaria de saber que, em um determinado momento (digamos, dois minutos antes da publicação de notícias importantes), o centro de negócios alterou a sua distância mínima tolerável para a realização de pedidos pendentes dos 10 pontos usuais para 20 pontos. Além disso, como regra, o trader quer saber a razão do servidor de transações se recusar a executar pedidos. Essas e outras informações úteis podem ser exibidas como um texto na janela do indicador. Da mesma forma, as linhas contendo mensagens mais antigas podem continuamente ser movidas para cima, de modo a liberar espaço para novas mensagens vindas do sistema de transações. Nesse caso, é necessário combinar o Expert Advisor realizando as transações, ou um script, com um indicador de exibição.

2.3. Controles
Caso você use um sistema de transações que inclua uma interface avançada, é melhor colocar os controles (objetos gráficos) na janela do indicador. Desse modo, podemos nos assegurar de que a tendência da vela não irá se sobrepor aos itens de controle e, consequentemente, de que ela não irá atrapalhar o controle.

2.4. Requisitos do sistema
O requisito principal em relação ao produto final, neste caso, é a operação síncrona. Portanto, para o desenvolvimento de um sistema baseado nos três tipos de programas, é necessário dissociar as tarefas a serem resolvidas por todos os seus componentes. Em relação aos recursos especiais de cada tipo de programa no nosso sistema, nós podemos definir as seguintes propriedades:

script - fornece o código básico contendo funções analíticas e transacionais;

Expert Advisor - fornece o painel de configuração;

indicador - fornece o campo da sub-janela que exibe controles e informações.

3. Soluções de software

Devemos indicar diretamente que nós consideramos aqui a estrutura de uma aplicação baseada em três componentes dentro da amplitude mínima exigida. Caso você decida usar a aplicação na prática, você mesmo deverá elaborá-la, pois ela está relacionada a operações analíticas e transacionais. Mas o material fornecido abaixo é suficiente para o desenvolvimento de uma estrutura.

3.1. Expert Advisor
Vamos considerar em detalhes a constituição e o funcionamento de um Expert Advisor.

// Expert.mq4
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж include жжжжжжж
#include <stdlib.mqh>
#include <stderror.mqh> 
#include <WinUser32.mqh> 
//======================================================================
#include <Peremen_exp.mq4>  // Description of the EA variables.
#include <Metsenat_exp.mq4> // Predefinition of the EA variables. 
#include <Del_GV_exp.mq4>   
// Deletion of all GlobalVariables created by the Expert Advisor.
#include <Component_exp.mq4> // Checking for availability of components.
#include <Component_uni.mq4> 
// Message in the indicator that components are not available.
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
//
// 
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
int init()  
  {
    Fishka=1;          // We are in init()  
    Metsenat_exp();   // Predefinition of the EA variables.
    Component_exp();  // Check for availability of components
    return;
 } 
//=====================================================================
int start() 
  { 
    Fishka=2;         // We are in start()  
    Component_exp();  // Check for availability of components
    return;                                                                 
 }
//=====================================================================
int deinit() 
  {   
    Fishka=3;         // We are in deinit()  
    Component_exp();  // check for availability of components
    Del_GV_exp();     // Deletion of the Expert Advisor's GlobalVariable.
    return;
 }
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
/*

Duas funções estão em funcionamento na função especial init() - Metsenat_exp() e Component_exp()

Metsenat_exp() - uma função de pré-definição de algumas variáveis.
// Metsenat_exp.mq4
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
int Metsenat_exp()
 {
//============================================ Predefinitions =====
   Symb     = "_"+Symbol();
   GV       = "MyGrafic_GV_";
//============================================= GlobalVariable ====
   GV_Ind_Yes = GV+"Ind_Yes"   +Symb;      
// 0/1 confirms that the indicator is loaded
   GV_Scr_Yes = GV+"Scr_Yes"   +Symb;      
// 0/1 confirms that the script is loaded
//-------------------------------------------- Public Exposure ----
   GV_Exp_Yes = GV+"Exp_Yes"   +Symb;     
   GlobalVariableSet(GV_Exp_Yes, 1 ); 
   GV_Extern  = GV+"Extern"    +Symb;     
   GlobalVariableSet(GV_Extern,  1 ); 
//  AAA is used as an example:
   GV_AAA     = GV+"AAA"       +Symb;     
GlobalVariableSet(GV_AAA,   AAA ); 
//==================================================================
   return;
 }
//жжжжжжжжжжжжжжжжжжжжжж End of Module жжжжжжжжжжжжжжжжжжжжжжжжжжжжж

Uma das tarefas de toda a manutenção da aplicação é o monitoramento da disponibilidade de todos os componentes. É por isso que todos os componentes (o script, o Expert Advisor e o indicador) devem monitorar uns aos outros e, caso um componente não estiver disponível, para de trabalhar e informar o usuário. Para este fim, cada um dos programas informa a sua disponibilidade durante a inicialização, publicando uma variável global. No caso apresentado, na função Metsenat_exp() do Expert Advisor, isso será feito na linha abaixo:

   GV_Exp_Yes = GV+"Exp_Yes"   +Symb;     
   GlobalVariableSet(GV_Exp_Yes, 1 );

A função Metsenat_exp() é controlada pela função init() do EA, ou seja, ela é usada apenas uma vez durante o carregamento ou a alteração de valores de variáveis externas. O script deve 'ficar sabendo' das alterações nas configurações, e é por isso que o Expert informa o script a este respeito alterando o valor da variável global GV_Extern:

   GV_Extern  = GV+"Extern"    +Symb;     
   GlobalVariableSet(GV_Extern,  1 );

Component_exp()
- um função destinada ao controle da completude. O cenário a seguir depende da função especial do Expert Advisor na qual a Component_exp() é usada.
// Component_exp.mq4 
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
int Component_exp()
 {
//===============================================================================================
   while( Fishka < 3 &&     // We are in init() or in start() and..
      (GlobalVariableGet(GV_Ind_Yes)!=1 || 
       GlobalVariableGet(GV_Scr_Yes)!=1)) 
    {                            // ..while a program is not available.
      Complect=0;                // Since one is inavailable, it is a deficiency
      GlobalVariableSet(GV_Exp_Yes, 1); 
// Inform that the EA is available
//-----------------------------------------------------------------------------------------------
      if(GlobalVariableGet(GV_Ind_Yes)==1 && 
         GlobalVariableGet(GV_Scr_Yes)!=1)
        {//If there is an indicator but there is no scrip available, then..
         Graf_Text = "Script is not installed.";  
// Message text
         Component_uni();                             
// Write the message text in the indicator window.
        }
//-----------------------------------------------------------------------------------------------
      Sleep(300);
    }
//===============================================================================================
     if(Complect==0)
    {
      ObjectDelete("Necomplect_1"); 
// Deletion of unnecessary messages informing about inavailability of components  
      ObjectDelete("Necomplect_2");       
      ObjectsRedraw();              // For quick deletion 
      Complect=1;        // If we have left the loop, it means that all components are available
    }
//===============================================================================================
   if(Fishka == 3 && GlobalVariableGet(GV_Ind_Yes)==1)
// We are in deinit(), and there is space to write the indicator into
    { 
//-----------------------------------------------------------------------------------------------
      if(GlobalVariableGet(GV_Scr_Yes)!=1)  // If there is no script available,
       {
         Graf_Text = "Components Expert and Script are not installed";
// Message (since we are unloading)
         Component_uni();     // Write the message text in the indicator window
       }
//-----------------------------------------------------------------------------------------------
    }
//===============================================================================================
   return;
 }
//жжжжжжжжжжжжжжжжжжжжж End of the module жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж

A disponibilidade do script e do indicador é monitorada com base na leitura dos valores das variáveis globais correspondentes - GV_Scr_Yes e GV_Ind_Yes. Caso nenhum dos correspondentes esteja disponível, o controle será passado ao ciclo infinito até que a completude seja alcançada, ou seja, até que tanto o indicador quanto o script sejam instalados. A aplicação informará o usuário a respeito do estado atual através da função

Component_uni(). Esta é uma função universal incluída em todos os componentes.

// Component_uni.mq4
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
int Component_uni()
 {
//================================================================
//----------------------------------------------------------------
   Win_ind = WindowFind("Indicator");                 
// What is our indicator's window number?
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   ObjectCreate ( "Necomplect_1", OBJ_LABEL, Win_ind, 0, 0  );
// Create an object in the indicator window
   ObjectSet    ( "Necomplect_1", OBJPROP_CORNER,        3  );
// coordinates related to the bottom-right corner
   ObjectSet    ( "Necomplect_1", OBJPROP_XDISTANCE,   450  );
// coordinates on X..
   ObjectSet    ( "Necomplect_1", OBJPROP_YDISTANCE,    16  );
// coordinates on Y..
   ObjectSetText("Necomplect_1", Graf_Text,10,"Courier New",Tomato);
// text, font, and color
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
   Graf_Text = "Application does not work.";
 // Message text
   ObjectCreate ( "Necomplect_2", OBJ_LABEL, Win_ind, 0, 0);
// Create an object in the indicator window
   ObjectSet    ( "Necomplect_2", OBJPROP_CORNER,        3);
// coordinates related to the bottom-right corner
   ObjectSet    ( "Necomplect_2", OBJPROP_XDISTANCE,   450);
// coordinates on Х..
   ObjectSet    ( "Necomplect_2", OBJPROP_YDISTANCE,     2);
// coordinates on Y..
   ObjectSetText("Necomplect_2", Graf_Text,10,"Courier New",Tomato);
// text, font, color
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
   ObjectsRedraw();                                // Redrawing.
   return;
//================================================================
 }
//жжжжжжжжжжжжжжжжжжжжж End of module жжжжжжжжжжжжжжжжжжжжжжжжжжжж

Assim que a aplicação estiver completa, o controle no EA será passado do ciclo ao código sequente, onde a mensagem desnecessária a respeito da incompletude será deletada.

Quando o EA estiver sendo descarregado, a função especial deinit() também se comunicará com o Component_exp(), mas por outro motivo: para comunicar o descarregamento no momento atual.

Na deinit() do Expert Advisor, a função

Del_GV_exp() também será comunicada.

Ela será usada para deletar todas as variáveis globais abertas pelo EA. De acordo com uma regra tácita, todos os programas sendo descarregados devem "limpar a sala", ou seja, deletar as variáveis globais e os objetos gráficos criados anteriormente.

// Del_GV_exp.mq4
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
int Del_GV_exp()
 {
//=================================================================
   GlobalVariableDel(GV_Exp_Yes      ); 
   GlobalVariableDel(GV_Extern       ); 
   GlobalVariableDel(GV_AAA          ); 
//=================================================================
   return;
 }
//жжжжжжжжжжжжжжжжжжжжжж End of module жжжжжжжжжжжжжжжжжжжжжжжжжжжж


Portanto, o Expert Advisor começa a trabalhar e monitora a disponibilidade dos dois outros componentes em todos os estágios: uma vez no init(), uma vez no deinit() e em todo tick, e no start(). Essa construção do EA torna possível usar o programa para completar a nossa tarefa: tornar o painel de configuração disponível. O arquivo que descreve as variáveis contém, como exemplo, a variável AAA e a sua variável global correspondente, GV_AAA, cujo valor é lido a partir do script.

Para examinar os detalhes do funcionamento de tudo isso, vamos considerar a estrutura de um script.

3.2. Script
Código do script:

// Script.mq4
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж include жжжж
#include <stdlib.mqh> 
#include <stderror.mqh>
#include <WinUser32.mqh>
//=================================================================
#include <Peremen_scr.mq4>       
// File describing variables of the script. 
#include <Metsenat_scr.mq4>      
// Predefining of variables of the script.   
#include <Mess_graf_scr.mq4>     
// List of graphical messages.
#include <Novator_scr.mq4>       
// Environment scanning, obtaining new values for some variables
#include <Del_GV_scr.mq4>        
// Deletion of all GlobalVariables created by the script.
#include <Component_scr.mq4>     
// Checking for components availability.
#include <Component_uni.mq4>     
// Message in the indicator about inavailability of components.
#include <Del_Obj_scr.mq4>       
// Deletion of all objects created by the program complex.
#include <Work_scr.mq4>          
// The main working function of the script. 
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
//
// 
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
int init()  
 {
   Fishka = 1;                                // We are in init()  
   Metsenat_scr();       // Predefining of variables of the script.
   return;
 }
//================================================================
int start()  
 {
   Fishka = 2;                               // We are in start()  
   while(true)
    {
      Component_scr();  // Checking for availability of components
      Work_scr();       // The main working function of the script.
    }
   return;
 }
//=================================================================
int deinit() 
 {
   Fishka = 3;                                // We are in deinit()  
   Component_scr();      // Checking for availability of components
   Del_Obj_scr();          // Deletion of graphical objects created
   Del_GV_scr();        // Deletion of GlobalVariable of the script.
   return;
 }
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж

A base do código é a disponibilidade de um ciclo infinito na função especial start(). No código do script, funções com nomes e conteúdos semelhantes são aplicadas. Vamos agora voltar a nossa atenção aos seus recursos especiais. No início de cada ciclo, a função

Component_scr() é chamada.

// Component_scr.mq4   
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
int Component_scr()
 {
//====================================================================
   Iter=0;                               // Zeroize iteration counter
   while (Fishka <3 &&              // We are in init() or in start() 
      (GlobalVariableGet(GV_Ind_Yes)!=1 || 
       GlobalVariableGet(GV_Exp_Yes)!=1)) 
    {                                 // Until a program is available
      GlobalVariableSet(GV_Scr_Yes, 1);               
// Declare about the script availability
//--------------------------------------------------------------------
      Iter++;                                    // Iteration counter
      if(Iter==1)                         // Skip the first iteration
       {
         Sleep(500);
         continue;
       }
//--------------------------------------------------------------------
      if(Iter==2)             // Take measures on the second iteration
       {
         Complect=0; // Program is not available, it is incompleteness
         for (i=0;i<=31;i++)ObjectDelete(Name_Graf_Text[i]);
// Deletion of all strings
// Here, a function can be inserted that will zeroize trade queue.
       }
//--------------------------------------------------------------------
      if(GlobalVariableGet(GV_Ind_Yes)==1 && 
          GlobalVariableGet(GV_Exp_Yes)!=1)
       {                       // If there is an indicator, but no EA
         Graf_Text = "Expert has not been installed."; 
// Message text 
         Component_uni();                             
// Write the text message in the indicator window.
       }
//-----------------------------------------------------------------
      Sleep(300);
    }
//-----------------------------------------------------------------
   if(Complect==0)                // Process it once at completing.
    {
      ObjectDelete("Necomplect_1"); 
// Deletion of unnecessary messages..
      ObjectDelete("Necomplect_2"); 
// ..about incompleteness of components        
      Mess_graf_scr(1);
// Inform the user about completeness
      if( IsExpertEnabled()) 
// The button is enabled
       {
         Mess_graf_scr(3000);
         Knopka_Old = 1;
       }
      if(!IsExpertEnabled()) 
// The button is disabled
       {
         Mess_graf_scr(4000);
         Knopka_Old = 0;
       }
      Complect=1; 
// The minimal installation completeness reached
      Redraw = 1; 
// For quick deletion 
    }
//====================================================================
   if(Fishka == 3 && GlobalVariableGet(GV_Ind_Yes)==1)      
// We are in deinit()  
    {
      for(i=0;i<=31;i++)ObjectDelete(Name_Graf_Text[i]);    
// Deletion of all strings
//--------------------------------------------------------------------
      if(GlobalVariableGet(GV_Exp_Yes)!=1)                 
// There is indicator, but no Expert Advisor
         Graf_Text="Components Expert and Script are not installed.";
// Message (as we're unloading)
      if(GlobalVariableGet(GV_Exp_Yes)==1)
// If there are both indicator and EA, then..
         Graf_Text="The Script has not been installed."; 
// Message (as we're unloading)
      Component_uni();   // Write the message in the indicator window.
//--------------------------------------------------------------------
      ObjectsRedraw();                    // For quick deletion 
    }
//====================================================================
   return;
 }
//жжжжжжжжжжжжжжжжжжжжжж End of module жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж

A primeira exigência em relação a um script é a

continuidade

da sua operação. Durante a atualização de variáveis externas, o Expert Advisor passa pela instalação completa. Ao se pressionar OK no painel de configuração do EA, ele será descarregado e passará o controle ao deinit(). Em seguida ele irá imediatamente carregar novamente, passando pelo init() e start() em sequência. Como resultado disso, o Expert Advisor deleta do deinit(), ainda que por pouco tempo, a variável global que confirma a sua disponibilidade.

Em ordem, o script assume que o EA não foi carregado, e a função Component_scr() contém um pequeno bloco que desabilita a capacidade de se tomar uma decisão na primeira iteração:

      Iter++;                         // Iteration counter
      if(Iter==1)              // Skip the first iteration
        {
          Sleep(500);
          continue;
        }


Cinco milissegundos é tempo suficiente, na maioria dos casos, para o carregamento completo do Expert Advisor. Caso você use um código mais exigente no init() do Expert Advisor, esse tempo será mais longo. Caso o EA não tiver sido detectado na segunda iteração, ficará decidido que o EA não está disponível em absoluto, e o script interrompe a sua operação.

      Complect = 0;    // A program is not available, incompleteness


A expressão "o script interrompe a sua operação" é usada no parágrafo anterior. No nosso exemplo não há código responsável por esse fenômeno simplesmente porque ele está além do escopo do assunto tratado neste artigo. No lugar onde você pode colocar uma chamada pelas funções correspondentes, há um comentário no código.

// Here, a function zeroizing trade counter can be inserted.

Na função Work_scr() de um programa em funcionamento real, exceto em relação Às funções usadas no nosso exemplo, outras funções são consideradas responsáveis por uma determinada ordem de eventos. Por exemplo, caso o seu programa esteja ajustado para modificar vários pedidos, ele certamente conterá uma matriz, na qual a fila de execução de transações será armazenada caso haja várias dessas transações ocorrendo no tick atual.

Caso ocorra a incompletude (por exemplo, caso o Expert Advisor ou o script tiverem sido carregados acidentalmente) no momento em que uma fila desse tipo existir, é necessário desabilitar as transações, o que pode ser feito através do uso da função "zeroize" na matriz supracitada da fila de transações e, talvez, em algumas outras variáveis, de acordo com a situação.

O ciclo infinito do script também contém a função Work_scr(). Essa é a função principal do script, na qual todo o seu código principal deve ser colocado.

// Work_scr.mq4
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
int Work_scr()  
 {
   Novator_scr();
//-----------------------------------------------------------------
   // Basic code of the entire application.
//------------------------------------------------ For example ----
   if(New_Tick==1)                             // At every new tick
    {                                                                    
      Alert ("The current value of ААА = ", AAA);
    }                                                                    
//-----------------------------------------------------------------
   if(Redraw==1)
    {
      ObjectsRedraw();                    // To display immediately
      Redraw=0;                         // Unflag objects redrawing
    }
//-----------------------------------------------------------------
   Mess_graf_scr(0);
   Sleep(1);                           // Just in case, from reload
   return;
 }
//жжжжжжжжжжжжжжжжжжжжжж End of module жжжжжжжжжжжжжжжжжжжжжжжжжжжж


O Work_scr() contém a função Novator_scr() destinada a realizar a atualização das variáveis ambientais usadas no código básico.

// Novator_scr.mq4  
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
int Novator_scr()  
 {
//===================================================================
//---------------------------------------- Updating of settings -----
   if(GlobalVariableGet(GV_Extern)==1) 
// Произошло обновление в эксперте
    {
      Metsenat_scr();         // Updating of the script variables.
      Mess_graf_scr(5000);    // Message about a new setting.
      Redraw=1;               // Redrawing at the end of the loop.
    }                                                                    
//--------------------------------- EA button state -----------------
   Knopka = 0;                                         // Preset
   if( IsExpertEnabled()) Knopka = 1; 
// Check for the real state of the button
 
   if(Knopka==1 && Knopka_Old==0) 
// If the state has changed for ON
    {
      Knopka_Old = 1;                // This will be the old one
      Mess_graf_scr(3);              // Inform the user about changes
    }
   if(Knopka==0 && Knopka_Old==1) 
// If the state has changed for OFF
    {
      Knopka_Old = 0;                 // This will be the old one
      Mess_graf_scr(4);              // Inform the user about changes
    }
//-------------------------------------------------- New tick --------
   New_Tick=0;                              // First of all, zeroize
   if (RefreshRates()==true) New_Tick=1; 
// It is easy to catch a new tick if you know how to do it
//--------------------------------------------------------------------
//====================================================================
   return;
 }
//жжжжжжжжжжжжжжжжжжжжж; End of module жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж


Vamos considerar a necessidade dessa função em maiores detalhes. Nós mencionamos no início do artigo que sempre que o EA é carregado, assim como quando as suas variáveis são atualizadas, a sua função subordinada Metsenat_exp() configura o valor de GV_Extern como 1. Em relação ao script, isso significa que as configurações precisam ser atualizadas. Para este fim, a função Novator_scr() contém o seguinte bloco:

//---------------------------------------- Updating settings ----
   if (GlobalVariableGet(GV_Extern)==1) 
// An update has taken place in the EA
    {
      Metsenat_scr();              // Updating script settings.
      Mess_graf_scr(5000);         // New setting message.
      Redraw=1;                    // Redrawing at the end of the loop.
    }

O valor da variável acima é analisado aqui e, em caso de necessidade de atualização, a função Metsenat_scr() é chamada, e realiza a atualização (leitura de novos valores de variáveis globais).


// Metsenat_scr.mq4
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
int Metsenat_scr()
  {
//========================================================== int ====
//======================================================= double ====
//======================================================= string ====
      MyGrafic    = "MyGrafic_";
    Mess_Graf   = "Mess_Graf_";
    Symb        = "_"+Symbol();
    GV          = "MyGrafic_GV_";
//=============================================== GlobalVariable ====
     GV_Ind_Yes  = GV+"Ind_Yes" +Symb;       
// 0/1 confirms that the indicator has been loaded
     GV_Exp_Yes  = GV+"Exp_Yes" +Symb;       
// 0/1 confirms that the EA has been loaded
//-------------------------------------------------- Publishing -----
     GV_Scr_Yes  = GV+"Scr_Yes" +Symb;     
    GlobalVariableSet(GV_Scr_Yes,          1 ); 
    GV_Extern   = GV+"Extern"  +Symb;     
    GlobalVariableSet(GV_Extern,           0 ); 
//--------------------------------------------------- Reading -------
                                             //  AAA is used as an example:
     GV_AAA      = GV+"AAA"     +Symb;     
   AAA  = GlobalVariableGet(GV_AAA); 
//===================================================================
     return;
 }
//жжжжжжжжжжжжжжжжжжжжжжжж End of module жжжжжжжжжжжжжжжжжжжжжжжжжжжж


A função Metsenat_scr(), por sua vez, configura o valor da variável global GV_Extern como 0. Na história a seguir, essa variável permanece igual a 0 até o usuário abrir a janela de configuração do EA.

Note que, apesar do fato de que devido às alterações em suas configurações o EA passa por todos os estágios de descarregamento e carregamento, o script não para de funcionar durante ou após as alterações nas configurações por parte do usuário. Portanto, o uso combinado do Expert Advisor e do script auxilia no cumprimento do requisito de operação, a continuidade da aplicação, e permite ao usuário alterar as configurações, ou seja, controlar o processo.

No bloco seguinte da função Novator_scr(), o botão do EA é controlado de modo a permitir que ele realize transações. Em seguida, um novo tick é detectado. Caso o seu sistema de transações presuma o uso daqueles parâmetros e de parâmetros semelhantes, é a função Novator_scr() que é destinada a cálculos do tipo.

Por exemplo, você pode completar essa função com blocos que detectam se uma nova barra surgiu, verificam se o tempo de um evento crítico foi alcançado, detectam se os termos comerciais foram alterados (por exemplo, o tamanho da margem, a distância mínima na qual os pedidos de parada podem ser feitos, etc.), e também fazem outros cálculos necessários antes das funções analíticas básicas começarem a operar.

As funções que produzem o conteúdo básico do programa não são exibidas na função Work_scr(). No artigo chamado Consideração de pedidos em um programa amplo, nós tratamos da função Terminal() que considera pedidos. Se você usar o mesmo princípio de consideração no seu sistema de transações, a função Terminal() deve ser incluída na função Work_scr() imediatamente após a função Novator_scr().

O script tem mais uma função auxiliar à sua disposição: Mess_graf_scr() que é destinada a exibir mensagens na janela do indicador.

// Mess_graf_scr.mq4
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
int Mess_graf_scr(int Mess_Number)
 {
//====================================================================
   if(Mess_Number== 0)        // This happens in every loop Work
    {
      if(Time_Mess>0 && GetTickCount()-Time_Mess>15000) 
// Color print has outdated within the last 
       {                       // ..15 sec, let's color lines gray
         ObjectSet(Name_Graf_Text[1],OBJPROP_COLOR,Gray);
// Last 2 lines
         ObjectSet(Name_Graf_Text[2],OBJPROP_COLOR,Gray);
// The last 2 lines
         Time_Mess=0;         // Additional flag not to color in vain
         Redraw=1;            // Then redraw
       }
      return;                 // It was a little step into 
    }
//--------------------------------------------------------------------
   Time_Mess=GetTickCount(); // Remember the message publishing time
   Por_Nom_Mess_Graf++;      // Count lines. This is just a name part.
   Stroka_2=0;            // Presume that message in one line
   if(Mess_Number>1000)      
// If a huge number occurs, the number will be brought to life, 
// understand that the previous line is from the same message, i.e.,it 
// should not be colored gray 
    {
      Mess_Number=Mess_Number/1000; 
      Stroka_2=1; 
    } 
//====================================================================
   switch(Mess_Number)
    {
//--------------------------------------------------------------------
      case 1:
         Graf_Text = "All necessary components installed.";
         Color_GT = LawnGreen; 
         break;
//--------------------------------------------------------------------
      case 2:
         Graf_Text = " ";
         break;
//--------------------------------------------------------------------
      case 3:
         Graf_Text = "Expert Advisors enabled.";
         Color_GT = LawnGreen; 
         break;
//--------------------------------------------------------------------
      case 4:
         Graf_Text = "Expert Advisors disabled.";
         Color_GT = Tomato; 
         break;
//--------------------------------------------------------------------
      case 5:
         Graf_Text = "Expert Advisor settings have been updated.";
         Color_GT = White; 
         break;
//---------------------------------------------------- default -------
      default:
         Graf_Text = "Line default "+ DoubleToStr( Mess_Number, 0);
         Color_GT = Tomato;
         break;
    }
//====================================================================
   ObjectDelete(Name_Graf_Text[30]); 
// the 30th object is preempted, delete it
   int Kol_strok=Por_Nom_Mess_Graf;
   if(Kol_strok>30) Kol_strok=30;
//-----------------------------------------------------------------
   for(int lok=Kol_strok;lok>=2;lok--)
// Go through graphical text names
    {
      Name_Graf_Text[lok]=Name_Graf_Text[lok-1];        
// Reassign them (normalize)
      ObjectSet(Name_Graf_Text[lok],OBJPROP_YDISTANCE,2+14*(lok-1));
//Change Y value (normalize)
      if(lok==3 || lok==4 || (lok==2 && Stroka_2==0))
         ObjectSet(Name_Graf_Text[lok],OBJPROP_COLOR,Gray);
//Color old lines gray.. 
    }
//-------------------------------------------------------------------
   Graf_Text_Number=DoubleToStr( Por_Nom_Mess_Graf, 0); 
//The unique part of the name unite with the message number
   Name_Graf_Text[1] = MyGrafic + Mess_Graf + Graf_Text_Number;
// Form the message name.
   Win_ind= WindowFind("Indicator");                    
//What is the window number of our indicator?
 
   ObjectCreate ( Name_Graf_Text[1],OBJ_LABEL, Win_ind,0,0);
// Create an object in the indicator window
   ObjectSet    ( Name_Graf_Text[1],OBJPROP_CORNER, 3   );  
// ..with coord, from the bottom-right corner..
   ObjectSet    ( Name_Graf_Text[1],OBJPROP_XDISTANCE,450); 
// ..with coordinates on X..
   ObjectSet    ( Name_Graf_Text[1],OBJPROP_YDISTANCE, 2);  
// ..with coordinates on Y..
   ObjectSetText(Name_Graf_Text[1],Graf_Text,10,"Courier New",
                 Color_GT);
//text font color
   Redraw=1;                                  // Then redraw
//=================================================================
   return;
 }
//жжжжжжжжжжжжжжжжжжжжжж End of module жжжжжжжжжжжжжжжжжжжжжжжжжжжж

Não é necessário considerar essa função em maiores detalhes. Nós podemos apenas mencionar alguns dos seus recursos especiais.


1. Todas as mensagens são exibidas através de representações gráficas.
2. O parâmetro formal a ser passado à função corresponde ao número da mensagem.
3. Caso o valor do parâmetro passado esteja entre 1 e 999, a linha de texto anterior na janela do indicador perderá a sua cor. Caso esse valor exceder 1000, a mensagem será exibida, sendo que o seu número é igual ao valor passado dividido por mil. Neste último caso, a linha anterior não perderá a sua cor.
4. Ao fim de quinze segundos após a última mensagem, todas as linhas perderão as suas cores.
5. Mantendo a possibilidade de descolorir linhas, a função deve ser ativada de tempos em tempos. Então há uma chamada ao fim da função Work_scr():

   Mess_graf_scr(0);


No artigo chamado Expert Advisor gráfico: AutoGraf, um conjunto de programa em funcionamento real é representado, sendo que nós usamos uma função semelhante contendo mais de 250 mensagens variadas. Você pode consultar este exemplo para usar todas ou algumas daquelas mensagens nas suas transações.

3.3. Indicador

Para que a nossa apresentação esteja completa, vamos considerar também o indicador, ainda que o seu código seja bastante simples.

// Indicator.mq4
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж; include жжжжжжжжжж
#include <stdlib.mqh>
#include <stderror.mqh>
#include <WinUser32.mqh>
//=======================================================================
#include <Peremen_ind.mq4>       
// Description of the indicator variables.
#include <Metsenat_ind.mq4>      
// Predefining the indicator variables. 
#include <Del_GV_ind.mq4>        
// Deletion of all GlobalVariables created by the indicator.
#include <Component_ind.mq4>     
// Check components for availability.
#include <Component_uni.mq4>     
// Message in the indicator about inavailability of components.
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
//
// 
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
#property indicator_separate_window
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
//
//
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
int init()  
 {
   Metsenat_ind();
   return;
 }
//=======================================================================
int start() 
 {
   if(Component_ind()==0) return; // Check for availability of components
   //...
   return;                                                           
 }
//=======================================================================
int deinit() 
 {
   Del_GV_ind();             // Deletion of the indicator GlobalVariable.
   return;
 }
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж


Apenas um recurso crítico de um indicador deve ser destacado aqui: O indicador é exibido em uma janela separada:

#property indicator_separate_window

Os conteúdos das funções Metsenat_ind() e Del_GV_ind() são semelhantes àqueles das funções consideradas previamente em relação ao Expert Advisor e ao script.

O conteúdo da função Component_ind() também é pouco sofisticado:

// Component_ind.mq4
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
int Component_ind()
 {
//===================================================================
   if(GlobalVariableGet(GV_Exp_Yes)==1 && 
      GlobalVariableGet(GV_Scr_Yes)==1)
//If all components are available
    {                        // State about the indicator available
      if(GlobalVariableGet(GV_Ind_Yes)!=1)
          GlobalVariableSet(GV_Ind_Yes,1);
      return(1);
    }
//--------------------------------------------------------------------
   if(GlobalVariableGet(GV_Scr_Yes)!=1 && 
      GlobalVariableGet(GV_Exp_Yes)!=1)
    {                           // If there is neither script nor EA  
      Graf_Text = "Components Expert and Script are not installed.";            
// Текст сообщения
      Component_uni();        // Write the info message in ind. window
    }
//=====================================================================
   return(0);
 }
//жжжжжжжжжжжжжжжжжжжжж; End of module жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж

Como podemos ver a partir do código, a função

Component_ind() apresenta uma mensagem apenas caso dois outros componentes não tiverem sido carregados - tanto o script quanto o Expert Advisor. Caso apenas um dos programas estiver indisponível, nenhuma ação será tomada. Isso presume que, caso eles estejam disponíveis na janela do símbolo, estes programas monitoram a composição do conjunto do programa e informam os resultados ao usuário.

Caso seja necessário, a propriedade principal do indicador, o desenho, também pode ser usada. Em termos do conjunto do programa, essa propriedade não é necessária, mas ela pode ser usada em transações reais, por exemplo, para dividir a subjanela em zonas.

4. Uso prático

A ordem de anexação dos componentes da aplicação à janela do símbolo não é importante. Contudo, recomenda-se anexar o indicador em primeiro lugar, pois isso nos permite ler os comentários logo após a anexação.

Portanto, deve-se fazer o seguinte para demonstrar o funcionamento da aplicação.

1. Anexar o indicador à janela do símbolo. Esta mensagem será exibida na janela do indicador imediatamente:

Os componentes Expert e Script não estão instalados
A aplicação não está em funcionamento.


2. Anexar o Expert Advisor à janela do símbolo. A função Component_exp() será acionada, e a seguinte mensagem irá aparecer na janela do indicador:

O Script não está instalado
A aplicação não está em funcionamento.


3. Anexar o script à janela do símbolo. Este evento será processado na função Component_scr() do script e exibido na janela do indicador:


Todos os componentes necessários estão instalados.
Expert Advisors habilitados.


Caso os Expert Advisors estivessem desabilitados, a mensagem seria a seguinte:

Todos os componentes necessários estão instalados.
Expert Advisors desabilitados.


4. Você pode pressionar o botão do EA várias vezes e verificar se essa sequência de eventos é processada pela aplicação imediatamente e exibida nas linhas de mensagem:

Expert Advisors desabilitados.
Expert Advisors habilitados.

Expert Advisors desabilitados.
Expert Advisors habilitados.
Expert Advisors desabilitados.


Note, por favor, que devido ao uso do script com o código básico em ciclo no conjunto do programa, a resposta do programa aos controles do usuário não é realizada ao longo de múltiplos ticks, mas imediatamente.

Por exemplo, nós colocamos, na função Work_scr(), a exibição dependente de ticks de uma variável das configurações do EA usando a função Alert().

Vamos considerar este recurso. A função Work_scr() é uma parte do script. O ciclo básico do script tem tempo para realizar centenas de revoluções entre os ticks enquanto a mensagem é apresentada pela função Alert() ao longo de múltiplos ticks.

5. Abra a barra de ferramentas de configuração do EA e substitua o valor AAA por 3. O script irá monitorar este evento e apresentar uma mensagem na janela do indicador:

Expert Advisors habilitados.
Expert Advisors desabilitados.
Expert Advisors habilitados.

Expert Advisors desabilitados.
As configurações do EA foram atualizadas.


A janela da função Alert() irá exibir o novo valor da variável AAA de acordo com os ticks:





6. Agora você pode carregar ou descarregar quaisquer componentes em qualquer sequência, brincar com o botão do EA, alterar o valor de variáveis ajustáveis, e formar a sua própria opinião a respeito da qualidade do conjunto do programa.

Conclusão

A principal vantagem alcançada através do uso da tecnologia descrita é o fato de que o script não para de funcionar, não importando se os eventos se dão ou não no seu ambiente. O script irá parar de funcionar caso ele perceba que um ou ambos os outros componentes (indicador, Expert Advisor) não estão disponíveis.

O princípio descrito de se criar um conjunto de programa é, de forma levemente modificada, usado na aplicação em funcionamento real AutoGraf que foi descrita no artigo chamado Expert Advisor gráfico: AutoGraf.

SK. Dnepropetrovsk. 2006

Traduzido do russo pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/1393

Arquivos anexados |
Exp_Scr_Ind.zip (33.24 KB)
Eventos no MetaTrader 4 Eventos no MetaTrader 4
O artigo trata do monitoramento programado de eventos no terminal do cliente do MetaTrader 4, como a abertura/fechamento/modificação de pedidos, e é destinado a um usuário que possua habilidades básicas no trabalho com o terminal e em programação em MQL4.
Consideração de pedidos em um programa amplo Consideração de pedidos em um programa amplo
São discutidos princípios gerais de consideração de pedidos em um programa amplo e complexo.
Como avaliar os resultados dos testes do Expert Como avaliar os resultados dos testes do Expert
O artigo fornece fórmulas e a ordem de cálculo relativas aos dados exibidos no relatório do verificador.
Trabalhando com arquivos. Um exemplo de visualização de eventos de mercado importantes Trabalhando com arquivos. Um exemplo de visualização de eventos de mercado importantes
O artigo trata das perspectivas do uso do MQL4 para a realização de trabalhos mais produtivos nos mercados FOREX.