English Русский 中文 Español Deutsch 日本語 한국어 Français Italiano Türkçe
Alterar os parâmetros do Expert Advisor instantaneamente a partir do painel de usuário

Alterar os parâmetros do Expert Advisor instantaneamente a partir do painel de usuário

MetaTrader 5Exemplos | 18 março 2014, 14:19
6 814 0
Anatoli Kazharski
Anatoli Kazharski

Conteúdo

Introdução
1. Assuntos em foco
2. Estrutura do Expert Advisor
3. Interação com o painel de usuário
Conclusão


Introdução

Durante o desenvolvimento de Expert Advisors complexos, o número de parâmetros externos pode ser muito grande. E, muito frequentemente, é necessário alterar as configurações manualmente, o que torna todo o processo muito demorado devido a enorme lista de parâmetros. É claro que é possível preparar conjuntos com antecedência e salvá-los, mas isso pode não ser exatamente o requerido em alguns casos. É aqui que o MQL5 é útil, como sempre.

Vamos tentar criar um painel de usuário que permitirá alterarmos os parâmetros de um Expert Advisor instantaneamente enquanto negociamos. Isso pode ser relevante para aqueles que negociam em modo manual ou semi-automático. Após cada alteração, os parâmetros serão escritos em um arquivo a partir do qual eles serão lidos pelo Expert Advisor para que sejam posteriormente exibidos no painel.


1. Assuntos em foco

Como exemplo, vamos desenvolver um EA simples que abre uma posição na direção do indicador JMA. O EA irá trabalhar em barras completas no símbolo e período de tempo atual. Os parâmetros externos incluirão Indicator Period (período do indicador), Stop Loss (interromper perda), Take Profit (obter lucro), Reverse (inverso) e Lot (lote). Essas opções serão suficientes para o nosso exemplo.

Vamos incluir dois parâmetros adicionais para que seja possível ligar e desligar o painel (On/Off Info Panel) e habilitar/desabilitar o modo de configuração de parâmetros do Expert Advisor (Configuração "On the Fly"). Quando o número de parâmetros é grande, é sempre mais conveniente colocar posições adicionais no início do final da lista para acesso mais fácil e rápido.

Figura 1. Painel de informações com parâmetros do Expert Advisor

Figura 1. Painel de informações com parâmetros do Expert Advisor

O modo de configuração "On The Fly" (instantâneo) está automaticamente desabilitado. Quando você habilita esse modo pela primeira vez, o Expert Advisor cria um arquivo para salvar todos os seus parâmetros atuais. O mesmo acontece caso o arquivo seja acidentalmente apagado. O Expert Advisor irá detectar o apagamento e criar o arquivo novamente. Com o modo de configuração "On The Fly" desabilitado, o Expert Advisor será dirigido por parâmetros externos.

Se esse modo for habilitado, o Expert Advisor lerá os parâmetros do arquivo e, com um simples clique sobre qualquer parâmetro do painel de informações, você poderá ou selecionar o valor requerido ou inserir um novo valor na janela de diálogo que aparecerá. Os dados do arquivo serão atualizados cada vez que um novo valor for selecionado.


2. Estrutura do Expert Advisor

Embora o programa seja pequeno e todas as funções possam facilmente estar em um arquivo único, ainda é muito mais conveniente navegar por todas as informações do projeto quando elas estão devidamente categorizadas. Assim, é melhor categorizar as funções pelo tipo e tê-las em diferentes arquivos desde o início para posteriormente incluí-los no arquivo mestre. A figura abaixo mostra uma pasta de projeto compartilhada com o Expert Advisor OnTheFly e todos os arquivos inclusos. Os arquivos inclusos são colocados em uma pasta separada (Include).

Figura 2. Arquivos de projeto na janela do navegador do MetaEditor

Figura 2. Arquivos de projeto na janela do navegador do MetaEditor

Quando os arquivos inclusos estão na mesma pasta que o arquivo mestre, o código é o seguinte:

//+------------------------------------------------------------------+
//| CUSTOM LIBRARIES                                                 |
//+------------------------------------------------------------------+
#include "Include/!OnChartEvent.mqh"
#include "Include/CREATE_PANEL.mqh"
#include "Include/FILE_OPERATIONS.mqh"
#include "Include/ERRORS.mqh"
#include "Include/ARRAYS.mqh"
#include "Include/TRADE_SIGNALS.mqh"
#include "Include/TRADE_FUNCTIONS.mqh"
#include "Include/GET_STRING.mqh"
#include "Include/GET_COLOR.mqh"
#include "Include/ADD_FUNCTIONS.mqh"

Mais informações sobre como incluir arquivos podem ser encontradas na Referência MQL5.

Precisaremos de variáveis globais - cópias de parâmetros externos. Os seus valores ou serão designados a partir dos parâmetros externos ou do arquivo, dependendo do modo do Expert Advisor. Essas variáveis são utilizadas ao longo de todo o código do programa, por exemplo, para exibir valores no painel de informações, nas funções de negociação, etc.

// COPY OF EXTERNAL PARAMETERS
int    gPeriod_Ind = 0;
double gTakeProfit = 0.0;
double gStopLoss   = 0.0;
bool   gReverse    = false;
double gLot        = 0.0;

Como em todos os outros Expert Advisors, teremos as funções principais: OnInit, OnTick e OnDeinit. E também haverá a função OnTimer. A cada segundo, ela irá verificar a existência do arquivo de parâmetro e recuperá-lo caso ele tenha sido acidentalmente apagado. Visto que precisamos interagir com o painel de usuário, a função OnChartEvent também será usada. Essa função, juntamente com outras funções relacionadas, foi colocada em um arquivo separado (!OnChartEvent.mqh).

O código principal do arquivo mestre é o seguinte:

#define szArrIP 5 // Size of the parameter array
#define NAME_EXPERT MQL5InfoString(MQL5_PROGRAM_NAME) // Name of EA
#define TRM_DP TerminalInfoString(TERMINAL_DATA_PATH) // Folder that contains the terminal data
//+------------------------------------------------------------------+
//| STANDARD LIBRARIES                                               |
//+------------------------------------------------------------------+
#include 
#include 
//+------------------------------------------------------------------+
//| CUSTOM LIBRARIES                                                 |
//+------------------------------------------------------------------+
#include "Include/!OnChartEvent.mqh"
#include "Include/CREATE_PANEL.mqh"
#include "Include/FILE_OPERATIONS.mqh"
#include "Include/ERRORS.mqh"
#include "Include/ARRAYS.mqh"
#include "Include/TRADE_SIGNALS.mqh"
#include "Include/TRADE_FUNCTIONS.mqh"
#include "Include/GET_STRING.mqh"
#include "Include/GET_COLOR.mqh"
#include "Include/ADD_FUNCTIONS.mqh"
//+------------------------------------------------------------------+
//| CREATING CLASS INSTANCES                                         |
//+------------------------------------------------------------------+
CSymbolInfo mysymbol; // CSymbolInfo class object 
CTrade      mytrade;  // CTrade class object
//+------------------------------------------------------------------+
//| EXTERNAL PARAMETERS                                              |
//+------------------------------------------------------------------+
input int    Period_Ind      = 10;    // Indicator Period
input double TakeProfit      = 100;   // Take Profit (p)
input double StopLoss        = 30;    // Stop Loss (p)
input bool   Reverse         = false; // Reverse Position
input double Lot             = 0.1;   // Lot
//---
input string slash="";       // * * * * * * * * * * * * * * * * * * *
sinput bool  InfoPanel       = true;  // On/Off Info Panel
sinput bool  SettingOnTheFly = false; // "On The Fly" Setting
//+------------------------------------------------------------------+
//| GLOBAL VARIABLES                                                 |
//+------------------------------------------------------------------+
int hdlSI=INVALID_HANDLE; // Signal indicator handle
double lcheck=0;  // For the check of parameter values
bool isPos=false; // Position availability
//--- COPY OF EXTERNAL PARAMETERS
int    gPeriod_Ind = 0;
double gTakeProfit = 0.0;
double gStopLoss   = 0.0;
bool   gReverse    = false;
double gLot        = 0.0;
//+------------------------------------------------------------------+
//| EXPERT ADVISOR INITIALIZATION                                    |
//+------------------------------------------------------------------+
void OnInit()
  {
   if(NotTest()) { EventSetTimer(1); } // If it's not the tester, set the timer
//---
   Init_arr_vparams(); // Initialization of the array of parameter values
   SetParameters(); // Set the parameters
   GetIndicatorsHandles(); // Get indicator handles
   NewBar(); // New bar initialization
   SetInfoPanel(); // Info panel
  }
