Discussão do artigo "O Protótipo do Robô de Negócio" - página 2

 

Recomendo evitar esse design

//------------------------------------------------------------------ CheckNewBar
bool CExpertAdvisor::CheckNewBar()          // função de verificar se uma nova barra aparece
  {
   MqlRates rt[2];
   if(CopyRates(m_smb,m_tf,0,2,rt)!=2)      // copiar as barras
     { Print("CopyRates of ",m_smb," failed, no history"); return(false); }
   if(rt[1].tick_volume>1) return(false);   // verificar o volume 
   return(true);
  }

pois o processamento do tique anterior pode levar tempo suficiente para perder a chegada do primeiro tique da nova barra.

respectivamente, é possível perder a abertura.

É melhor vincular-se à hora de abertura da barra, mas para isso você precisa salvar a hora anterior da barra zero, por exemplo, para compará-la com a hora atual da barra zero.

Se for o mesmo, não há nova barra

Se for diferente, pelo menos uma nova (próxima) barra é aberta, após a qual inicializamos a hora armazenada da barra zero com a hora atual da barra zero.

Essa construção é mais confiável.

Документация по MQL5: Стандартные константы, перечисления и структуры / Торговые константы / Свойства позиций
Документация по MQL5: Стандартные константы, перечисления и структуры / Торговые константы / Свойства позиций
  • www.mql5.com
Стандартные константы, перечисления и структуры / Торговые константы / Свойства позиций - Документация по MQL5
 

Trate desse assunto em um artigo futuro:

  • Ordens de stop-loss e take-profit de nível diferente *robustas* (como no lado do servidor) por negociação; elas são *necessárias* para evitar problemas associados a interrupções da rede e do programa do cliente (desconexões prolongadas da rede, deslizamento induzido por atraso da rede (e recotações), encerramento do programa do cliente ou do sistema operacional, reinicializações, falhas (ausência prolongada do software do lado do cliente) etc.); as chamadas ordens "virtuais" simplesmente não são suficientes e nem os substitutos não-OCO (não, isso *não* é negociável, se a robustez for um requisito, as ordens stop-loss e take-profit *devem* estar no lado do servidor e, se uma for atingida, a outra *deve* ser removida *pelo servidor* ao mesmo tempo)
  • recuperação *robusta* do estado por negociação em caso de falha; em outras palavras, se o cliente/SO falhar (e reiniciar automaticamente), quero que o EA saiba exatamente o que aconteceu com as negociações e ordens individuais pendentes nesse meio tempo: preenchidas, fechadas, ainda ativas, quais ordens s/l e t/p associadas pertencem a qual negociação/ordem etc. (não, gravar o estado no disco não é suficiente porque há uma condição de corrida entre a abertura de uma negociação e a gravação do estado no disco e o programa do cliente pode travar exatamente no momento inadequado; os comentários da ordem no lado do servidor podem ser suficientes, se forem modificáveis)

Até onde sei, o MT5 suporta apenas *1* (uma) ordem s/l e t/p do lado do servidor *por instrumento* (não por operação) e nenhuma ordem OCO (as ordens OCO podem ser usadas para simular ordens s/l e t/p por operação, mas também há uma condição de corrida). A menos que as questões acima sejam resolvidas, eu não comprometeria mais do que US$ 100,00 em negociações via MT5 (EAs simplistas do tipo MA cross de ordem única, período único e direção única). E nem mesmo tenho certeza sobre os US$ 100.

 
olyakish:

Recomendo evitar esse design

pois o processamento do tique anterior pode levar tempo suficiente para perder a chegada do primeiro tique da nova barra.

respectivamente, é possível perder a abertura.

É melhor vincular-se à hora de abertura da barra, mas para isso você precisa salvar a hora anterior da barra zero, por exemplo, para compará-la com a hora atual da barra zero.

Se for o mesmo, não há nova barra

Se for diferente, pelo menos uma nova (próxima) barra é aberta, após a qual inicializamos a hora armazenada da barra zero com a hora atual da barra zero.

Esse design é mais confiável.

Eu o fiz dessa forma:

bool CUniexp::checkNewBar(void)
{
   static datetime prevTime[1];
   datetime currentTime[0];
   CopyTime(_Symbol,_Period,0,1,currentTime);
   if (currentTime[0]==prevTime[0])
   {return (false);}
   else
   {
      prevTime[0] = currentTime[0];
      return (true);
   }
}
 
isNewBar
isNewBar
  • votos: 7
  • 2010.05.07
  • Prival
  • www.mql5.com
Функция анализа появления нового бара на заданном таймфрейме.
 

Compila, mas o depurador falha.

Falha no carregamento de C:\Program Files\MetaTrader 5\MQL5\Experts\Examples\eMyEA.ex5

 


Obrigado pelo excelente artigo! Sou novato, mas tenho uma dúvida sobre o código.


Na função void CExpertAdvisor::TrailingPosition(long dir,int TS), há uma linha:

sl=NormalSL(dir,apr,apr,TS,StopLvl); // calcular Stop Loss


Devemos usar apr tanto para o segundo quanto para o terceiro argumento ao chamar NormalSL? Achei que deveria ser assim:

sl=NormalSL(dir,op,apr,TS,StopLvl);

já que o segundo argumento deve ser o preço de compra/venda para a direção "especificada" (ou seja, a variável op) em vez da direção "inversa" (ou seja, a variável apr).


Obrigado!

 
echostate:


Na função void CExpertAdvisor::TrailingPosition(long dir,int TS), há uma linha:

sl=NormalSL(dir,apr,apr,TS,StopLvl); // calcular Stop Loss


Devemos usar apr tanto para o segundo quanto para o terceiro argumento ao chamar NormalSL? Achei que deveria ser assim:

sl=NormalSL(dir,op,apr,TS,StopLvl);

Não.
o segundo e o terceiro argumentos devem ser apr.

porque o cálculo do tral é derivado do preço no qual a posição será fechada. A função Bid para a compra e Ask para a venda está correta.

já que o segundo argumento deve ser o preço de compra/venda para a direção "especificada" (ou seja, a variável op) em vez da direção "inversa" (ou seja, a variável apr).

deve ser calculado a partir da direção "inversa". Nesse caso, apr.
 
sergeev:

não.
o segundo e o terceiro argumento devem ser apr.

porque o cálculo do tral é derivado do preço no qual a posição será fechada. A função Bid para compra e Ask para venda está correta.

O preço de venda deve ser calculado a partir da direção "inversa". Nesse caso, apr.


Obrigado pela resposta rápida! Achei que devia estar errado.


Posso também perguntar na função

double CExpertAdvisor::CountLotByRisk(int dist,double risk,double lot) // calcular o lote pelo tamanho do risco
  {
   if(dist==0 || risk==0) return(lot);
   m_smbinf.Refresh();
   return(NormalLot(AccountInfoDouble(ACCOUNT_BALANCE)*risk/(dist*10*m_smbinf.TickValue())));
  }

por que temos um "10" entre "dist" e "m_smbinf.TickValue()" no valor de retorno? Acho que "dist" é o stop loss (em termos de pips) e "m_smbinf.TickValue()" é o valor em dólares americanos por pip e por lote para o par de moedas. Portanto, não tenho certeza de por que multiplicamos outro "10" entre eles.

Obrigado!

 
Muito obrigado.
 

Artigo muito útil. Muito obrigado!