Especialistas: Programação no MQL5 para traders: códigos-fonte retirados do livro. Parte 6

 

Programação no MQL5 para traders: códigos-fonte retirados do livro. Parte 6:

Na quarta parte do livro "Automação de negociações", do livro "Programação no MQL5 para traders", estudaremos um componente fundamental da linguagem MQL5 - a automação de negociações. Vamos começar descrevendo as entidades básicas, como especificações de instrumentos financeiros e configurações de contas de negociação, que são necessárias para criar Expert Advisors certos.

Programação no MQL5 para traders: códigos-fonte retirados do livro. Parte 6

Autor: MetaQuotes

 
Excelente
 

Use obotão CODE (Alt-S) ao inserir o código.

Um moderador formatou o código colado incorretamente. Normalmente, esse código é removido.

@StanislavKorotky Por favor, você pode me ajudar a analisar esse erro? Acredito que ele tenha começado depois das atualizações do MT5, porque eu sabia que o código funcionava nos meses anteriores sem nenhuma modificação.

parameter convertion type 'long[][2]' to 'string[][] &' is not allowed SymbolFilter.mqh 199 20

O tipo de conversão de parâmetro 'double[][2]' para 'string[][] &' não é permitido TradeFilter.mqh 332 20
Não é permitida a conversão do parâmetro 'long[][2]' para 'string[][] &' TradeFilter.mqh 163 17


Acredito que o código abaixo ajudará a replicar o problema:

void printSymbols() {
   SymbolFilter f;                      // objeto de filtro
   string symbols[];                    // matriz para nomes 
   long permissions[][2];               // matriz para dados (valores de propriedade)
   
   // lista de propriedades de símbolo solicitadas
   ENUM_SYMBOL_INFO_INTEGER modes[] = {
      SYMBOL_TRADE_MODE,
      SYMBOL_ORDER_MODE
   };
   
   // aplicar o filtro, obter matrizes com resultados
   f.let(SYMBOL_VISIBLE, true).select(true, modes, symbols, permissions);
   
   const int n = ArraySize(symbols);
   PrintFormat("===== Trade permissions for the symbols (%d) ===== ", n);
   for(int i = 0; i < n; ++i)  {
      Print(symbols[i] + ":");
      for(int j = 0; j < ArraySize(modes); ++j) {
         // exibir descrições de bits e números "como estão"
         PrintFormat("  %s (%d)",
            SymbolMonitor::stringify(permissions[i][j], modes[j]),
            permissions[i][j]);
      }
   }
}

Stanislav Korotky - marketeer - Trader's profile
Stanislav Korotky - marketeer - Trader's profile
  • 2025.07.05
  • www.mql5.com
Trader's profile
 
pauldic #:
@StanislavKorotky Por favor, você pode ajudar a analisar esse erro? Acredito que ele começou após as atualizações do MT5, pois eu sabia que o código funcionava nos meses anteriores sem nenhuma modificação.

parameter convertion type 'long[][2]' to 'string[][] &' is not allowed SymbolFilter.mqh 199 20
O tipo de conversão de parâmetro 'double[][2]' para 'string[][] &' não é permitido TradeFilter.mqh 332 20
Não é permitida a conversão do parâmetro 'long[][2]' para 'string[][] &' TradeFilter.mqh 163 17


Acredito que o código abaixo ajudará a replicar o problema:


Veja as linhas:

   // precisamos dessa sobrecarga porque o ArraySort incorporado
   // não oferece suporte a matrizes de cadeias de caracteres
   void ArraySort(string &s[][]) const
   {
      QuickSortTm<string> qt(s);
   }

nos arquivos de cabeçalho SymbolFilter.mqh e TradeFilter.mqh, e adicione a seguinte sobrecarga de método ao lado delas:

   // precisamos dessa sobrecarga porque o ArraySort incorporado
   // não oferece suporte a matrizes de cadeias de caracteres
   void ArraySort(string &s[][]) const
   {
      QuickSortTm<string> qt(s);
   }
   
   template<typename T>
   void ArraySort(T &s[][]) const
   {
      ::ArraySort(s);
   }
PS. Essa pergunta parece não ter relação com o artigo.
 