//+------------------------------------------------------------------+
//| CURRENT SYMBOL TICKS                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
// If the bar is not new, exit
   if(!NewBar()) { return; }
   else
     { TradingBlock(); }
  }
//+------------------------------------------------------------------+
//| TIMER                                                            |
//+------------------------------------------------------------------+
void OnTimer()
  {
   SetParameters(); SetInfoPanel();
  }
//+------------------------------------------------------------------+
//| EXPERT ADVISOR DEINITIALIZATION                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
// Get the deinitialization reason code
   if(NotTest()) {
     { Print(getUnitReasonText(reason)); }
//---
// When deleting from the chart
   if(reason==REASON_REMOVE)
     {
      // Delete all objects created by the Expert Advisor
      DeleteAllExpertObjects();
      //---
      if(NotTest()) { EventKillTimer(); } // Stop the timer
      IndicatorRelease(hdlSI); // Delete the indicator handle
     }
  }

Também inclui mais algumas funções no arquivo mestre:

  • GetIndicatorsHandles – obtém o handle do indicador.
  • NewBar – determina o evento de nova barra.
  • SetParameters – estabelece os parâmetros de acordo com o modo.
  • iZeroMemory – zera algumas variáveis e arrays.
Os códigos fonte dessas funções podem ser encontrados nos arquivos anexos a este artigo Aqui, apenas analisaremos a função SetParameters function (os comentários explicativos estão apresentados no código):
//+------------------------------------------------------------------+
//| SETTING PARAMETERS IN TWO MODES                                  |
//+------------------------------------------------------------------+
// If this variable is set to false, the parameters in the file are read from the array
// where they are saved for quick access after they have been read for the first time.
// The variable is zeroed out upon the change in the value on the panel.
bool flgRead=false;
double arrParamIP[]; // Array where the parameters from the file are saved
//---
void SetParameters()
  {
// If currently in the tester or
// in real time but with the "On The Fly" Setting mode disabled
   if(!NotTest() || (NotTest() && !SettingOnTheFly))
     {
      // Zero out the variable and parameter array
      flgRead=false;
      ArrayResize(arrParamIP,0);
      //---
      // Check the Indicator Period for correctness
      if(Period_Ind<=0)
        { lcheck=10; }
      else { lcheck=Period_Ind; }
      gPeriod_Ind=(int)lcheck;
      //---
      gStopLoss=StopLoss;
      gTakeProfit=TakeProfit;
      gReverse=Reverse;
      //---
      // Check the Lot for correctness
      if(Lot<=0)
        { lcheck=0.1; }
      else { lcheck=Lot; }
      gLot=lcheck;
     }
   else // If "On The Fly" Setting mode is enabled
     {
      // Check whether there is a file to write/read parameters to/from the file
      string lpath="";
      //---
      // If the folder exists
      if((lpath=CheckCreateGetPath())!="")
        {
         // Write or read the file
         WriteReadParameters(lpath);
        }
     }
  }

O código fonte para a função SetParameters é simples e direto. Vamos analisar a função WriteReadParameters de perto. Tudo aqui é muito simples. Primeiramente, verificamos se o arquivo com os parâmetros existe. Caso exista, lemos o arquivo e escrevemos os valores de parâmetro em um array, utilizando a função GetValuesParamsFromFile. Se o arquivo não existir, ele será criado, com os parâmetros externos atuais escritos nele.

