English Русский 中文 Español Deutsch 日本語 한국어 Français Italiano Türkçe
Guia prático do MQL5: obter propriedades de posição

Guia prático do MQL5: obter propriedades de posição

MetaTrader 5Exemplos | 20 março 2014, 13:50
7 135 0
Anatoli Kazharski
Anatoli Kazharski

Introdução

O artigo anterior, chamado "Livro de receitas MQL5: Utilização de diferentes modos de impressão" mostrou como podemos escrever um script rapidamente e imprimir as informações requeridas utilizando três modos diferentes. Agora vamos criar um script que obtém e exibe todas as propriedades de posição para o usuário.

Precisamos implementá-lo de forma que permita que o usuário selecione a opção adequada nos parâmetros externos do script, da seguinte forma: ou apenas obter as propriedades de posição de um símbolo (atual) ou ser executado para todas as posições abertas (se houver alguma), uma a uma, em todos os símbolos. Desta vez, visualizaremos as informações requeridas na própria caixa de diálogo, o que é muito conveniente e alguns de vocês podem achar este método mais útil.


Escrever um script

O começo do script é mais ou menos igual ao do artigo anterior (veja o código abaixo). Iniciamos com as propriedades do programa. Elas são seguidas pela linha com a diretiva #define e então atribuímos o nome do programa à variável SCRIPT_NAME utilizando a função MQLInfoString() e a constante MQL_PROGRAM_NAME que ela especifica. Mais informações sobre todos os valores possíveis da função MQLInfoString() podem ser encontradas na Referência MQL5.

Continuamos com a enumeração dos modos. Se você escrever um comentário para cada identificador, o texto desse comentário será exibido na lista suspensa nos parâmetros externos. Implementaremos duas opções:

  • Símbolo atual - para exibir apenas as propriedades de posição para os símbolos atuais, e
  • Todos os símbolos - para exibir propriedades de posição para todos os símbolos.

Haverá apenas um parâmetro externo (modo) a ser utilizado para selecionar o modo apropriado. O comentário que segue o parâmetro externo também será exibido na janela de parâmetros externos. Isso permitirá criarmos nomes de parâmetros mais significativos. Ao mesmo tempo, nomes de variáveis mais curtos seriam mais convenientes em termos de código.

#property copyright   "Copyright 2012, http://tol64.blogspot.com"
#property link        "http://tol64.blogspot.com"
#property description "email: hello.tol64@gmail.com"
#property version     "1.0"
#property script_show_inputs
//---
#define SCRIPT_NAME MQLInfoString(MQL_PROGRAM_NAME) // Script name
//---
// ENUMERATION OF MODES
enum ENUM_SYMBOLS_MODE
  {
   CURRENT_SYMBOL =0,                     // Current symbol
   ALL_SYMBOLS    =1                      // All symbols
  };
//---
// INPUT PARAMETERS
input ENUM_SYMBOLS_MODE mode=CURRENT_SYMBOL;     // Mode

O código continua com variáveis globais. Para que as variáveis globais possam ser acessadas de qualquer parte do script, elas devem ser colocadas fora das funções (geralmente logo no início do programa).

// GLOBAL VARIABLES
long                 pos_magic=0;         // Magic number
string               pos_symbol="";       // Symbol
string               pos_comment="";      // Comment
double               pos_swap=0.0;        // Swap
double               pos_commission=0.0;  // Commission
double               pos_price=0.0;       // Current price of the position
double               pos_cprice=0.0;      // Current price of the position
double               pos_profit=0.0;      // Profit/Loss of the position
double               pos_volume=0.0;      // Position volume
double               pos_sl=0.0;          // Stop Loss of the position
double               pos_tp=0.0;          // Take Profit of the position
datetime             pos_time=NULL;       // Position opening time
long                 pos_id=0;            // Position identifier
ENUM_POSITION_TYPE   pos_type=NULL;       // Position type
//---

Na função principal do programa, chamaremos apenas uma função definida pelo usuário, PrintPositionProperties(), que realizará todas as operações requeridas:

//+------------------------------------------------------------------+
//| MAIN FUNCTION                                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   PrintPositionProperties();
  }

Vamos observar agora, passo a passo, a estrutura da função PrintPositionProperties() definida pelo usuário. Primeiramente, criaremos a base para o nosso trabalho futuro. Ela é muito simples e, quando implementada, tem o seguinte aspecto:

