English Русский 中文 Español Deutsch 日本語
preview
Agora é mais fácil criar painéis gráficos no MQL5

Agora é mais fácil criar painéis gráficos no MQL5

MetaTrader 5Negociação | 9 novembro 2023, 13:06
921 0
Mohamed Abdelmaaboud
Mohamed Abdelmaaboud

Introdução

O MQL5 oferece aos desenvolvedores uma variedade de ferramentas úteis que facilitam a escrita de código. Em particular, o MQL5 contém um grande número de bibliotecas ou classes que podem ser usadas para escrever vários aplicativos, como painéis e bibliotecas, sem criar seu código do zero. Neste artigo, aprenderemos como podemos usar essas classes para criar aplicativos, bem como apresentaremos dois métodos diferentes de criação do mesmo aplicativo.

O artigo pode servir como um excelente material prático para melhorar as habilidades de programação de um desenvolvedor iniciante através da criação de um aplicativo do zero. Além disso, o artigo pode ser visto como um guia simples para o desenvolvimento de ferramentas que facilitam o trabalho dos traders. Se você é um desenvolvedor iniciante em MQL5, ele pode ser usado como um guia para criar painéis gráficos no terminal MetaTrader 5.

O artigo aborda o seguintes tópicos:

Eu recomendo que você se familiarize com o tópico de programação orientada a objetos em MQL5 para entender melhor o tópico deste artigo. Em particular, você pode ler meu artigo "Programação Orientada a Objetos (POO) em MQL5".

Atenção! Todo o conteúdo deste artigo é apresentado "tal qual como está", apenas para fins educacionais e não constitui uma recomendação de trading. O artigo não oferece nenhuma garantia de resultados. Tudo o que você colocar em prática com base neste artigo, você faz exclusivamente por sua conta e risco, o autor não garante nenhum resultado.


Identificação gráfica de painéis

Nesta seção, aprenderemos o que é um painel gráfico e como ele pode ser útil para nós na indústria de negociação. Um painel pode ser apenas uma interface gráfica com funções ou informações úteis, como um painel para abrir e gerenciar negociações, fornecer informações sobre a conta ou o dia de negociação, entre outras coisas. Tais painéis economizam tempo ao executar ações ou obter informações necessárias, permitindo-nos concentrar mais na negociação e análise de mercado.

Podemos criar um painel personalizado dependendo dos objetos e tarefas ou da natureza da interação entre o usuário e esse painel. Os objetos incluem, em particular:

  • Números,
  • Strings,
  • Formas,
  • Cores,
  • Botões,
  • Etc.

Existem dois métodos para criar e desenvolver esses painéis. Podemos escrever o código do zero, o que consome muito tempo e esforço, mas se você for um desenvolvedor, deve entender como fazê-lo, pois isso aprimora suas habilidades de programação. O segundo método é usar classes ou bibliotecas prontas para executar seu trabalho de maneira rápida e eficiente, economizando muito tempo e esforço. Neste artigo, aprenderemos mais sobre as classes que podem ser usadas para criar painéis. Além disso, criaremos um aplicativo simples usando ambos os métodos. Isso demonstrará o valor das classes.


Classes de painéis e diálogos

Vamos considerar as classes que nos ajudarão a criar facilmente um painel gráfico. Vamos nos referir às classes de painéis e diálogos. Informações mais detalhadas sobre elas podem ser encontradas na documentação do MQL5. Neste artigo, consideraremos apenas algumas delas.

Agora vamos definir as classes para a criação de painéis de controle e diálogos. Eles representam uma biblioteca com código pronto para a criação ou desenvolvimento de painéis interativos ou aplicativos, incluindo indicadores e Expert Advisors. Isso pode ser encontrado na pasta de dados do terminal > pasta Include > pasta Controls. Existem classes auxiliares, básicas, simples e complexas que podem ser usadas para diferentes operações. Exemplos dessas classes:

Classe Nome do arquivo (pasta Controls) Descrição
CLabel Label.mqh Classe de controle simples para criar rótulos de texto simples e não editáveis
CButton Button.mqh Classe de controle simples para criar botões simples.
CEdit Edit.mqh Classe de controle simples que permite ao usuário inserir texto
CPanel Panel.mqh Classe de controle simples que permite combinar controles com outras funções semelhantes em um grupo
CCheckBox
CheckBox.mqh Classe de controle complexo para exibir uma caixa de seleção (true/false)
CSpinEdit
SpinEdit.mqh Classe de controle complexa que permite editar um valor inteiro.
CDialog
Dialog.mqh Classe de controle simples que permite combinar controles com outras funções diferentes em um grupo

Como vemos, podemos usar as classes para executar muitas tarefas que de outra forma levariam muito tempo e esforço. Na próxima seção, vamos comparar a criação de um aplicativo do zero e usando classes.


Painel gráfico simples

Vamos criar um simples painel de negociação para abrir ordens de compra e venda após definir o tamanho do lote. Primeiro, escreveremos o código do zero sem o uso de classes para treinar nossas habilidades de programação, e depois aplicaremos classes para ver o quanto isso é conveniente.

Painel gráfico sem classes

Os seguintes passos descrevem a criação de um painel de ordens simples para abrir ordens de compra e venda após a definição do tamanho do lote sem o uso de classes, exceto pela classe Trade:

Usaremos #include para incluir o arquivo Trade e criar um objeto trade, que será usado para as ordens abertas.

#include <Trade\Trade.mqh>
CTrade trade;

Criaremos uma função lógica trade para definir a variável do tipo de ordem ENUM_ORDER_TYPE e a variável double do tamanho do lote. Esses são os parâmetros da função criada. Para o corpo da função:

  • Criamos uma variável double para o preço.
  • Estabeleceremos uma condição para determinar o tipo de preço (ask ou bid) com base no tipo de ordem, usando uma condição if:
    • Se o tipo de ordem for compra (buy), o preço de abertura da ordem será Ask.
    • Se o tipo de ordem for venda (sell), o preço de abertura será Bid.
  • O resultado será a abertura de uma posição com o símbolo atual, tipo de ordem, tamanho do lote, tipo de preço, stop loss e take profit com valores zerados, e um comentário em branco.
bool openTrade(ENUM_ORDER_TYPE type, double vol)
  {
   double price;
   if(type==ORDER_TYPE_BUY)
   {
      price=SymbolInfoDouble(Symbol(),SYMBOL_ASK);
   }
   else price=SymbolInfoDouble(Symbol(),SYMBOL_BID);

   return trade.PositionOpen(Symbol(),type,vol,price,0,0,"");
  }

Definiremos a localização do painel escolhendo o canto superior esquerdo após criar a variável const ENUM_BASE_CORNER PanelLoc.

const ENUM_BASE_CORNER panelLoc=CORNER_LEFT_UPPER;

Definiremos xMargin e yMargin após a criação de variáveis inteiras constantes x e y.

const int xMargin=20;
const int yMargin=20;

Definiremos o espaço entre os elementos para x e y após a criação de outra variável inteira constante.

const int xSpace=10;
const int ySpace=10;

Definiremos o tamanho dos elementos, que são botões e texto, após a criação de quatro variáveis inteiras constantes btnWidth para a largura do botão, btnHeight para a altura do botão, txtWidth para a largura do texto e txtHeight para a altura do texto.

const int btnWidth=50;
const int btnHeight=20;
const int txtWidth=(btnWidth*2)+xSpace;
const int txtHeight=20;

Definiremos a localização do texto e dos botões; temos text x, text y, buy button x, buy button y, sell button x e sell y. Declararemos variáveis inteiras constantes para todas e atribuiremos valores a cada uma delas.

const int txtX=3;
const int txtY=yMargin+txtHeight;
const int buyX=3;
const int buyY=txtY+ySpace+btnHeight;
const int sellX=buyX+xSpace+btnWidth;
const int sellY=txtY+ySpace+btnHeight;

Atribuiremos nomes aos botões de compra e venda após a criação de variáveis constantes de string para eles.

const string txtName="txttVol";
const string buyName="buyBtn";
const string sellName="sellBtn";

Criaremos uma variável double para o tamanho do lote com um valor inicial.

double lotSize=0.01;

Na parte OnInit(), chamaremos a função createPanel(), que criaremos mais tarde.

   createPanel();