Abaixo, segue o código com mais comentários detalhados para a implementação das ações descritas acima:

//+------------------------------------------------------------------+
//| WRITE DATA TO FILE                                               |
//+------------------------------------------------------------------+
void WriteReadParameters(string pth)
  {
   string nm_fl=pth+"ParametersOnTheFly.ini"; // File name and path
//---
// Get the file handle to read the file
   int hFl=FileOpen(nm_fl,FILE_READ|FILE_ANSI);
//---
   if(hFl!=INVALID_HANDLE) // If the handle has been obtained, the file exists
     {
      // Get parameters from the file
      if(!flgRead)
        {
         // Set the array size
         ArrayResize(arrParamIP,szArrIP);
         //---
         // Fill the array with values from the file
         flgRead=GetValuesParamsFromFile(hFl,arrParamIP);
        }
      //---
      // If the array size is correct,...
      if(ArraySize(arrParamIP)==szArrIP)
        {
         // ...set the parameters to the variables
         //---
         // Check the Indicator Period for correctness
         if((int)arrParamIP[0]<=0) { lcheck=10; }
         else { lcheck=(int)arrParamIP[0]; }
         gPeriod_Ind=(int)lcheck;
         //---
         gTakeProfit=arrParamIP[1];
         gStopLoss=arrParamIP[2];
         gReverse=arrParamIP[3];
         //---
         // Check the Lot for correctness
         if(arrParamIP[4]<=0)
           { lcheck=0.1; }
         else { lcheck=arrParamIP[4]; }
         gLot=lcheck;
        }
     }
   else // If the file does not exist
     {
      iZeroMemory(); // Zero out variables
      //---
      // When creating the file, write current parameters of the Expert Advisor
      //---
      // Get the file handle to write to the file
      int hFl2=FileOpen(nm_fl,FILE_WRITE|FILE_CSV|FILE_ANSI,"");
      //---
      if(hFl2!=INVALID_HANDLE) // If the handle has been obtained
        {
         string sep="=";
         //---
         // Parameter names and values are obtained from arrays in the ARRAYS.mqh file
         for(int i=0; i<szarrip; i++)=""           ="" {="" FileWrite(hFl2,arr_nmparams[i],sep,arr_vparams[i]); }
         //---
         FileClose(hFl2); // Close the file
         //---
         Print("File with parameters of the "+NAME_EXPERT+" Expert Advisor created successfully.");
        }
     }
//---
   FileClose(hFl); // Close the file
  }

As funções The WriteReadParameters e GetValuesParamsFromFile podem ser encontradas no arquivo FILE_OPERATIONS.mqh.

Algumas das funções já foram descritas em meu artigo anterior "Como preparar cotações do MetaTrader 5 para outros aplicativos", de forma que não vou me ater a elas aqui. Você também não deverá ter qualquer dificuldade com as funções de negociação, visto que elas são muito diretas e estão detalhadamente comentadas. O que vamos fazer é focar no assunto principal do artigo.


3. Interação com o painel de usuário

O arquivo !OnChartEvent.mqh contém funções para interação com o painel de usuário. Variáveis e arrays que são usados em muitas funções são declarados no escopo global logo no início:

// Current value on the panel or
// entered in the input box
string currVal="";
bool flgDialogWin=false; // Flag for panel existence
int
szArrList=0,// Size of the option list array
number=-1; // Parameter number in the panel list
string
nmMsgBx="",  // Name of the dialog window
nmValObj=""; // Name of the selected object
//---
// Option list arrays in the dialog window
string lenum[],lenmObj[];
//---
// colors of the dialog window elements
color
clrBrdBtn=clrWhite,
clrBrdFonMsg=clrDimGray,clrFonMsg=C'15,15,15',
clrChoice=clrWhiteSmoke,clrHdrBtn=clrBlack,
clrFonHdrBtn=clrGainsboro,clrFonStr=C'22,39,38';

