Discussão do artigo "Introdução ao MQL5: Como escrever Expert Advisor e Custom Indicator simples" - página 2

 
Rosh:

Para os buffers de indicadores, ele diz SetIndexBuffer:

Para os Expert Advisors deve ser semelhante, verifique

Ainda não há analogia. Ao verificar esse código

//+------------------------------------------------------------------+
//|Test002.mq5
//+------------------------------------------------------------------+
double high[];
int bars;
//+------------------------------------------------------------------+
//| Função de inicialização de especialista|
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   bars=Bars(Symbol(),PERIOD_CURRENT);
   ArraySetAsSeries(high,true);
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Função de desinicialização de especialista|
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
  }
//+------------------------------------------------------------------+
//| Função de tique de especialista|
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   int copied=CopyHigh(Symbol(),0,0,bars,high);
   return;
  }
//+------------------------------------------------------------------+

coloquei um ponto de interrupção em frente ao operador de retorno. O depurador produz o seguinte resultado: high "dynamic array[8563], S". Entendo que S significa "Series".

 
Yedelkin:

A analogia ainda não funciona. Ao verificar esse código

coloquei um ponto de interrupção em frente ao operador de retorno. O depurador gera o seguinte resultado: high "dynamic array[8563], S". Entendo que S significa "Series".

Então, por que isso não funciona? Em caso de dúvida, defina uma verificação explícita para séries por meio da função ArrayGetAsSeries:

//+------------------------------------------------------------------+
//|Test_ArraySetAsSeries.mq5
//| Copyright Copyright 2010, MetaQuotes Software Corp.
//| http://www.mql5.com
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
double high[];
int bars;
//+------------------------------------------------------------------+
//| Função de inicialização de especialista|
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   bars=Bars(Symbol(),PERIOD_CURRENT);
   ArraySetAsSeries(high,true);
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Função de tique de especialista|
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   int copied=CopyHigh(Symbol(),0,0,bars,high);
   bool IsSeries=ArrayGetAsSeries(high);
   return;
  }
//+------------------------------------------------------------------+

Resultado


 
Rosh писал(а) :

Por que não funciona. Em caso de dúvida, defina uma verificação explícita de serialidade com a função ArrayGetAsSeries:

Deixe-me lembrá-lo do que estou falando. Eu estava perguntando se as matrizes deveriam ser sempre indexadas somente depois de terem sido copiadas. Você se referiu à nota da função SetIndexBuffer e disse que deveria ser o mesmo para os EAs. Essa nota de função SetIndexBuffer implica que"após a vinculação, o buffer dematriz dinâmica [] será indexado como em matrizes regulares, mesmo que a matriz vinculada esteja predefinida para ser indexada como em séries temporais".

Assim, vi uma analogia para os EAs no fato de que, depois de usar as funções CopyTime, CopyHigh e CopyLow, as matrizes de recebimento também terão de ser indexadas como em matrizes regulares. Para testar essa analogia, coloquei a função ArraySetAsSeries antes da função CopyHigh, na função OnInit(). Mas o meu exemplo e a verificação explícita da serialização pela função ArrayGetAsSeries que você sugeriu mostram que, depois de usar a função CopyHigh, a indexação predefinida (como em timeseries) da matriz receptora high[] não foi alterada. Isso, por sua vez, indica que a analogia com a função SetIndexBuffer que você mencionou ainda não foi observada, pois, caso contrário, a verificação explícita de serialidade deveria ter mostrado que IsSeries=false.

 

Yedelkin:

Para testar essa analogia, coloquei a função ArraySetAsSeries antes da função CopyHigh, na função OnInit(). Mas o meu exemplo e a verificação explícita da serialização pela função ArrayGetAsSeries que você sugeriu mostram que, depois de usar a função CopyHigh, a indexação predefinida (como em timeseries) da matriz receptora high[] não foi alterada.

Na verdade, eu quis dizer que, depois de definir a serialização para a matriz global em OnInit() ou em alguma outra função, essa serialização não será alterada em nenhum outro lugar. A única exceção está relacionada à função SetIndexBuffer().

