Discusión sobre el artículo "Introducción a MQL5: Cómo escribir un Expert Advisor y un Indicador Personalizado" - página 2

 
Rosh:

Para los buffers indicadores dice SetIndexBuffer:

Para Asesores Expertos debería ser similar, comprobar

Aún no hay analogía. Al comprobar este código

//+------------------------------------------------------------------+
//|Test002.mq5
//+------------------------------------------------------------------+
double high[];
int bars;
//+------------------------------------------------------------------+
//| Función de inicialización experta|
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   bars=Bars(Symbol(),PERIOD_CURRENT);
   ArraySetAsSeries(high,true);
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Función de desinicialización experta|
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
  }
//+------------------------------------------------------------------+
//| Función tick experto|
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   int copied=CopyHigh(Symbol(),0,0,bars,high);
   return;
  }
//+------------------------------------------------------------------+

puse un punto de interrupción frente al operador return. El depurador produce el siguiente resultado: high "dynamic array[8563], S". Entiendo que S significa "Series".

 
Yedelkin:

La analogía aún no funciona. Al comprobar este código

puse un punto de interrupción frente al operador return. El depurador genera el siguiente resultado: high "dynamic array[8563], S". Entiendo que S significa "Serie".

Entonces, ¿por qué no funciona? Si dudas, pon una comprobación explícita de series mediante la función 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;
//+------------------------------------------------------------------+
//| Función de inicialización experta|
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   bars=Bars(Symbol(),PERIOD_CURRENT);
   ArraySetAsSeries(high,true);
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Función tick experto|
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   int copied=CopyHigh(Symbol(),0,0,bars,high);
   bool IsSeries=ArrayGetAsSeries(high);
   return;
  }
//+------------------------------------------------------------------+

Resultado


 
Rosh писал(а) :

Por qué no funciona. En caso de duda, establece una comprobación explícita de serialidad con la función ArrayGetAsSeries:

Permíteme recordarte de qué estoy hablando. Estaba preguntando si las matrices deberían indexarse siempre después de haber sido copiadas. Te referías a la nota de la función SetIndexBuffer y decías que debería ser igual para los EAs. Esta nota de la función SetIndexBuffer implica que"después de enlazar, el buffer[]del array dinámico se indexará como en los arrays normales, incluso si el array enlazado está preconfigurado para indexarse como en las series temporales".

En consecuencia, vi una analogía para los EAs en que después de usar las funciones CopyTime, CopyHigh y CopyLow, los arrays receptores también tendrán que ser indexados como en arrays regulares. Para probar esta analogía, coloqué la función ArraySetAsSeries antes de la función CopyHigh, en la función OnInit(). Pero mi ejemplo y la comprobación explícita de serialización por la función ArrayGetAsSeries que sugeriste muestran que después de usar la función CopyHigh, la indexación preestablecida (como en timeseries) del array receptor high[] no ha cambiado. Esto, a su vez, indica que la analogía con la función SetIndexBuffer que mencionas no se observa todavía, porque de lo contrario la comprobación explícita de serialización debería haber mostrado que IsSeries=false.

 

Yedelkin:

Para probar esta analogía, coloqué la función ArraySetAsSeries antes de la función CopyHigh, en la función OnInit(). Pero mi ejemplo y la comprobación explícita de serialización por la función ArrayGetAsSeries que sugeriste muestran que después de usar la función CopyHigh, la indexación preestablecida (como en timeseries) del array receptor high[] no ha cambiado.

En realidad, me refería a que después de establecer la serialización para el array global en OnInit() o alguna otra función, esta serialización no cambiará en ningún otro lugar. La única excepción está relacionada con la función SetIndexBuffer().

Creo que hemos llegado a un acuerdo sobre esta cuestión y podemos considerarla agotada.

 

Sí, la pregunta ha sido respondida. Gracias por la aclaración.

 

Unas preguntas.

1.

   if(CopyTime(Symbol(),0,0,i,t)<i || CopyHigh(Symbol(),0,0,i,h)<i || CopyLow(Symbol(),0,0,i,l)<i)
     {
      Print("¡Fallo al copiar la serie temporal!");
      return;
     }

Se dice que "En el operador if..., el operador return se utiliza para terminar la ejecución de la función OnTick".

¿Es OnTick? y no de if (....) {...}?

2.

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

En MQL4 se recomendaba la búsqueda inversa.

for(i= PositionsTotal();i>0;i--) {…}
¿qué es mejor?

3. Descargado el Asesor de Expertos y el indicador (para Opera 10.54 moderadores, problemas con la descarga de archivos adjuntos). Todo compilado. Iniciado en el probador en M5 seleccionar el último mes.

Registro

2010.05.15 13:16:02 Core 1 Desconectado

2010.05.15 13:16:01 Core 1 Archivo 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) generados en 1431016 ms (total de barras en el historial 100352)

2010.05.15 13:16:01 Core 1 OnTester resultado 0

2010.05.15 12:52:13 Core 1 EURUSD,Diario: la historia comienza a partir de 2009.01.02 00:00

2010.05.15 12:52:13 Core 1 EURUSD,Diario: caché del historial reservada para 355 barras estimadas

2010.05.15 12:52:13 Core 1 EURUSD: contiene 484483 registros M1 de datos de inicio desde 2009.01.02 06:01 hasta 2010.05.03 00:00

2010.05.15 12:52:10 Núcleo 1 Lotes=0.100000