Isso é seguido pela função principal que gerencia os eventos. Em nosso exemplo, precisaremos gerenciar dois eventos:

  • O evento CHARTEVENT_OBJECT_CLICK – clique com o botão esquerdo sobre o objeto gráfico.
  • O evento CHARTEVENT_OBJECT_EDIT – fim da edição de texto no objeto gráfico Editar.

Você pode ler mais sobre outros eventos MQL5 na Referência MQL5.

Primeiramente, vamos colocar uma marca somente para gerenciamento de eventos em tempo real, sempre com a condição de que o modo de configuração "On The Fly" esteja habilitado (SettingOnTheFly). O gerenciamento de eventos será feito por duas funções separadas: ChartEvent_ObjectClick e ChartEvent_ObjectEndEdit.

//+------------------------------------------------------------------+
//| USER EVENTS                                                      |
//+------------------------------------------------------------------+
void OnChartEvent(const int     id,
                  const long   &lparam,
                  const double &dparam,
                  const string &sparam)
  {
// If the event is real time and the "On The Fly" setting mode is enabled
   if(NotTest() && SettingOnTheFly)
     {
      //+------------------------------------------------------------------+
      //| THE CHARTEVENT_OBJECT_CLICK EVENT                                |
      //+------------------------------------------------------------------+
      if(ChartEvent_ObjectClick(id,lparam,dparam,sparam)) { return; }
      //---
      //+------------------------------------------------------------------+
      //| THE CHARTEVENT_OBJECT_ENDEDIT EVENT                              |
      //+------------------------------------------------------------------+
      if(ChartEvent_ObjectEndEdit(id,lparam,dparam,sparam)) { return; }
     }
//---
   return;
  }

Quando você clica no objeto que pertence à lista, uma janela de diálogo aparecerá no painel de informações, permitindo que você selecione outro valor ou insira um novo valor na caixa de entrada.

Figura 3. Janela de diálogo para modificações do valor do parâmetro selecionado.

Figura 3. Janela de diálogo para modificações do valor do parâmetro selecionado.

Vamos analisar o funcionamento de perto. Quando se clica sobre um objeto gráfico, o programa primeiramente usa a função ChartEvent_ObjectClick para verificar com o identificador do evento se realmente houve um clique sobre um objeto gráfico.

Se você deseja que a janela de diálogo abra no meio do gráfico, você precisa saber o tamanho dele. Isso pode ser obtido pela indicação das propriedades CHART_WIDTH_IN_PIXELS e CHART_HEIGHT_IN_PIXELS na função ChartGetInteger. O programa então comuta para o DialogWindowInfoPanel. Você pode se familiarizar com as propriedades do gráfico na Referência MQL5.

Segue abaixo o código para a implementação das ações acima:

//+------------------------------------------------------------------+
//| THE CHARTEVENT_OBJECT_CLICK EVENT                                |
//+------------------------------------------------------------------+
bool ChartEvent_ObjectClick(int id,long lparam,double dparam,string sparam)
  {
   // If there was an event of clicking on a graphical object
   if(id==CHARTEVENT_OBJECT_CLICK) // id==1
     {
      Get_STV(); // Get all data on the symbol
      //---
      string clickedChartObject=sparam; // Name of the clicked object
      //---
      // Get the chart size
      width_chart=(int)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS,0);
      height_chart=(int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,0);
      //---
      DialogWindowInfoPanel(clickedChartObject);
     }
//---
   return(false);
  }

Utilizando a função DialogWindowInfoPanel, primeiramente verificamos se a janela de diálogo está aberta no momento. Se a janela não for encontrada, a função GetNumberClickedObjIP verifica se o clique foi em relação a um objeto da lista do painel de informações. Se o objeto clicado está na lista, a função retornará o número de elemento relevante do array de objetos. Utilizando esse número, a função InitArraysAndDefault determina o tamanho do array da lista na janela de diálogo e os valores padrão. Se todas as ações forem bem sucedidas, a janela de diálogo aparecerá.

