Perguntas de Iniciantes MQL5 MT5 MetaTrader 5 - página 116

 
Em princípio, o erro foi provavelmente o facto de o meu cabo indicador ter sido criado na função OnTick e os dados serem copiados imediatamente no mesmo tick. Compreendi-o à noite, agora vou tentar transferir alças indicadoras para a função OnInit.
Документация по MQL5: Основы языка / Функции / Функции обработки событий
Документация по MQL5: Основы языка / Функции / Функции обработки событий
  • www.mql5.com
Основы языка / Функции / Функции обработки событий - Документация по MQL5
 
sss20192:
O erro estava no cabo indicador criado na função OnTick e os dados são copiados no mesmo tick. Compreendi-o à noite, agora vou tentar transferir as pegas dos indicadores para a função OnInit.

Não funcionou. Aqui está o código agora


#property version   "1.00"

input int                  InpFastEMA=12;                // Fast EMA period
input int                  InpSlowEMA=26;                // Slow EMA period
input int                  InpSignalMA=9;                // Signal MA period
input ENUM_APPLIED_PRICE   InpAppliedPrice=PRICE_CLOSE;  // Applied price
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int Handle1, Handle2, Handle3;
double MacdArray[];

int OnInit()
  {
//---
  Handle1 = iMACD(_Symbol, PERIOD_M5, InpFastEMA, InpSlowEMA, InpSignalMA, InpAppliedPrice);
  Handle2 = iMACD(_Symbol, PERIOD_M15, InpFastEMA, InpSlowEMA, InpSignalMA, InpAppliedPrice);
  Handle3 = iMACD(_Symbol, PERIOD_H1, InpFastEMA, InpSlowEMA, InpSignalMA, InpAppliedPrice);
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
        CopyBuffer(Handle1, 0, 1, 1, MacdArray);
        Print(MacdArray[0], " ", GetLastError());
        
        CopyBuffer(Handle2, 0, 1, 1, MacdArray);
        Print(MacdArray[0], " ", GetLastError());
        
        CopyBuffer(Handle3, 0, 1, 1, MacdArray);
        Print(MacdArray[0], " ", GetLastError());
  }
//+------------------------------------------------------------------+

As seguintes mensagens aparecem no diário de bordo

2013.04.13 15:21:31 2010.01.04 00:00:00:01 6.187448020344988e-005 0

2013.04.13 15:21:31 2010.01.04 00:00:00:01 6.187448020344988e-005 0

2013.04.13 15:21:31 2010.01.04 00:00:00:01 6.187448020344988e-005 0

E é sempre assim. Não parece haver um erro de cópia.

 
sss20192: Não ajudou. Aqui está o código

Mas até agora não tem nem uma verificação para a criação bem sucedida de pegas, nem uma verificação para o cálculo bem sucedido de indicadores e verificação para a cópia. A ideia de deslocar a inicialização das pegas para o OnInit() é correcta.

Além disso, adicione a linha Print(MacdArray[0]) no início de OnTick() - para ver qual o valor do lixo contido na matriz antes de começar a copiar buffers.

Para acrescentar. Naturalmente, a utilização de GetLastError() após a própria função pode ser uma peculiaridade do estilo de programação. Mas ainda assim verificá-lo-ia tendo em conta o exemplo da Referência. Se não estou enganado, um valor nulo de GetLastError() nem sempre significa que a função funcionou com sucesso.

 
Yedelkin:
Mas até agora não tem nem uma verificação para a criação bem sucedida de pegas, nem uma verificação para o cálculo bem sucedido de indicadores e verificação para a cópia. A ideia de deslocar a inicialização das pegas para o OnInit() é correcta.
Mas apenas pela primeira vez. Se em qualquer outro lugar do programa se verificar que algum cabo é inválido, temos de tentar obtê-lo novamente. Por conseguinte, não podemos dizer que o código escrito para obter alças no OnInit() resolverá completamente o problema e será 100% correcto. ))
 
Verificou quantos dados foram copiados com a função CopyBuffer, escreve sempre 1. E não há erro, mas os dados ainda estão errados.
Документация по MQL5: Доступ к таймсериям и индикаторам / CopyBuffer
Документация по MQL5: Доступ к таймсериям и индикаторам / CopyBuffer
  • www.mql5.com
Доступ к таймсериям и индикаторам / CopyBuffer - Документация по MQL5
 

tol64

Yedelkin : A ideia de mover a inicialização das pegas para o OnInit() é uma boa ideia.

Mas apenas pela primeira vez. Se em qualquer outra parte do programa se verificar que alguma pega é inválida, terá de tentar obtê-la novamente. Por conseguinte, não podemos dizer que o código escrito para obter alças no OnInit() resolverá completamente o problema e será 100% correcto. ))

Está a dizer que a ideia de mover a inicialização das pegas para OnInit() a partir de OnTick() está errada em si mesma?
 
sss20192:
Verifiquei quantos dados foram copiados com a função CopyBuffer, escreve sempre 1. E não há erro, mas os dados ainda estão errados.

Tenho este resultado deste código no testador:

//---

A única coisa que fiz antes do teste foi apenas converter os valores indicadores antes da saída para o registo:

Print(DoubleToString(MacdArray[0],Digits())," ",GetLastError());
 
Yedelkin:
Está a dizer que a ideia de mover a inicialização do manipulador para OnInit() a partir de OnTick() está errada por si só?
Se apenas no OnInit() e em nenhum outro lugar, então sim - errado. A primeira vez que tentamos obter um controlo no OnInit(). Depois, antes de cada tentativa de obter dados indicadores, verificamos se o cabo é válido. Se for válido, obtemos os dados, se não, tentamos obter o cabo novamente.
 
tol64:

Obtive este resultado deste código no testador:

//---

A única coisa que fiz antes do teste foi simplesmente converter os valores indicadores antes de os emitir para o registo:

Ooh, isso é genial! Muito obrigado! Terceiro dia a resolver o problema)
 
tol64:
Yedelkin: Está a dizer que a ideia de mover a inicialização das pegas para OnInit() a partir de OnTick() está errada por si só?
Se apenas no OnInit() e em nenhum outro lugar, sim - errado. A primeira vez que tentamos obter um controlo no OnInit(). Depois, antes de cada tentativa de obter dados indicadores, verificamos se o cabo é válido. Se for válido, obtemos os dados, se não, tentamos obter o cabo novamente.

E sem "se"? E em relação a esta situação particular? O manípulo indicador foi criado na função OnTick durante cada tick, e os dados são copiados durante o mesmo tick. Isto significa que o mesmo manípulo indicador foi solicitado de cada vez, sem verificação da validade/invalidade. Neste contexto, continuará a argumentar que a ideia de transferir a inicialização das pegas para o OnInit() a partir do OnTick() está errada por si só?

PS. Parece que ajudou o homem, pelo que a questão pode ser considerada esgotada.