//+------------------------------------------------------------------+
//| OPENING A DIALOG BOX WITH SYMBOL DATA                            |
//+------------------------------------------------------------------+
void PrintPositionProperties()
  {
   int err=0; // Variable for handling errors
//---
// If you need to get position properties on the current symbol only
   if(mode==CURRENT_SYMBOL)
     {
 
     }
//---
// If you need to get position properties on all symbols
   if(mode==ALL_SYMBOLS)
     {
 
     }
  }

Temos apenas dois ramos e uma variável local err que é responsável por gerenciar erros e é declarada no início da função. Agora precisamos escrever cenários de caso de uso para cada uma das opções. Vamos iniciar com a primeira, ou seja "Se você precisa obter apenas as propriedades de posição para o símbolo atual".

Isso é muito simples. Antes de mais nada, precisamos verificar se há uma posição no símbolo atual. Isso pode ser feito pela função PositionSelect() disponível em MQL5, a qual utiliza o nome do símbolo como parâmetro único. Para transferir o nome do símbolo atual, precisamos utilizar ou a função Symbol() ou a variável _Symbol predefinida que já contém o nome do símbolo atual. A função PositionSelect() retornará um resultado positivo, se houver uma posição naquele símbolo, ou um resultado negativo, se não houver uma posição ou se ocorreu um erro.

O código com comentários detalhados para a primeira opção é fornecido abaixo:

//---
      // If a position exists, then...
      if(PositionSelect(_Symbol))
        {
         // ...get its properties
         GetPositionProperties();
         //---
         // Open a dialog box to display all the data we obtained
         MessageBox("Symbol        : "+pos_symbol+"\n"+
                    "Comment       : "+pos_comment+"\n"+
                    "Magic Number  : "+IntegerToString(pos_magic)+"\n"+
                    "Price Open    : "+DoubleToString(pos_price,_Digits)+"\n"+
                    "Current Price : "+DoubleToString(pos_cprice,_Digits)+"\n"+
                    "Stop Loss     : "+DoubleToString(pos_sl,_Digits)+"\n"+
                    "Take Profit   : "+DoubleToString(pos_tp,_Digits)+"\n"+
                    "Type          : "+PositionTypeToString(pos_type)+"\n"+
                    "Volume        : "+DoubleToString(pos_volume,2)+"\n"+
                    "Commission    : "+DoubleToString(pos_commission,2)+"\n"+
                    "Swap          : "+DoubleToString(pos_swap,2)+"\n"+
                    "Profit        : "+DoubleToString(pos_profit,2)+"\n"+
                    "Time          : "+TimeToString(pos_time)+"\n"+
                    "Identifier    : "+IntegerToString(pos_id)+"",
                    //---
                    "Message Box",MB_ICONASTERISK);
         //---
         return;
        }
      // If there is no position or an error has occurred, report it
      else
        {
         err=GetLastError(); // Get the code of the last registered error
         //---
         if(err>0) // If there is an error
           {
            // Print the relevant message
            MessageBox("Error ("+IntegerToString(err)+") when selecting a position ("+_Symbol+") !\n\n"+
                       "It is possible that there is no position on this symbol. If this is not the case, please try again.",
                       "Error",
                       MB_ICONWARNING);
            //---
            return; // Exit the function
           }
        }
      //---

No código acima, podemos observar mais duas funções definidas pelo usuário - GetPositionProperties() e PositionTypeToString(). Porque teremos que obter propriedades de posição em diversos pontos ao longo do programa, será bom criar uma função separada para reduzir a quantidade de códigos e facilitar a leitura. O código dessa função segue abaixo. Certifique-se de verificar a Referência MQL5 para obter informações adicionais sobre as funções e identificadores MQL5 utilizados em GetPositionProperties().