Stanislav Korotky #:

Encontre as linhas:

nos arquivos de cabeçalho SymbolFilter.mqh e TradeFilter.mqh, e adicione a seguinte sobrecarga de método ao lado deles:

PS. Essa pergunta parece não ter relação com o artigo.

Obrigado por sua resposta rápida, mas depois de fazer a atualização, recebi mais erros:

parameter convertion type 'double[][2]' to 'string[][] &' is not allowed                TradeFilter.mqh 338     20
cannot convert parameter 'double[][2]' to 'OrderMonitor&[][]'                   TradeFilter.mqh 338     20
parameter convertion type 'double[][2]' to 'string[][] &' is not allowed                TradeFilter.mqh 338     20
cannot convert parameter 'double[][2]' to 'PositionMonitor&[][]'                        TradeFilter.mqh 338     20
parameter convertion type 'long[][2]' to 'string[][] &' is not allowed          TradeFilter.mqh 163     17
cannot convert parameter 'long[][2]' to 'OrderMonitor&[][]'                             TradeFilter.mqh 163     17
parameter convertion type 'long[][2]' to 'string[][] &' is not allowed          TradeFilter.mqh 163     17
cannot convert parameter 'long[][2]' to 'PositionMonitor&[][]'                  TradeFilter.mqh 163     17
etc..

Percebi que chamar o QuickSortTm genérico diretamente em vez do ArraySort corrige temporariamente o problema, embora eu não acredite que essa seja a solução ideal

QuickSortTm<V> qt(array);
//ArraySort(array);
 
pauldic #:

Obrigado por sua resposta rápida, mas depois de fazer a atualização, recebi mais erros dizendo:

Isso é estranho, depois da correção sugerida acima, compilei e executei esse script /MQL5/Scripts/MQL5Book/p6/SymbolFilterTradeMode.mq5 com êxito na compilação 5346. Você não mostrou seu código-fonte.
 
Stanislav Korotky #:
Isso é estranho, depois da correção sugerida acima, compilei e executei esse script /MQL5/Scripts/MQL5Book/p6/SymbolFilterTradeMode.mq5 com êxito na compilação 5346. Você não mostrou seu código-fonte.
Perdoe-me por ter omitido meu código-fonte, então reverti para a correção sugerida para que eu possa obter os erros novamente e parece que essas partes do meu código são as partes que levam ao erro de acordo com o registro
Estou executando a versão 5 build 5327

void printActiveOrders() {
   
   OrderFilter filter;
   ENUM_ORDER_PROPERTY_DOUBLE properties[] = {ORDER_VOLUME_INITIAL, ORDER_PRICE_OPEN, ORDER_SL, ORDER_TP};
   double d[][4];
   ENUM_ORDER_TYPE types[];
   ulong tickets[], magics[];
   string symbols[], comments[];
   
   filter.select(properties, tickets, d);
   filter.select(ORDER_SYMBOL, tickets, symbols);
   filter.select(ORDER_COMMENT, tickets, comments);
   filter.select(ORDER_TYPE, tickets, types);
   filter.select(ORDER_MAGIC, tickets, magics);
   
   Print("Orders ..................  ", ArraySize(tickets));
   for (int i=0; i < ArraySize(tickets); i++) {
      Print(tickets[i], "\t", magics[i], "\t", symbols[i], "\t", EnumToString(types[i]), " \t", NormalizeDouble(d[i][0],3), "\t", d[i][1], " \t ",  d[i][2], " \t", d[i][3], "\t", comments[i]);
   }
}