Na parte OnDeinit, removeremos os objetos pelos seus nomes.

   ObjectDelete(0,txtName);
   ObjectDelete(0,buyName);
   ObjectDelete(0,sellName);

Na área global, criaremos uma função que nos permitirá interagir com o painel, realizando os seguintes passos.

Usaremos a função OnChartEvent e seus parâmetros:

  • const int id - para identificador de evento
  • const long &lparam - para o parâmetro de evento long
  • const double &dparam - para o parâmetro de evento double
  • const string &sparam - para o parâmetro de evento string

Definiremos as condições para interação com o texto dos objetos (tamanho do lote), o botão de compra e venda.

//+------------------------------------------------------------------+
//| Interaction function                                             |
//+------------------------------------------------------------------+
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
  {
//--- If the event id is equal to the end of text editing in the panel and the string type event is equal to the text name
   if(id==CHARTEVENT_OBJECT_ENDEDIT && sparam==txtName)
     {
      //--- lotTxt string variable will be equal to the returned property value by using the ObjectGetString function
      string lotTxt=ObjectGetString(0, txtName, OBJPROP_TEXT);
      //--- call setLot function that we will create later with the lotTxt value
      setLot(lotTxt);
      //Setting the property value by using the ObjectSetString
      ObjectSetString(0, txtName, OBJPROP_TEXT, string(lotSize));
      //--- Use return
      return;
     }
//--- If the event id is equal to the object click to check if we click the buy button
   else
      if(id==CHARTEVENT_OBJECT_CLICK)
        {
         //We will check if the string param is equal to buyname
         if(sparam==buyName)
           {
            //--- Setting the value of the property by using the ObjectSetInteger
            ObjectSetInteger(0, buyName, OBJPROP_STATE, false);
            //Calling the created openTrade to open a buy order.
            openTrade(ORDER_TYPE_BUY, lotSize);
            //--- Use return
            return;
           }
         //--- If the event id is equal to the object click to check if we click the sell button
         //--- We will check if the string param is equal to sellname
         else
            if(sparam==sellName)
              {
               //--- Setting the value of the property by using the ObjectSetInteger
               ObjectSetInteger(0, sellName, OBJPROP_STATE, false);
               //Calling the created openTrade to open a sell order
               openTrade(ORDER_TYPE_SELL, lotSize);
               //--- Use return
               return;
              }
        }
  }

Crie a função void createPanel que chamamos anteriormente na parte OnInit(), executando os seguintes passos:

  • Excluímos os objetos txtName, buyName e SellName.
  • Chamamos a função EditCreate.
  • Chamamos a função ButtonCreate para o botão de compra.
  • Chamamos a função ButtonCreate para o botão de venda.