//+------------------------------------------------------------------+
//| GETTING SYMBOL PROPERTIES                                        |
//+------------------------------------------------------------------+
void GetPositionProperties()
  {
   pos_symbol     =PositionGetString(POSITION_SYMBOL);
   pos_comment    =PositionGetString(POSITION_COMMENT);
   pos_magic      =PositionGetInteger(POSITION_MAGIC);
   pos_price      =PositionGetDouble(POSITION_PRICE_OPEN);
   pos_cprice     =PositionGetDouble(POSITION_PRICE_CURRENT);
   pos_sl         =PositionGetDouble(POSITION_SL);
   pos_tp         =PositionGetDouble(POSITION_TP);
   pos_type       =(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
   pos_volume     =PositionGetDouble(POSITION_VOLUME);
   pos_commission =PositionGetDouble(POSITION_COMMISSION);
   pos_swap       =PositionGetDouble(POSITION_SWAP);
   pos_profit     =PositionGetDouble(POSITION_PROFIT);
   pos_time       =(datetime)PositionGetInteger(POSITION_TIME);
   pos_id         =PositionGetInteger(POSITION_IDENTIFIER);
  }

A função PositionTypeToString() definida pelo usuário converte o tipo de posição retornado como um inteiro para uma string para formato de leitura, conforme exibido no código abaixo:

//+------------------------------------------------------------------+
//| CONVERTING POSITION TYPE TO A STRING                             |
//+------------------------------------------------------------------+
string PositionTypeToString(int position_type)
  {
   string str="";
//---
   if(position_type==0) { str="buy";  }
   if(position_type==1) { str="sell"; }
//---
   return(str);
  }

Assim, o código da primeira posição através do qual podemos visualizar as propriedades de posição apenas para o símbolo atual está pronto. Se você seguiu todos os passos descritos no artigo, ele pode ser inclusive testado agora mesmo. Abra uma posição no MetaTrader 5 utilizando as ferramentas padrão. Para isso, aperte F9 e a janela de Ordem abrirá e nela você poderá encontrar todas as opções necessárias para configurar as propriedades da posição antes de abrí-la:

Figura 1. A janela de Ordem no terminal do cliente MetaTrader 5.

Figura 1. A janela de Ordem no terminal do cliente MetaTrader 5

Quando todas as propriedades forem configuradas, selecione Vender ou Comprar e execute o script com um clique duplo ou arrastando ele sobre o gráfico. Uma janela do script aparecerá. O valor requerido (Símbolo atual) do parâmetro Modo já foi configurado de forma automática. Um clique sobre o botão OK abrirá uma caixa de diálogo exibindo todas as propriedades de posição para o símbolo atual:

Figura 2. Caixa de diálogo com as propriedades de posição para o símbolo atual.

Figura 2. Caixa de diálogo com as propriedades de posição para o símbolo atual

Do contrário, se não houver posição no símbolo atual, aparecerá uma caixa de alerta:

Figura 3. Caixa de alerta.

Figura 3. Caixa de alerta

Tudo parece estar funcionando como planejado e implementado no código.

Agora vamos analisar o código de programa que será usado se você escolher visualizar todas as propriedades de posição aberta. O código com comentários detalhados é exibido abaixo:

//---
      int digits=0; // Number of decimal places
      int mb_res=-1; // Variable with the option selected in the dialog box
      int pos_total=PositionsTotal(); // Number of open positions in the terminal
      //---
      // View properties of all positions in a loop one by one
      for(int i=0; i<pos_total; i++)
        {
         ResetLastError(); // Reset the last error
         //---
         pos_symbol=PositionGetSymbol(i); // Get the symbol name
         digits=(int)SymbolInfoInteger(pos_symbol,SYMBOL_DIGITS); // Get the number of digits in the price
         //---
         // If a position on this symbol exists, then...
         if(PositionSelect(pos_symbol))
           {
            // ...get its properties
            GetPositionProperties();
            //---
            // Open a dialog box to display all position properties obtained
            mb_res=MessageBox("Total Positions/Current: "+IntegerToString(pos_total)+"/"+IntegerToString(i+1)+"\n"+
                              "---------------------------------\n"+
                              "Symbol: "        +pos_symbol+"\n"+
                              "Comment: "       +pos_comment+"\n"+
                              "Magic Number: "  +IntegerToString(pos_magic)+"\n"+
                              "Price Open: "    +DoubleToString(pos_price,digits)+"\n"+
                              "Current Price: " +DoubleToString(pos_cprice,digits)+"\n"+
                              "Stop Loss: "     +DoubleToString(pos_sl,digits)+"\n"+
                              "Take Profit: "   +DoubleToString(pos_tp,digits)+"\n"+
                              "Type: "          +PositionTypeToString(pos_type)+"\n"+
                              "Volume: "        +DoubleToString(pos_volume,2)+"\n"+
                              "Commission: "    +DoubleToString(pos_commission,2)+"\n"+
                              "Swap: "          +DoubleToString(pos_swap,2)+"\n"+
                              "Profit: "        +DoubleToString(pos_profit,2)+"\n"+
                              "Time: "          +TimeToString(pos_time)+"\n"+
                              "Identifier: "    +IntegerToString(pos_id)+"",
                              //---
                              "Message Box",MB_CANCELTRYCONTINUE|MB_ICONASTERISK);
            //---
            if(mb_res==IDCANCEL) // If you have clicked Cancel or Close
              { Print("The program ("+SCRIPT_NAME+") has been terminated by the user!"); return; } // Exit the function
            //---
            // If you have clicked Retry   
            if(mb_res==IDTRYAGAIN) { i--; } // Reset the counter to retry
           }
         else // If there is no position or an error has occurred, report it
           {
            err=GetLastError(); // Get the code of the last registered error
            //---
            if(err>0) // If there is an error
              {
               // Print the relevant message
               MessageBox("Error ("+IntegerToString(err)+") when selecting a position ("+pos_symbol+") !\n\n"+
                          "It is possible that there is no position on this symbol. If this is not the case, please try again.",
                          "Error",
                          MB_ICONWARNING);
              }
           }
        }
      //---

Agora apenas precisamos testar essa opção. Vamos, por exemplo, abrir posições em dois símbolos (AUDUSD e EURUSD). Uma vez que executarmos o script, selecione o modo Todos os símbolos na lista suspensa nos parâmetros externos e clique em OK. Uma caixa de diálogo aparecerá, conforme exibido abaixo:

Figura 4. Caixa de diálogo com as propriedades de posição para a segunda opção.

Figura 4. Caixa de diálogo com as propriedades de posição para a segunda opção


Conclusão

Como você pode ver na figura acima, há três botões na caixa de diálogo. Se você clicar em Tentar novamente, o contador cíclico será reiniciado e as propriedades de posição para o símbolo exibido atualmente na caixa de diálogo serão atualizadas. Se você clicar em Continuar, o programa passará ao próximo símbolo. O botão Cancelar serve para encerrar o programa.

Deve-se destacar também que a primeira linha acima da lista de propriedades de posição contém informações sobre o número total de posições abertas (Total de Posições) e número atual do contador de posições (Atual).

Isso é praticamente tudo. Sinta-se livre para fazer o download do arquivo do código-fonte anexo abaixo, o qual precisará ser compilado no MetaEditor.

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

Arquivos anexados |
Guia prático do MQL5: Propriedades de posição no painel de informações personalizado Guia prático do MQL5: Propriedades de posição no painel de informações personalizado
Agora criaremos um Consultor Especialista simples que obterá propriedades de posição no símbolo atual e as exibirá no painel personalizado de informações durante as negociações manuais. O painel de informações será criado usando objetos gráficos e a informação exibida será atualizada a cada ponto. Isto será muito mais conveniente do que ter que executar manualmente todas as vezes o script descrito no artigo anterior da série, chamado "Guia prático do MQL5: Obter propriedades de posição".
Guia prático do MQL5: utilização de diferentes modos de impressão Guia prático do MQL5: utilização de diferentes modos de impressão
Este é o primeiro artigo da série Livro de receitas MQL5. Vou iniciar com exemplos simples para permitir que aqueles que estejam dando os seus primeiros passos em programação se familiarizem gradativamente com a nova linguagem. Eu me lembro que as minhas primeiras tentativas de projetar e programar sistemas de negociação foram muito difíceis, visto que era a primeira linguagem de programação da minha vida. Entretanto, no fim das contas foi mais fácil do que eu pensava e apenas demorou alguns meses até que eu pudesse desenvolver um programa razoavelmente complexo.
Guia prático do MQL5: Analisando propriedades de posição no testador de estratégias do MetaTrader 5 Guia prático do MQL5: Analisando propriedades de posição no testador de estratégias do MetaTrader 5
Apresentaremos uma versão modificada do Expert Advisor a partir fo artigo anterior "Guia prático do MQL5: Propriedades de posição no painel de informações personalizado". Alguns dos assuntos que abordaremos incluem a obtenção de dados das barras, verificação de eventos de uma nova barra no símbolo atual, inclusão de uma classe de negociação da Biblioteca padrão a um arquivo, criação de uma função para buscar por sinais de negociação e uma função para execução das operações de negócio, assim como determinar os eventos de negócio na função OnTrade().
O MQL5 Market está fazendo um ano de idade O MQL5 Market está fazendo um ano de idade
Já passou um ano desde o lançamento das vendas no Mercado MQL5. Foi um ano de trabalho duro, que transformou o novo serviço na maior loja de robôs de negociação e de indicadores técnicos para a plataforma MetaTrader 5.