void printPositions() {
   PositionFilter filter;
   
   ENUM_POSITION_PROPERTY_DOUBLE properties[] = {POSITION_PRICE_OPEN, POSITION_VOLUME, POSITION_SL, POSITION_TP, POSITION_PROFIT, POSITION_SWAP};
   
   ENUM_POSITION_TYPE types[];
   double d[][6];
   ulong tickets[], extIds[];
   string symbols[], comments[];
   
   filter.let(POSITION_MAGIC, sets.MagicNumber).select(properties, tickets, d);
   filter.select(POSITION_SYMBOL, tickets, symbols);
   filter.select(POSITION_COMMENT, tickets, comments);
   filter.select(POSITION_TYPE, tickets, types);
   filter.select(POSITION_IDENTIFIER, tickets, extIds);

   Print("Tickets\t  Parent Id\tSymbols \t Trade Type \t\t\t\t\t\tEntry \t Lots \t\t SL  \t\t\t TP \t\t\t\t Profit \tSwat \t\tComments");
   for ( int i =0; i < ArraySize(tickets); i++) {
      Print(tickets[i], "\t", extIds[i] == 0 ? "\t\t\t\t\t\t\t\t\t" : (string)extIds[i], "\t", symbols[i], "\t", EnumToString(types[i]), " \t", (string)NormalizeDouble(d[i][0],3), "\t", d[i][1], " \t ",  d[i][2], " \t", d[i][3], " \t", d[i][4], " \t ", d[i][5], "\t", comments[i]);
      //Print(tickets[i], "\t", extIds[i] == 0 ? "\t\t\t\t\t\t\t\t\t" : extIds[i], "\t", symbols[i], "\t", EnumToString(types[i]), " \t", NormalizeDouble(d[i][0],3), "\t", d[i][1], " \t ",  d[i][2], " \t", d[i][3], " \t", d[i][4], " \t ", d[i][5]);
   }
}


Além disso, frequentemente vejo estas mensagens:

This single line message always shows whenever I attach my EA to a chart:
Unresolved int value as enum: 8 for MonitorInterface<ENUM_POSITION_PROPERTY_INTEGER,ENUM_POSITION_PROPERTY_DOUBLE,ENUM_POSITION_PROPERTY_STRING>::TradeState


While these ones below shows when it is detached

2025.10.17 19:30:01.347 Deriv Trader (Volatility 10 (1 s) Index.0,M15)   8 leaked strings left
2025.10.17 19:30:01.347 Deriv Trader (Volatility 10 (1 s) Index.0,M15)   2 undeleted dynamic objects found:
2025.10.17 19:30:01.347 Deriv Trader (Volatility 10 (1 s) Index.0,M15)      1 object of class 'WebSocketConnectionHybi'
2025.10.17 19:30:01.347 Deriv Trader (Volatility 10 (1 s) Index.0,M15)      1 object of class 'MqlWebSocketTransport'
2025.10.17 19:30:01.347 Deriv Trader (Volatility 10 (1 s) Index.0,M15)   576 bytes of leaked memory found
Arquivos anexados:
log.txt  34 kb
 
pauldic #:
Perdoe-me por omitir minha fonte, então reverti para a correção sugerida para que eu possa obter os erros novamente e parece que essas partes do meu código são as partes que levam ao erro, de acordo com o log

. Além disso, vejo essas mensagens com frequência:

Não me dei conta de que a letra T já estava sendo usada como typename do modelo de classe (é estranho que o compilador não tenha produzido um erro nesse caso), portanto, mudar T para qualquer outra letra livre não terá problema, por exemplo, X:

   template<typename X>
   void ArraySort(X &s[][]) const
   {
      ::ArraySort(s);
   }

Quanto ao primeiro aviso, aqui está uma explicação dos fóruns (que eu lhe dei anteriormente):

Fórum sobre negociação, sistemas de negociação automatizados e teste de estratégias de negociação

Especialistas: MQL5 Programming for Traders - Source Codes from the Book. Parte 7

Stanislav Korotky, 2025.06.14 16:26

Isso é apenas um aviso causado pelo fato de que a enumeração integrada correspondente da MQL5 tem uma lacuna nas constantes que normalmente são atribuídas consecutivamente. Essa lacuna ocorre porque a MQL5 está em constante mudança, e algumas constantes podem se tornar obsoletas e ser eliminadas. Você pode editar o código-fonte para evitar esses avisos.

E sobre o vazamento de memória - receio que haja uma omissão em seu código-fonte personalizado, pois o livro não mostrou tais coisas. Você deve fornecer um código de teste completo para reproduzir o problema.