Acredito que chegamos a um acordo sobre essa questão e podemos considerá-la esgotada.

 

Sim, a pergunta foi respondida. Obrigado pelo esclarecimento!

 

Algumas perguntas.

1.

   if(CopyTime(Symbol(),0,0,i,t)<i || CopyHigh(Symbol(),0,0,i,h)<i || CopyLow(Symbol(),0,0,i,l)<i)
     {
      Print("Falha ao copiar a série temporal!");
      return;
     }

Diz-se que "No operador if..., o operador return é usado para encerrar a execução da função OnTick."

OnTick é ? e não de if (....) {...}?

2.

   for(i=0;i<PositionsTotal();i++) {…}

Na MQL4, a pesquisa reversa era recomendada.

for(i= PositionsTotal();i>0;i--) {…}
o que é melhor?

3. Baixei o Expert Advisor e o indicador (para moderadores do Opera 10.54, problemas com o download de arquivos anexados). Tudo compilado. Iniciado no testador no M5 selecionando o último mês.

Registro

2010.05.15 13:16:02 Core 1 Desconectado

2010.05.15 13:16:01 Core 1 Arquivo de registro "D:\MetaTrader 5\Tester\Agent-127.0.0.0.1-3000\logs\20100515.log" escrito

2010.05.15 13:16:01 Core 1 EURUSD,M5: 553908 ticks (2580 barras) gerados em 1431016 ms (total de barras no histórico 100352)

2010.05.15 13:16:01 Core 1 OnTester result 0

2010.05.15 12:52:13 Core 1 EURUSD,Daily: o histórico começa em 2009.01.02 00:00

2010.05.15 12:52:13 Core 1 EURUSD,Daily: cache do histórico reservado para 355 barras estimadas

2010.05.15 12:52:13 Core 1 EURUSD: contém 484483 registros M1 de dados iniciais de 2009.01.02 06:01 a 2010.05.03 00:00

2010.05.15 12:52:10 Core 1 Lotes=0.100000

2010.05.15 12:52:10 Core 1 MAper=240

2010.05.15 12:52:10 Core 1 EndHour=19

2010.05.15 12:52:10 Core 1 StartHour=7

2010.05.15 12:52:10 Core 1 EURUSD,M5: teste do Experts\expert.ex5 de 2010.05.01 00:00 a 2010.05.14 00:00 iniciado com entradas:

Demorou muito tempo para ser executado e não abriu uma única negociação. A negociação automática é permitida. Não há mensagens no registro ((( (editar provavelmente ainda não sei como encontrá-las). O indicador e o Expert Advisor estão localizados onde deveriam estar. Windows XP, MT (build 274).

4. Tentei o modo de depuração, mas ele não funciona. Provavelmente por causa do sábado. Sem aspas. Fiz o ponto de parada da mesma forma que no artigo. Se eu estiver certo, é uma pena que você só possa depurar em um dia útil. Seria bom para a depuração poder carregar seu próprio arquivo com os dados necessários e (ou) com alguns dados típicos (que seja um pedaço da história por um dia), isso será suficiente para a depuração.

5) Se alguém tiver pesquisado a função Copiar... compartilhe informações sobre como ela funciona se houver barras faltando. Embora provavelmente seja melhor encomendar um artigo.

 
Prival:

Algumas perguntas.

1. Diz-se que "No operador if..., o operador return é usado para encerrar a execução da função OnTick."

OnTick é ? e não de if (....) {...}?

Da descrição do operador return return:

Оператор return прекращает выполнение текущей функции и возвращает управление 
вызвавшей программе. Результат вычисления выражения возвращается вызываемой 
функции. Выражение может содержать оператор присваивания.

A função atual para a instrução de retorno neste exemplo é a função OnTick().

Prival:

4. Tentei o modo de depuração, mas ele não funciona. Provavelmente por causa do sábado. Sem aspas. Fiz o ponto de parada da mesma forma que no artigo. Se eu estiver certo, é uma pena que você só possa depurar em um dia útil. Seria bom para a depuração poder carregar seu próprio arquivo com os dados necessários e (ou) com alguns dados típicos (que seja um pedaço da história por um dia), isso será suficiente para a depuração.

O site já discutiu questões semelhantes sobre depuração. Se você estiver interessado, use a pesquisa e procure a palavra "Debugging".

 

Depois de carregar a atualização automática (compilação 275), o compilador começou a gerar avisos nas linhas em que as condições do seguinte tipo são verificadas

if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
Os avisos são do mesmo tipo:
implicit enum conversion Perito02-04 temp3.mq5 1233 45
Perguntas: a operação correta do compilador implica o aparecimento desses avisos na situação especificada? De que "conversão" estamos falando?
 
Yedelkin :

Depois de carregar a atualização automática (compilação 275), o compilador começou a gerar avisos nas linhas em que as condições do tipo são verificadas

Os avisos são do mesmo tipo: Perguntas: o trabalho correto do compilador implica o aparecimento desses avisos na situação especificada? De que "conversão" estamos falando?

O aviso foi introduzido para fazer com que os programadores prestem atenção e verifiquem novamente seu código.

Você pode se livrar dos avisos convertendo explicitamente o resultado da função em um enumerador ou enumerador em int.

 
Prival:

Algumas perguntas.

1. Diz-se que "No operador if..., o operador return é usado para encerrar a execução da função OnTick."

OnTick é ? e não de if (....) {...}?

Se pelo menos uma das condições do operador

if(CopyTime(Symbol(),0,0,i,t)<i || CopyHigh(Symbol(),0,0,i,h)<i || CopyLow(Symbol(),0,0,i,l)<i)

pelo menos uma das condições for atendida, ou seja, pelo menos uma das matrizes não pôde ser copiada completamente (não há dados históricos suficientes ou ocorreu um erro) - a função OnTick é encerrada, pois outros cálculos são impossíveis sem esses dados.

2. Na MQL4, a enumeração inversa era recomendada.

O que é melhor?

Variantes

for(i=0;i<PositionsTotal();i++)

и

for(i=PositionsTotal()-1;i>=0;i--)

são equivalentes, mas a primeira variante é mais curta em forma de texto, por isso foi usada.

3. Baixei o Expert Advisor e o indicador (para os moderadores, o Opera 10.54 tem problemas com o download de arquivos anexados). Tudo compilado. Eu o executei no testador no M5, selecionando o último mês.

Levou muito tempo para ser executado e não abriu uma única negociação. A negociação automática é permitida. Não há mensagens no registro (((( (provavelmente ainda não sei como encontrá-las). O indicador e o Expert Advisor estão localizados onde deveriam estar. Windows XP, MT (build 274).

4. Tentei o modo de depuração, mas ele não funciona. Provavelmente por causa do sábado. Sem aspas. Fiz o ponto de parada da mesma forma que no artigo. Se eu estiver certo, é uma pena, pois você só pode depurar em um dia útil. Seria bom para a depuração poder carregar seu próprio arquivo com os dados necessários e (ou) com alguns dados típicos (que seja um pedaço da história por um dia), isso será suficiente para a depuração.

5) Se alguém tiver pesquisado a função Copiar... compartilhe informações sobre como ela funciona se houver barras faltando. Embora provavelmente seja melhor encomendar um artigo.

Para ser honesto, meu testador também não funciona muito bem: o teste leva muito mais tempo do que o teste de um EA semelhante em MQL4; as negociações são abertas somente nos primeiros um ou dois dias do intervalo de teste (isso é observado ao testar diferentes Expert Advisors).

As funções OnTick e OnCalculate são iniciadas quando uma nova cotação é recebida, portanto, para sua depuração, é necessário receber cotações (não funcionará em um fim de semana). Caso contrário, o depurador funciona normalmente (experimente-o, pergunte-me se precisar de algo).

Com relação a arrays-timeseries: - a direção dos arrays pode ser alterada a qualquer momento em ambas as direções, a localização dos arrays na memória não muda, apenas a indexação muda (de 0,1,2,...,last to last,...,2,1,0) .