2010.05.15 12:52:10 Núcleo 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: pruebas de Experts\expert.ex5 de 2010.05.01 00:00 a 2010.05.14 00:00 iniciado con entradas:

Tardó mucho tiempo en ejecutarse y no abrió ni una sola operación. El trading automático está permitido. No hay mensajes en el registro ((( (editar probablemente no sé cómo encontrarlos todavía). Indicador y Asesor Experto se encuentran donde deben estar. Windows XP, MT (build 274).

4. Probado el modo de depuración, no funciona. Probablemente debido al sábado. No hay comillas. Hice el punto de parada de la misma manera que en el artículo. Si estoy en lo cierto es una pena, resulta que sólo se puede depurar en día laborable. Estaría bien para depurar poder subir tu propio fichero con los datos necesarios y (o) con algún dato típico (que sea un trozo de historia de un día), será suficiente para depurar.

5. Si alguien ha investigado la función Copiar... por favor comparta información sobre cómo funciona si faltan barras. Aunque probablemente sería mejor pedir un artículo.

 
Prival:

Unas preguntas.

1. Se dice que "En el operador if..., el operador return se utiliza para terminar la ejecución de la función OnTick".

¿Es OnTick? y no de if (....) {...}?

De la descripción del operador return

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

La función actual para la sentencia return en este ejemplo es OnTick().

Prival:

4. Probado el modo debug, no va. Probablemente debido al sábado. No hay comillas. He hecho el punto de parada igual que en el artículo. Si estoy en lo cierto es una pena, resulta que sólo se puede depurar en día laborable. Estaría bien para depurar poder subir tu propio archivo con los datos necesarios y (o) con unos datos típicos (que sea un trozo de historia de un día), será suficiente para depurar.

En este sitio ya se han tratado cuestiones similares sobre depuración. Si está interesado, utilice la búsqueda y busque la palabra "Depuración".

 

Después de cargar la actualización automática (build 275), el compilador ha empezado a generar advertencias en las líneas en las que se comprueban condiciones del siguiente tipo

if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
Las advertencias son del mismo tipo:
implicit enum conversion Perito02-04 temp3.mq5 1233 45
Preguntas: ¿implica el correcto funcionamiento del compilador la aparición de estas advertencias en la situación especificada? ¿De qué "conversión" estamos hablando?
 
Yedelkin :

Después de cargar la actualización automática (build 275), el compilador empezó a generar advertencias en las líneas donde se comprueban condiciones del tipo

Las advertencias son del mismo tipo: Preguntas: ¿implica el correcto trabajo del compilador la aparición de estas advertencias en la situación especificada? ¿De qué "conversión" estamos hablando?

La advertencia se introdujo para que los programadores prestaran atención y revisaran dos veces su código.

Puedes librarte de las advertencias convirtiendo explícitamente el resultado de la función en un enumerador o enumerador en int.

 
Prival:

Unas preguntas.

1. Se dice que "En el operador if..., el operador return se utiliza para terminar la ejecución de la función OnTick".

¿Es OnTick? y no de if (....) {...}?

Si se cumple al menos una de las condiciones del operador

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

se cumple al menos una de las condiciones, es decir, al menos una de las matrices no ha podido copiarse por completo (no hay suficientes datos históricos o se ha producido un error), la función OnTick finaliza, ya que sin estos datos es imposible realizar más cálculos.

2. en MQL4 se recomendaba la enumeración inversa.

¿que es mejor?

Variantes

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

и

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

son equivalentes, pero la primera variante es más corta en forma de texto, por lo que se utilizó.

3. Descargado el Asesor de Expertos y el indicador (para los moderadores Opera 10.54 problemas con la descarga de archivos adjuntos). Todo compilado. Lo corrí en el probador en M5, seleccionando el último mes.

Tardó muchísimo en ejecutarse y no abrió ni una sola operación. El trading automático está permitido. No hay mensajes en el log ((( (probablemente no se como encontrarlos todavia). Indicador y Asesor Experto se encuentran donde deben estar. Windows XP, MT (build 274).

4. Probado el modo de depuración, no va. Probablemente debido al sábado. No hay comillas. He hecho el punto de parada igual que en el artículo. Si estoy en lo cierto es una pena, resulta que sólo se puede depurar en día laborable. Estaría bien para depurar poder subir tu propio fichero con los datos necesarios y (o) con algún dato típico (que sea un trozo de historia por un día), será suficiente para depurar.

5. Si alguien ha investigado la función Copiar... por favor comparta información de cómo funciona si faltan barras. Aunque probablemente sería mejor pedir un artículo.

Para ser honesto, mi probador tampoco funciona muy bien: las pruebas tardan mucho más que probar un EA similar en MQL4; las operaciones se abren sólo en los primeros uno o dos días del intervalo de prueba (esto se observa al probar diferentes Asesores Expertos).

Las funciones OnTick y OnCalculate se lanzan cuando se recibe una nueva cotización, por lo que para su depuración es necesario recibir cotizaciones (no funcionará en fin de semana). Por lo demás, el depurador funciona normalmente (pruébalo, pregúntame si necesitas algo).

Respecto a arrays-timeseries: - la dirección de los arrays se puede cambiar en cualquier momento en ambas direcciones, la ubicación de los arrays en memoria no cambia, sólo cambia la indexación (de 0,1,2,...,último a último,...,2,1,0) .