PS. É mais eficiente executar uma única seleção para todas as propriedades de seu interesse:

   // EXEMPLO: solicitar lucro, símbolo, tíquete para posições
   // por número mágico específico, classificado por lucro
   
   #include <MQL5Book/Tuples.mqh>
   #include <MQL5Book/PositionFilter.mqh>
   #property script_show_inputs
   
   input ulong Magic;
   
   void OnStart()
   {
      int props[] = {POSITION_PROFIT, POSITION_SYMBOL, POSITION_TICKET};
      Tuple3<double,string,ulong> tuples[];
      PositionFilter filter;
      filter.let(POSITION_MAGIC, Magic).select(props, tuples, true);
      ArrayPrint(tuples);
   }



NB: Acho que os moderadores deveriam mover todas as perguntas e respostas sobre o livro (a partir do número 41) para o tópico apropriado, por exemplo, aqui - https://www.mql5.com/en/forum/459067.

 
Stanislav Korotky #:

Não percebi que a letra T já estava sendo usada como o modelo de classe typename (é estranho que o compilador não tenha produzido um erro nesse caso), portanto, mudar T para qualquer outra letra livre será aceitável, por exemplo, X:

Quanto ao primeiro aviso, aqui está uma explicação dos fóruns (que eu lhe dei anteriormente):

E sobre o vazamento de memória - receio que haja uma omissão em seu código-fonte personalizado, pois o livro não mostra essas coisas. Você deve fornecer um código de teste completo para reproduzir o problema.

PS. É mais eficiente executar um único select para todas as propriedades de seu interesse:



NB: Acho que os moderadores deveriam mover todas as perguntas e respostas sobre o livro (a partir do número 41) para o tópico apropriado, por exemplo, aqui - https://www.mql5.com/en/forum/459067.

Muito obrigado, essa pequena alteração T -> X fez a mágica. E obrigado novamente pela indicação da minha pergunta anterior (esqueci que já havia perguntado antes) e seu lembrete me ajudou a ver a atualização do toyjson3.mqh, que eu havia perdido anteriormente, e pelo 'select' am, farei as correções.

Acredito que você esteja certo sobre o vazamento, acho que já tenho uma ideia de onde ele vem.

Muito obrigado, irmão.
 
void printActiveOrders() {
   int properties[] = {ORDER_VOLUME_INITIAL, ORDER_PRICE_OPEN, ORDER_SL, ORDER_TP, ORDER_TICKET, ORDER_MAGIC, ORDER_TYPE, ORDER_SYMBOL, ORDER_COMMENT};
   Tuple9<double,double,double,double,long,long,long,string,string> values[]; 
   OrderFilter filter;
   filter.select(properties, values);
   Print("\nFound:  ", ArraySize(values), " Orders\n{ORDER_VOLUME_INITIAL, ORDER_PRICE_OPEN, ORDER_SL, ORDER_TP, ORDER_TICKET, ORDER_MAGIC, ORDER_TYPE, ORDER_SYMBOL, ORDER_COMMENT}");
   ArrayPrint(values);
}

void printDeals() {
   DealFilter filter;    
   int properties[] = {DEAL_TIME, DEAL_SYMBOL, DEAL_TICKET, DEAL_TYPE, DEAL_VOLUME, DEAL_PRICE, DEAL_COMMISSION, DEAL_PROFIT};
   
   Tuple8<long,string,long,long,double,double,double,double> data[];   
   filter.select(properties, data, true); // Filtrar por tempo
   Print("\nFound:  ", ArraySize(data), " Deals\nTIME, SYMBOL, TICKET, TYPE, VOLUME, PRICE, COMMISSION, PROFIT");
   ArrayPrint(data);
}

@StanislavKorotky
Posso acessar as transações e os pedidos com esse código, mas não consegui descobrir como acessá-los em um período de tempo específico. Por favor, você pode me orientar sobre algum documento ou exemplo de como fazer o mesmo para um período de tempo específico?

 
pauldic #:

Consigo acessar as transações e os pedidos com esse código, mas não consegui descobrir como acessá-los em um período de tempo específico. Por favor, você pode me orientar sobre algum documento ou exemplo de como fazer o mesmo para um período de tempo específico?

De qualquer forma, ordens, negócios e posições não estão relacionados a períodos de tempo. Ou você entendeu algo errado ou seu texto está incorreto.