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

 

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

Na parte final, parte 7, exploramos as capacidades avançadas da API MQL5 que são úteis na criação de programas para o MetaTrader 5. Alguns deles incluem instrumentos financeiros personalizados e um calendário econômico incorporado, enquanto outros abrangem tecnologias universais, como funções de rede, bancos de dados e criptografia.

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

Autor: MetaQuotes

 
Bons recursos de aprendizado
 
Aprender
 
Aqui estão pequenas correções de erros e melhorias no cache e no filtro do calendário.
MQL5 Book: Advanced language tools / Economic calendar / Transferring calendar database to tester
MQL5 Book: Advanced language tools / Economic calendar / Transferring calendar database to tester
  • www.mql5.com
The calendar is available for MQL programs only online, and therefore testing news trading strategies poses some difficulties. One of the solutions...
Arquivos anexados:
 

Você pode me dizer se isso é um erro ou se eu não entendi alguma coisa?

Arquivo MarginProfitMeter.mqh.

// Converter a quantia de dinheiro "atual" em dinheiro "da conta
bool Convert(const string current, const string account,
             const bool ask, double &margin, const datetime moment = 0)
  {
   string rate;
   int dir = FindExchangeRate(current, account, rate);
   if(dir == +1)
     {
      margin *= moment == 0 ?
                SymbolInfoDouble(rate, ask ? SYMBOL_BID : SYMBOL_ASK) :
                GetHistoricPrice(rate, moment, ask);
     }
   else
      if(dir == -1)
        {
         margin /= moment == 0 ?
                   SymbolInfoDouble(rate, ask ? SYMBOL_ASK : SYMBOL_BID) :
                   GetHistoricPrice(rate, moment, ask);
        }
      else
        {
         static bool once = false;
         if(!once)
           {
            Print("Can't convert ", current, " -> ", account);
            once = true;
           }
        }
   return true;
  }

É impossível dividir por zero, não é?


Além disso, esse método deveria retornar a margem, mas ele retorna o preço. Entendo que em algum lugar esse preço deve ser multiplicado pelo tamanho do contrato, mas não entendo onde fazer isso corretamente.

Devo adicionar isso nessa função ou de onde chamamos essa função?

 
Aleksandr Slavskii #:

Você pode me dizer se isso é um erro ou se estou perdendo alguma coisa?

Arquivo MarginProfitMeter.mqh

É impossível dividir por zero, não é?

De fato, não é possível.

margin /= moment == 0 ?
                   SymbolInfoDouble(rate, ask ? SYMBOL_ASK : SYMBOL_BID) :
                   GetHistoricPrice(rate, moment, ask);

Há um operador ternário após o símbolo de divisão com a atribuição "/=". Portanto, se momet==0, então:

margin /= SymbolInfoDouble(rate, ask ? SYMBOL_ASK : SYMBOL_BID)

senão:

margin /= GetHistoricPrice(rate, moment, ask)

Mas eu ainda acrescentaria uma verificação de zero em ambas as funções....


Além disso, esse método deveria retornar a margem, mas ele retorna o preço. Entendo que em algum lugar esse preço deve ser multiplicado pelo tamanho do contrato, mas não entendo onde fazer isso de forma mais correta....

A julgar pela descrição

// Converter a quantia de dinheiro "atual" em dinheiro "da conta

o método converte o dinheiro (moeda) atual em dinheiro (moeda) do depósito. E, a julgar pelo código, o método converte a margem na moeda do depósito.

Se for bem-sucedido, o método retornará true. E também calculará o novo valor corrigido da margem, armazenando-o na variável margin. Ela é um parâmetro no link:

double &margin

Portanto, você pode obtê-lo como resultado do cálculo.

 
Denis Kirichenko #:

Você realmente não pode.

Há um operador ternário após o símbolo de divisão com a atribuição "/=". Portanto, se momet==0, então:

Sim. É isso mesmo, um operador ternário. Estou cansado esta manhã, estou ficando burro.


Denis Kirichenko #:

A julgar pela descrição

o método converte o dinheiro atual (moeda) em dinheiro de depósito (moeda). E, a julgar pelo código, o método converte a margem na moeda de depósito.

Não, isso também está correto agora.


Peço desculpas, cometi um pequeno erro no código.


De qualquer forma, é de pouca utilidade, porque no final ele ainda conta a margem incorretamente se o volume for maior que três.

EURUSD; margin = 24668.8  //  OrderCalcMargin()
EURUSD; margin = 10889.599999999999 // MarginProfitMeter.mqh 

Cálculo da margem para dez contratos.

 
Denis Kirichenko #:
margem /= momento == 0? SymbolInfoDouble(rate, ask ? SYMBOL_ASK: SYMBOL_BID): GetHistoricPrice(rate, moment, ask);

Um pouco errado. A condição(margin /= moment)==0 e, em seguida, o operador ternário...

 
Alexey Viktorov #:

Um pouco errado. A condição (margem /= momento)==0 e, em seguida, um operador ternário...

De alguma forma, não concordo. Tente atender a essa condição primeiro:

double margin = 1.5;
datetime moment = 0;
margin /= moment;

Então você estará dividindo ouriços em ouriços, o que é questionável por si só.

E as operações de atribuição têm uma prioridade muito baixa, apenas o zpt tem uma prioridade mais baixa.

O compilador também fica irritado:

possible loss of data due to type conversion from 'datetime' to 'double'

E a lógica da função é a conversão de margem. Pelo que entendi, moment = 0 é agora, então:

margin /= moment == 0 ?
                SymbolInfoDouble(rate, ask ? SYMBOL_ASK : SYMBOL_BID) :
                GetHistoricPrice(rate, moment, ask);

significa que, se for agora, pedimos o preço atual. E se for no passado, nos referimos aos preços históricos. E, depois de obter o preço desejado, no final, dividimos o valor da margem por esse preço com a atribuição.... e com sua lógica, verifica-se que no momento = 0, não obteremos a conversão da margem, mas apenas o preço de mercado ou o preço do passado....


Em geral, seria melhor escrever entre colchetes para um livro didático:

margin /= (moment == 0) ?
                   SymbolInfoDouble(rate, ask ? SYMBOL_ASK : SYMBOL_BID) :
                   GetHistoricPrice(rate, moment, ask);
 
Denis Kirichenko #:

De alguma forma, eu não concordo. Tente cumprir essa condição primeiro:

Isso divide os ouriços em ouriços, o que, por si só, já é questionável.

E as operações de atribuição têm uma prioridade muito baixa, apenas o zpt tem uma prioridade mais baixa.

E o compilador também fica irritado:

E a lógica da função é a conversão de margem. Pelo que entendi, moment = 0 é agora. Então:

significa que, se for agora, pedimos o preço atual. E se for no passado, então nos referimos aos preços históricos. E, depois de obter o preço desejado, no final, dividimos o valor da margem por esse preço com a atribuição.... e com sua lógica, verifica-se que se moment = 0, não obteremos uma conversão de margem, mas apenas um preço de mercado ou um preço do passado...


Em geral, seria melhor escrever entre colchetes para um livro didático:

Convincente. Concordo, eu estava desatento. Mas se você escrever para um livro didático e para que seja compreensível até para mim, seria melhor assim

margin /= ( moment == 0 ?
                   SymbolInfoDouble(rate, ask ? SYMBOL_ASK : SYMBOL_BID) :
                   GetHistoricPrice(rate, moment, ask));