Se a função DialogWindowInfoPanel determina que a janela de diálogo já está aberta, o programa verificará se houve ou não um clique sobre um objeto da janela de diálogo. Por exemplo, após abrir a janela de diálogo, a linha cujo valor está sendo exibido atualmente no painel aparecerá como selecionada. Se você clicar sobre outra opção da lista, o programa usará a função SelectionOptionInDialogWindow que seleciona a opção da lista que foi clicada na janela de diálogo.

Se você clicar sobre a opção da lista que está selecionada no momento, esse objeto será identificado como objeto a ser editado e uma caixa de entrada aparecerá para que um novo valor possa ser inserido quando você clicar nela. A função SetEditObjInDialogWindow é responsável pela configuração da caixa de entrada.

E finalmente, se houve um clique sobre o botão Aplicar, o programa verificará se o valor foi modificado. Caso tenha sido, o novo valor aparecerá no painel e será escrito no arquivo.

O código da função principal da janela de diálogo é fornecido abaixo:

//+------------------------------------------------------------------+
//| DIALOG WINDOW OF THE INFO PANEL                                  |
//+------------------------------------------------------------------+
void DialogWindowInfoPanel(string clickObj)
  {
// If there is currently no dialog window
   if(!flgDialogWin)
     {
      // Get the object number in the array
      // Exit if none of the parameters displayed on the panel has been clicked
      if((number=GetNumberClickedObjIP(clickObj))==-1) { return; }
      //---
      // Initialization of default values
      //and determination of the list array size
      if(!InitArraysAndDefault()) { return; }
      //---
      // Set the dialog window
      SetDialogWindow();
      //---
      flgDialogWin=true; // Mark the dialog window as open
      ChartRedraw();
     }
   else // If the dialog window is open
     {
      // Set the input box for the modification of the value
      SetEditObjInDialogWindow(clickObj);
      //---
      // If one of the buttons in the dialog box is clicked
      if(clickObj=="btnApply" || clickObj=="btnCancel")
        {
         // If the Apply button is clicked
         if(clickObj=="btnApply")
           {
            // Compare values on the panel with the ones on the list
            // If the value on the list is different from the one that is currently displayed on the panel 
            // (which means it is different from the one in the file),
            // ...change the value on the panel and update the file
            if(currVal!=ObjectGetString(0,nmValObj,OBJPROP_TEXT))
              {
               // Update the value on the panel
               ObjectSetString(0,nmValObj,OBJPROP_TEXT,currVal); ChartRedraw();
               //---
               // Read all data on the panel and write it to the file
               WriteNewData();
              }
           }
         //---
         DelDialogWindow(lenmObj); // Delete the dialog window
         iZeroMemory(); // Zero out the variables
         //---
         // Update the data
         SetParameters();
         GetHandlesIndicators();
         SetInfoPanel();
         //---
         ChartRedraw();
        }
      else // If neither Apply nor Cancel has been clicked
        {
         // Selection of the dialog window list option
         SelectionOptionInDialogWindow(clickObj);
         //---
         ChartRedraw();
        }
     }
  }

Cada vez que um novo valor é inserido na caixa de entrada, o evento CHARTEVENT_OBJECT_EDIT é gerado e o programa comuta para a função ChartEvent_ObjectEndEdit. Se o valor da janela de diálogo foi modificado, o valor inserido será armazenado, sua exatidão será verificada e ele será atribuído ao objeto da lista. Você pode visualizar mais detalhes no código abaixo:

//+------------------------------------------------------------------+
//| THE CHARTEVENT_OBJECT_ENDEDIT EVENT                              |
//+------------------------------------------------------------------+
bool ChartEvent_ObjectEndEdit(int id,long lparam,double dparam,string sparam)
  {
   if(id==CHARTEVENT_OBJECT_ENDEDIT) // id==3
     {
      string editObject=sparam; // Name of the edited object
      //---
      // If the value has been entered in the input box in the dialog window
      if(editObject=="editValIP")
        {
         // Get the entered value
         currVal=ObjectGetString(0,"editValIP",OBJPROP_TEXT);
         //---
         // (0) Period Indicator
         if(number==0)
           {
            // Correct the value if it is wrong
            if(currVal=="0" || currVal=="" || SD(currVal)<=0) { currVal="1"; }
            //---
            // Set the entered value
            ObjectSetString(0,"enumMB0",OBJPROP_TEXT,currVal);
           }
         //---
         // (4) Lot
         if(number==4)
           {
            // Correct the value if it is wrong
            if(currVal=="0" || currVal=="" || SD(currVal)<=0) { currVal=DS(SS.vol_min,2); }
            //---
            // Set the entered value
            ObjectSetString(0,"enumMB0",OBJPROP_TEXT,DS2(SD(currVal)));
           }
         //---
         // (1) Take Profit (p)
         // (2) Stop Loss (p)
         if(number==1 || number==2)
           {
            // Correct the value if it is wrong
            if(currVal=="0" || currVal=="" || SD(currVal)<=0) { currVal="1"; }
            //---
            // Set the entered value
            ObjectSetString(0,"enumMB1",OBJPROP_TEXT,currVal);
           }
         //---         
         DelObjbyName("editValIP"); ChartRedraw();
        }
     }
//---
   return(false);
  }

O Expert Advisor em ação pode ser visto no vídeo abaixo:



Conclusão

Você poderá fazer o download dos arquivos zipados ao final do artigo para um estudo mais detalhado.

Espero que este artigo ajude quem começou a aprender MQL5 agora a encontrar respostas rápidas para diversas questões, através do uso dos exemplos simples apresentados. Intencionalmente, deixei de fora algumas verificações dos fragmentos de código apresentados.

Por exemplo, se você alterar a altura/largura quando a janela de diálogo estiver aberta, a janela não ficará automaticamente centralizada. E se você completa isso com a seleção de outra opção da lista, o objeto que serve para selecionar a linha relevante será consideravelmente deslocada. Deixe que isso seja a sua lição de casa. É muito importante praticar programação. Quando mais você praticar, melhor.

Boa sorte!

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

Arquivos anexados |
onthefly_en.zip (26.38 KB)
Aprendizagem de máquina: como as máquinas de vetores de suporte podem ser utilizadas nas negociações Aprendizagem de máquina: como as máquinas de vetores de suporte podem ser utilizadas nas negociações
As máquinas de vetores de suporte foram por muito tempo usadas em campos como de bioinformática e aplicava matemática para avaliar conjuntos de dados e extrair padrões úteis que podem ser usados para classificar dados. Este artigo visa em como é uma máquina de vetor de suporte, como trabalha e por que pode ser tão útil na extração de padrões complexos. Podemos investigar como elas podem ser aplicadas ao mercado e potencialmente usadas para aconselhar sobre negócios. Usando a Ferramenta de aprendizado da máquina de vetor de suporte, o artigo fornece exemplos trabalhados que permitem que os leitores experimentem com seus próprios negócios.
Fundamentos básicos da programação MQL5: arrays Fundamentos básicos da programação MQL5: arrays
Juntamente com as variáveis e funções, os arrays são partes integrais de quase todas as linguagens de programação. O artigo deve ser de interesse principalmente para programadores MQL5 novatos, enquanto os desenvolvedores mais experientes terão uma boa oportunidade para resumir e sistematizar seu conhecimento.
Fundamentos básicos da programação MQL5: strings Fundamentos básicos da programação MQL5: strings
O artigo cobre tudo que você pode fazer com strings no MQL5. Deve ser de interesse principalmente para programadores MQL5 novatos, enquanto os desenvolvedores mais experientes terão uma boa oportunidade para resumir e sistematizar seu conhecimento.
Sinais de negociação no MetaTrader 5: uma melhor alternativa às contas PAMM! Sinais de negociação no MetaTrader 5: uma melhor alternativa às contas PAMM!
Temos o prazer de anunciar que o MetaTrader 5 agora dispõe de Sinais de negociação, proporcionando assim uma ferramenta poderosa aos investidores e gerentes. Enquanto você estiver seguindo as negociações de um trader bem sucedido, o terminal irá reproduzi-las automaticamente em sua conta!