//+------------------------------------------------------------------+
//|createPanel function                                              |
//+------------------------------------------------------------------+
void createPanel()
  {
//--- Delete objects of txtName, buyName, and sellName
   ObjectDelete(0, txtName);
   ObjectDelete(0, buyName);
   ObjectDelete(0, sellName);
//--- calling the EditCreate function
   EditCreate(             // Parameters:
      0,                   // const long (chart_ID): to specify the chart's ID, we will use (0).
      txtName,             // const string (name): to specify the button name,  we will use (txtName)
      0,                   // const int (sub_window): to specify the subwindow index, we will use (0) for the main window
      txtX,                // const int (x): to specify the X coordinate, we will use (txtX)
      txtY,                // const int (y): to specify the Y coordinate, we will use (txtY)
      txtWidth,            // const int (width):to specify the button width, we will use (txtWidth)
      txtHeight,           // const int (height): to specify the button height, we will use (txtHeight)
      string(lotSize),     // const string (text): to specify the text, we will use (lotSize)
      "Arial",             // const string (font): to specify the font, we will use "Arial"
      10,                  // const int (font_size): to specify the font size, we will use (10)
      ALIGN_LEFT,          // const ENUM_ALIGN_MODE (align_mode): to specify the position of text, we will use (ALIGN_LEFT)
      false,               // const bool (read_only=false): to specify the ability to edit, we will be (false)
      panelLoc,            // const ENUM_BASE_CORNER (corner): to specify the chart corner for anchoring, we will call panelLoc function
      clrBlack,            // const color (clr): to specify the text color, we will specify clrBlack
      clrWhite,            // const color (back_clr): to specify the background color, we will specify clrWhite
      clrBlack,            // const color (border_clr): to specify the border color, we will specify clrBlack
      false,               // const bool (back=false): in the background, we will set false
      false,               // const bool (selection=false): highlight to move, we will set false
      false,               // const bool (hidden): hidden in the object list, we will set false
      0);                  // const long (z_order=0): priority for a mouse click, we will use (0)
//--- calling the ButtonCreate function for the buy
   ButtonCreate(           // Parameters:
      0,                   // const long (chart_ID): to specify the chart's ID, we will use (0)
      buyName,             // const string (name): to specify the button name, we will use (buyName) for the buy button
      0,                   // const int (sub_window): to specify the subwindow index, we will use (0) for the main window
      buyX,                // const int (x): to specify the X coordinate, we will use (buyX) for buy
      buyY,                // const int (y): to specify the Y coordinate, we will use (buyY) for buy
      btnWidth,            // const int (width): to specify the button width, we will use (btnWidth) for buy
      btnHeight,           // const int (height): to specify the button height, we will use (btnHeight) for buy
      panelLoc,            // const ENUM_BASE_CORNER (corner): to specify the chart corner for anchoring, we will call panelLoc function for buy button
      "Buy",               // const string (text): to specify the text, we will use ("Buy") for the buy button
      "Arial",             // const string (font): to specify the font, we will use "Arial"
      10,                  // const int (font_size): to specify the font size, we will use (10)
      clrBlack,            // const color (clr): to specify the text color, we will specify clrBlack
      clrGreen,            // const color (back_clr): to specify the background color, we will specify clrGreen for the buy button
      clrBlack,            // const color (border_clr): to specify the border color, we will specify clrBlack
      false,               // const bool (state): to specify if the object is pressed or released, we will specify false
      false,               // const bool (back=false): in the background, we will set false
      false,               // const bool (selection=false): highlight to move, we will set false
      false,               // const bool (hidden): hidden in the object list, we will set false
      0);                  // const long (z_order=0): priority for mouse click, we will use (0) for buy button
//--- calling the ButtonCreate function for the sell
   ButtonCreate(          //Parameters:
      0,                   //const long (chart_ID): to specify the chart's ID, we will use (0)
      sellName,            //const string (name): to specify the button name, we will use (sellName) for the sell button
      0,                   //const int (sub_window): to specify the subwindow index, we will use (0) for the main window
      sellX,               //const int (x): to specify the X coordinate, we will use (sellX) for sell
      sellY,               //const int (y): to specify the Y coordinate, we will use (sellY)
      btnWidth,            //const int (width): to specify the button width, we will use (btnWidth) for sell
      btnHeight,           //const int (height): to specify the button height, we will use (btnHeight) for sell
      panelLoc,            //const ENUM_BASE_CORNER (corner): to specify the chart corner for anchoring, we will call panelLoc function for sell button
      "Sell",              //const string (text): to specify the text, we will use ("Sell") for the sell button
      "Arial",             //const string (font): to specify the font, we will use "Arial"
      10,                  //const int (font_size): to specify the font size, we will use (10)
      clrBlack,            //const color (clr): to specify the text color, we will specify clrBlack
      clrRed,              //const color (back_clr): to specify the background color, we will specify clrRed for the sell button
      clrBlack,            //const color (border_clr): to specify the border color, we will specify clrBlack
      false,               //const bool (state): to specify if the object is pressed or released, we will specify false
      false,               //const bool (back=false): in the background, we will set false
      false,               //const bool (selection=false): highlight to move, we will set false
      false,               //const bool (hidden): hidden in the object list, we will set false
      0);                  //const long (z_order=0): priority for mouse click, we will use (0) for sell button
  }

    Criaremos a função void setLot com um parâmetro — lotTxt, que é usado para lotSize. O corpo da função é mostrado abaixo:

    • Criamos uma variável double newLot e a atribuímos a lotTxt depois de convertê-la de string para double usando a função StringToDouble.
    • Confirmamos se o valor de newLot é menor que 0. Imprimimos a mensagem "Invalid Volume Specified" (Volume inválido especificado) e, em seguida, usamos return.
    • Retornamos o valor de newLot que corresponde a lotSize.
    void setLot(string lotTxt)
      {
       double newLot=StringToDouble(lotTxt);
       if(newLot<0)
         {
          Print("Invaid Volume Specified");
          return;
         }
       lotSize=newLot;
      }

    A criação da função EditCreate consiste nos seguintes passos:

    //+------------------------------------------------------------------+
    //|EditCreate function                                               |
    //+------------------------------------------------------------------+
    bool EditCreate(const long             chart_ID=0,
                    const string           name="Edit",
                    const int              sub_window=0,
                    const int              x=0,
                    const int              y=0,
                    const int              width=50,
                    const int              height=18,
                    const string           text="Text",
                    const string           font="Arial",
                    const int              font_size=10,
                    const ENUM_ALIGN_MODE  align=ALIGN_CENTER,
                    const bool             read_only=false,
                    const ENUM_BASE_CORNER corner=CORNER_LEFT_UPPER,
                    const color            clr=clrBlack,
                    const color            back_clr=clrWhite,
                    const color            border_clr=clrNONE,
                    const bool             back=false,
                    const bool             selection=false,
                    const bool             hidden=true,
                    const long             z_order=0)
      {
    //--- Reset the error value by using ResetLastError()
       ResetLastError();
    //--- Create an edit field
       if(!ObjectCreate(chart_ID, name, OBJ_EDIT, sub_window, 0, 0))
         {
          Print(__FUNCTION__,
                ": failed to create \"Edit\" object! Error code = ", GetLastError());
          return(false);
         }
    //--- Setting the object coordinates x and y by using the ObjectSetInteger
       ObjectSetInteger(chart_ID, name, OBJPROP_XDISTANCE, x);
       ObjectSetInteger(chart_ID, name, OBJPROP_YDISTANCE, y);
    //--- Setting the object size by using the ObjectSetInteger function also
       ObjectSetInteger(chart_ID, name, OBJPROP_XSIZE, width);
       ObjectSetInteger(chart_ID, name, OBJPROP_YSIZE, height);
    //--- Setting the text by using ObjectSetString function
       ObjectSetString(chart_ID, name, OBJPROP_TEXT, text);
    //--- Setting the text font by using the ObjectSetString function also
       ObjectSetString(chart_ID, name, OBJPROP_FONT, font);
    //--- Setting the font size by using the ObjectSetInteger function
       ObjectSetInteger(chart_ID, name, OBJPROP_FONTSIZE, font_size);
    //--- Setting the type of text alignment in the object
       ObjectSetInteger(chart_ID, name, OBJPROP_ALIGN, align);
    //--- Setting the ability to edit, enable if it is (true) or cancel (false) if you need a read-only mode
       ObjectSetInteger(chart_ID, name, OBJPROP_READONLY, read_only);
    //--- Setting the chart's corner, relative to which object coordinates are defined to set the location of the object.
       ObjectSetInteger(chart_ID, name, OBJPROP_CORNER, corner);
    //--- Setting the text color
       ObjectSetInteger(chart_ID, name, OBJPROP_COLOR, clr);
    //--- Setting the background color
       ObjectSetInteger(chart_ID, name, OBJPROP_BGCOLOR, back_clr);
    //--- Setting the border color of the object
       ObjectSetInteger(chart_ID, name, OBJPROP_BORDER_COLOR, border_clr);
    //--- Displaying in the foreground by (false) or in the background by (true)
       ObjectSetInteger(chart_ID, name, OBJPROP_BACK, back);
    //--- Setting (true) to enable or (false) to disable the mode of moving the label by mouse
       ObjectSetInteger(chart_ID, name, OBJPROP_SELECTABLE, selection);
       ObjectSetInteger(chart_ID, name, OBJPROP_SELECTED, selection);
    //--- Setting (true) if you need hiding or (false) if you need the display of graphical object name in the object list
       ObjectSetInteger(chart_ID, name, OBJPROP_HIDDEN, hidden);
    //--- Setting the priority for receiving the event of a mouse click in the chart
       ObjectSetInteger(chart_ID, name, OBJPROP_ZORDER, z_order);
    //--- Returning (true) if successful execution
       return(true);
      }

    Criaremos a função ButtonCreate de maneira semelhante aos parâmetros da função EditCreate com uma pequena diferença:

    bool ButtonCreate(const long              chart_ID=0,               
                      const string            name="Button",            
                      const int               sub_window=0,             
                      const int               x=0,                      
                      const int               y=0,                      
                      const int               width=50,                 
                      const int               height=18,                
                      const ENUM_BASE_CORNER  corner=CORNER_LEFT_UPPER, 
                      const string            text="Button",            
                      const string            font="Arial",             
                      const int               font_size=10,             
                      const color             clr=clrBlack,             
                      const color             back_clr=C'236,233,216',  
                      const color             border_clr=clrNONE,       
                      const bool              state=false,              
                      const bool              back=false,               
                      const bool              selection=false,          
                      const bool              hidden=true,              
                      const long              z_order=0)                
      {
       ResetLastError();
       if(!ObjectCreate(chart_ID,name,OBJ_BUTTON,sub_window,0,0))
         {
          Print(__FUNCTION__,
                ": failed to create the button! Error code = ",GetLastError());
          return(false);
         }
       ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x);
       ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y);
       ObjectSetInteger(chart_ID,name,OBJPROP_XSIZE,width);
       ObjectSetInteger(chart_ID,name,OBJPROP_YSIZE,height);
       ObjectSetInteger(chart_ID,name,OBJPROP_CORNER,corner);
       ObjectSetString(chart_ID,name,OBJPROP_TEXT,text);
       ObjectSetString(chart_ID,name,OBJPROP_FONT,font);
       ObjectSetInteger(chart_ID,name,OBJPROP_FONTSIZE,font_size);
       ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
       ObjectSetInteger(chart_ID,name,OBJPROP_BGCOLOR,back_clr);
       ObjectSetInteger(chart_ID,name,OBJPROP_BORDER_COLOR,border_clr);
       ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
       ObjectSetInteger(chart_ID,name,OBJPROP_STATE,state);
       ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
       ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
       ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
       ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
       return(true);
      }

    Após a compilação e execução do código, o painel aparece da seguinte maneira:

    simpleOrderPanelWithoutClass

    Como podemos ver, no canto superior esquerdo temos um painel com o tamanho do lote e dois botões Buy e Sell e podemos especificar o tamanho do lote que precisamos e colocar um pedido pressionando o botão Buy ou Sell. Agora, para comparação, vamos criar o mesmo painel usando as classes Panels e Dialogs.


    Painel gráfico usando classes

    Execute os seguintes passos para criar o painel.

    Inclua os arquivos ou classes necessárias: Dialog, Button, Edit e Trade. Como sabemos, isso pode ser feito com o comando #include.

    #include <Controls\Dialog.mqh>
    #include <Controls\Button.mqh>
    #include <Controls\Edit.mqh>
    #include <Trade\Trade.mqh>

    Usaremos a macrosubstituição #define, que é uma diretiva de pré-processador para atribuir nomes mnemônicos às constantes:

    • PANEL_NAME "Order Panel"
    • PANEL_WIDTH 116
    • PANEL_HIEIGHT 100
    • ROW_HEIGHT 20
    • BUY_BTN_NAME "Buy BTN"
    • SELL_BTN_NAME "Sell BTN"
    • CLOSE_BTN_NAME "Close BTN"
    • EDIT_NAME "Lot Size"
    #define PANEL_NAME "Order Panel"
    #define PANEL_WIDTH 116
    #define PANEL_HIEIGHT 100
    #define ROW_HEIGHT 20
    #define BUY_BTN_NAME "Buy BTN"
    #define SELL_BTN_NAME "Sell BTN"
    #define CLOSE_BTN_NAME "Close BTN"
    #define EDIT_NAME "Lot Size"

    Criaremos objetos das classes

    CAppDialog panel;
    CButton buyBtn;
    CButton sellBtn;
    CButton closeBtn;
    CEdit lotSize;
    CTrade trade;

    Na parte OnInit(), precisamos criar um objeto de painel usando o objeto Panel.

    • const long chart - definimos 0 para que o painel seja exibido no gráfico principal.
    • const string name - definimos PANEL_NAME
    • const int subwin - definimos 0
    • const int x1 - definimos 10
    • const int y1 - definimos 20
    • const int x2 - usamos 10+PANEL_WIDTH+8
    • const int y2 - usamos 20+PANEL_HIEIGHT
    panel.Create(0,PANEL_NAME,0,10,20,10+PANEL_WIDTH+8,20+PANEL_HIEIGHT);

    Criamos e configuraremos os botões de compra e venda:

    • Criamos objetos usando object.Create.
    • Configuramos a largura dos objetos de compra e venda usando object.Width.
    • Definimos a altura dos objetos de compra e venda usando object.Height.
    • Ajustamos a cor de fundo dos objetos usando object.ColorBackground.
    • Definimos o texto dos objetos usando object.Text.
    • Ajustamos a fonte dos objetos usando object.Font.
    • Definimos o tamanho da fonte dos objetos usando object.FontSize.
    • Ajustamos a cor dos objetos usando object.Color.
    • Definimos a cor da borda dos objetos usando object.ColorBorder.
    • Posicionamos os objetos na tela.
    • Iniciamos a exibição da tela.
    int OnInit()
      {
       //buy button
       panel.Create(0,PANEL_NAME,0,10,20,10+PANEL_WIDTH+8,20+PANEL_HIEIGHT);
       buyBtn.Create(0,BUY_BTN_NAME,0,3,40,0,0);
       buyBtn.Width(50);
       buyBtn.Height(ROW_HEIGHT);
       buyBtn.ColorBackground(clrGreen);
       buyBtn.Text("Buy");
       buyBtn.Font("Arial");
       buyBtn.FontSize(10);
       buyBtn.Color(clrBlack);
       buyBtn.ColorBorder(clrBlack);   
       panel.Add(buyBtn);
       //sell button
       sellBtn.Create(0,SELL_BTN_NAME,0,63,40,0,0);
       sellBtn.Width(50);
       sellBtn.Height(ROW_HEIGHT);
       sellBtn.ColorBackground(clrRed);
       sellBtn.Text("Sell");
       sellBtn.Font("Arial");
       sellBtn.FontSize(10);
       sellBtn.Color(clrBlack);
       sellBtn.ColorBorder(clrBlack);
       panel.Add(sellBtn);
       //lotSize
       lotSize.Create(0,EDIT_NAME,0,4,10,0,0);
       lotSize.Width(108);
       lotSize.Height(ROW_HEIGHT);
       lotSize.Text("0.01");
       lotSize.Font("Arial");
       lotSize.FontSize(10);
       lotSize.ColorBackground(clrWhite);
       lotSize.Color(clrBlack);
       lotSize.ColorBorder(clrBlack);
       panel.Add(lotSize);
       //run the panel
       panel.Run();
       return(INIT_SUCCEEDED);
      }

    Na parte OnDeinit(const int Reason) usaremos Destroy como uma função de deinitialization, conforme mostrado abaixo.

    void OnDeinit(const int reason)
      {
       panel.Destroy();
      }

    Incluiremos interação com o painel usando a função OnChartEvent e estabeleceremos condições para o comportamento dos botões de compra e venda:

    • Criamos a função OnChartEvent.
    • O corpo da função será o seguinte:
      • Usamos object.ChartEvent com os parâmetros id para o evento, lparam para o tipo de evento long, dparam para o tipo double e sparam para o tipo string.
      • Verificamos se o identificador corresponde ao clique no gráfico (Chart Click).
      • Verificamos se sparam é igual aos nomes buyBtn ou SellBtn.
      • Criamos uma variável double para o tamanho do lote e atribuiremos a ela o valor StringToDouble (tamanho do lote).
      • Abrimos uma ordem de compra ou venda, dependendo do tipo de evento, usando o valor do tamanho do lote.
    void  OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
      {
       panel.ChartEvent(id,lparam,dparam,sparam);
       if(id==CHARTEVENT_OBJECT_CLICK)
         {
          if(sparam==buyBtn.Name())
            {
             double lot=StringToDouble(lotSize.Text());
             trade.Buy(lot);
            }
          else
             if(sparam==sellBtn.Name())
               {
                double lot=StringToDouble(lotSize.Text());
                trade.Sell(lot);
               }
         }
      }

    Após a compilação e execução do código, veremos o painel no gráfico:

    simpleOrderPanelWithClass

    No canto superior esquerdo, o painel com o tamanho do lote e os objetos de compra e venda são exibidos. Podemos editar o tamanho do lote e abrir ordens.

    Após o trabalho realizado, vemos que criar um painel usando classes é mais simples e conveniente. Assim, as classes são muito úteis e nos economizam muito tempo. No entanto, se você é um programador iniciante, tente estudar e entender como elas são criadas. É um ótimo modo de melhorar suas habilidades de programação.

    Você pode aperfeiçoar o aplicativo criado, adicionando mais funcionalidades.


    Conclusão

    As classes são uma ferramenta valiosa e útil em geral e, em particular, na criação de painéis que podem ser usados no MetaTrader 5. Elas permitem que os traders se concentrem mais na negociação. Aprendemos o que são painéis e exploramos seus tipos, bem como criamos um painel simples de duas maneiras, constatando o quanto o uso das classes Panels e Dialog acelera e facilita o trabalho.

    Espero que o artigo seja útil para você, e que a informação apresentada seja fácil de entender e implementar. Também espero que você tenha adquirido mais conhecimento sobre o desenvolvimento de aplicações, incluindo painéis, que podem ser úteis para a sua negociação.

    Para aprender mais sobre classes e objetos, recomendo que leia um dos meus artigos anteriores "Programação Orientada a Objetos (POO) em MQL5". Se você gostou do artigo e o achou útil, leia meus artigos anteriores para descobrir como desenvolver sistemas de negociação baseados em vários indicadores técnicos populares.

    Traduzido do Inglês pela MetaQuotes Ltd.
    Artigo original: https://www.mql5.com/en/articles/12903

    Redes neurais de maneira fácil (Parte 49): Soft Actor-Critic (SAC) Redes neurais de maneira fácil (Parte 49): Soft Actor-Critic (SAC)
    Continuamos nossa exploração dos algoritmos de aprendizado por reforço na resolução de problemas em espaços de ação contínua. Neste artigo, apresento o algoritmo Soft Actor-Critic (SAC). A principal vantagem do SAC está em sua capacidade de encontrar políticas ótimas que não apenas maximizam a recompensa esperada, mas também têm a máxima entropia (diversidade) de ações.
    Pode o Heiken-Ashi em combinação com médias móveis oferecer bons sinais? Pode o Heiken-Ashi em combinação com médias móveis oferecer bons sinais?
    Combinar estratégias pode aumentar a eficácia da negociação. Podemos combinar indicadores e padrões para obter confirmações adicionais. As médias móveis nos ajudam a confirmar a tendência e a segui-la. Este é o indicador técnico mais conhecido, o que se explica pela sua simplicidade e eficácia comprovada na análise.
    Desenvolvendo um sistema de Replay (Parte 35): Ajeitando as coisas (I) Desenvolvendo um sistema de Replay (Parte 35): Ajeitando as coisas (I)
    Temos que corrigir algumas coisas antes de realmente poder continuar. Mas não se trata necessariamente de uma correção e sim de um aperfeiçoamento na forma de gerir e utilizar classe. O motivo é que existem falhas ocorrendo por conta de algum tipo de interação dentro do sistema. Apesar das tentativas de tentar compreender o motivo de algumas das falhas, para assim sana-las. Todas foram frustradas, já que não fazia o mínimo sentido de algumas delas estarem ocorrendo. Quando fazemos uso de ponteiros ou recursão em C / C++, e o programa começa a apresentar falhas.
    Melhore seus gráficos de negociação com uma GUI interativa baseada em MQL5 (Parte I): GUI móvel (II) Melhore seus gráficos de negociação com uma GUI interativa baseada em MQL5 (Parte I): GUI móvel (II)
    Libere todo o poder da representação de dados dinâmicos em suas estratégias de negociação ou utilitários com o nosso guia detalhado para desenvolver uma GUI móvel em MQL5. Mergulhe nos princípios fundamentais da programação orientada a objetos e aprenda a desenvolver e usar de forma fácil e eficiente uma ou mais GUIs móveis em um único gráfico.