Cualquier pregunta de los recién llegados sobre MQL4 y MQL5, ayuda y discusión sobre algoritmos y códigos - página 380

 
Hola a todos.
Esta es mi primera vez en el foro, si estoy haciendo algo mal en el foro, por favor, perdóname de antemano.
Estoy mirando los gráficos con indicadores durante mucho tiempo. Recientemente he perdido 2 depósitos. Quiero comprobar la rentabilidad de la estrategia en los datos históricos antes de abrir una nueva cuenta. Estoy usando una cuenta demo en MT4.
No soy programador en absoluto. Sólo puedo instalar el indicador en MT4 y tal vez cambiar el grosor de la línea del indicador en MetaEditor (lo más probable es que no pueda cambiar el color en el código del indicador, sólo en el terminal).
¿Tienes alguna información clara para alguien con mis conocimientos, por dónde empezar a hacer las pruebas paso a paso (en lenguaje llano "instrucciones para los negros de cómo usar el baño")? La estrategia tiene 3 indicadores: MA (3 simples), Estocástico con niveles estándar, y CCI con 5 niveles. Apertura de operaciones en corto tras cruzar niveles de indicadores de arriba a abajo, operaciones en largo viceversa (supongo que está claro...). Ajuste de la toma y la pérdida.
Me gustaría poder hacer un seguimiento visual de la estrategia en modo automático, así como sin visualización para seleccionar los parámetros de los indicadores y las órdenes.
 
ZebStamp:
Hola a todos.
Esta es mi primera vez en el foro, si estoy haciendo algo mal en el foro, por favor, perdóname de antemano.
Estoy mirando los gráficos con indicadores durante mucho tiempo. Recientemente he perdido 2 depósitos. Antes de abrir una nueva cuenta quiero comprobar la rentabilidad de la estrategia en el historial. Estoy usando una cuenta demo en MT4.
No soy programador en absoluto. Sólo puedo instalar el indicador en MT4 y quizás cambiar el grosor de la línea del indicador en MetaEditor (lo más probable es que no pueda cambiar el color en el código del indicador, sólo en el terminal).
¿Tienes alguna información clara para alguien con mis conocimientos, por dónde empezar a hacer las pruebas paso a paso (en lenguaje llano "instrucciones para los negros de cómo usar el baño")? La estrategia tiene 3 indicadores: MA (3 simples), Estocástico con niveles estándar, y CCI con 5 niveles. Apertura de operaciones en corto tras cruzar niveles de indicadores de arriba a abajo, operaciones en largo viceversa (supongo que está claro...). Ajuste de la toma y la pérdida.
Me gustaría poder seguir la estrategia en modo automático visualmente, así como sin visualización para seleccionar los parámetros de los indicadores y las órdenes.

Al crear un objeto gráfico (GO), como TrendLine, se selecciona el color. Cuando se vuelve a crear la TrendLine, se crea con el mismo color. En el caso de Hline - se elige un color - y el siguiente es así. Toma el amarillo, el azul, ...

Si CS crea el Asesor Experto, el indicador, la secuencia de comandos - a continuación, como se escribe en el programa. A veces, la elección de los parámetros

 
STARIJ:

Si cree que alguien que mira su código puede encontrar rápidamente un error, se equivoca. El compilador busca errores. El texto del programa debe ser formateado - MetaEditor tiene una herramienta de estilo para eso. Si le gusta un estilo diferente, utilice, por ejemplo, el programa AStyle.exe. Después de la estilización, verá rápidamente que el programa 1) tiene un paréntesis de cierre extra. 2) Variable declarada: datetime date_Buf_1; // Indicador de matriz de fechas - para que sea una matriz, debe ser [size] o [] para una matriz dinámica y luego el tamaño debe ser establecido a ArrayResize parece. Y tienes que hacerlo antes de usar un array - ver los posts anteriores sobre ello. 3) FileOpen(InpDirectoryName+"//"+InpFileName - parece que los palos deberían estar inclinados en la otra dirección. Y es mejor prescindir de InpDirectoryName+"//" - de todos modos encontrará el archivo en la carpeta Files.

en la línea: int copied=CopyTime(NULL,0,0,0,date_Buf_1); el compilador se enfada, start=0=0


Gracias. Conseguí arreglar algo, pero más por intuición que por comprensión. Pero seguimos teniendo 3 errores relativos a la matriz:

'Buf_1' - array requerido 111.mq4 93 21

'date_Buf_1' - array requerido 111.mq4 94 21

'Buf_1' - array requerido 111.mq4 100 16


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
input string             InpFileName="111.csv";      // Имя файла 
input string             InpDirectoryName="Data";     // Имя каталога 

datetime Время=0;   // Время прошлого бара
double Bid1;
double   Buf_1[];
// double ExtBuffer;
long V1; // объем для текущего тика вверх
long V2; // накопленный объем для всех тиков вверх текущего бара
long V3; // объем текущего тика вниз
long V4; // накопленный объем для всех тиков вниз для текущего бара
long V5;  // отрицательные и положительные iVolume нарастающим итогом
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnInit()
  {
   IndicatorDigits(0);
   SetIndexBuffer(0,Buf_1);
//SetIndexBuffer(1,Buf_2);
   Bid1=Bid;
   V5=0;

  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   datetime Вр=Time[0];   // Время текущего бара
   if(Вр>Время)           // Если новый бар
     {
      Время=Вр;           // Запомнить
                          //      Buf_1[0]=0;         // и обнулить последний элемент буфера
     }

   datetime date_Buf_1[]; // массив дат индикатора 
   datetime time_Buf_1[]; // массив времени 
                          // --- считаю объем для положительных и отрицательных тиков      
   if(Bid>=Bid1)
     {
      if(Bid>Bid1) // если тик положительный..
        {
         V1=iVolume(NULL,0,0); // если повышающий цену тик, то находим его объем
         V2= V1 + V2;
        }
      else
        {
         V1=0;                // если Bid1 = Bid2, т.е. изменение цены = 0, то iVolume этого тика присваиваем 0;
         V2= V1 + V2;
        }
     }
   else
     {
      V3 = iVolume(NULL, 0, 0); // если понижающий цену тик 
      V4 = V3 + V4;             // то находим его объем  
     }

   V5=V2-V4;               // определяем разницу (дельту) между объемами положительных и отрицательных тиков
   Bid1=Bid;
   Buf_1[0]=V5; // в буфер сгружаем  дельту

                //   ExtBuffer = Buf_1 [0];
//   double macurrent=iMAOnArray(ExtBuffer,0,5,0,MODE_LWMA,0); 

// запись в файл данных буфера


//--- установим для массивов признак таймсерии 
   ArraySetAsSeries(Buf_1[0],true);
   ArraySetAsSeries(date_Buf_1[0],true);

//--- скопируем таймсерию 
   int copied=CopyTime(NULL,0,10000,0,date_Buf_1);

//--- подготовим массив Buf_1 
   ArrayResize(Buf_1[0],copied);

//--- скопируем значения линии индикатора  
   for(int i=0;i<copied;i++)
     {
      Buf_1[i]=V5;
     }
//--- откроем файл для записи значений индикатора 
   ResetLastError();
   int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_WRITE|FILE_CSV);
   if(file_handle!=INVALID_HANDLE)
     {
      PrintFormat("Файл %s открыт для записи",InpFileName);
      PrintFormat("Путь к файлу: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH));
      //--- сначала запишем значения индикатора 
      FileWrite(file_handle,Buf_1[0]);
      //--- запишем время и значения в файл 
      for(int i=0;i<Buf_1[0];i++)
         FileWrite(file_handle,time_Buf_1[0],Buf_1[0]);
      //--- закрываем файл 
      FileClose(file_handle);
      PrintFormat("Данные записаны, файл %s закрыт",InpFileName);
     }
   else
      PrintFormat("Не удалось открыть файл %s, Код ошибки = %d",InpFileName,GetLastError());

   return(rates_total);
  }
//+------------------------------------------------------------------+


No entiendo cómo aplicar sus comentarios. Pero encontré una grapa extra :)
 
YarTrade:

Gracias. Conseguí arreglar algo, pero más por intuición que por comprensión. Pero sigo teniendo 3 errores relacionados con la matriz:

'Buf_1' - array requerido 111.mq4 93 21

'date_Buf_1' - array requerido 111.mq4 94 21

'Buf_1' - array requerido 111.mq4 100 16



No entiendo cómo aplicar sus comentarios. Pero he encontrado un soporte extra :)
Deja sólo los nombres de las variables del array. Elimine "[]" en aquellas líneas de código a las que el compilador le indique.
 
Artyom Trishkin:
Deja sólo los nombres de las matrices de las variables. Elimine "[]" en aquellas líneas de código a las que el compilador le indique.

Gracias. Veré lo que ocurre en la vida real. Tengo grandes dudas de que se escriba algo en el archivo :)

 

Me han surgido varias preguntas, espero mucho su ayuda. He encontrado una cosa muy triste, que el rendimiento de EA durante las pruebas y en tiempo real es muy diferente, por lo que me gustaría analizar los errores más comunes y típicos. Primero escribiré sobre los que me he encontrado. Os agradecería que compartierais vuestras experiencias con el programador que sabe lo que debe tener en cuenta y lo que debe mantener en su código.

1. El error de división por cero aparecía en el modo de negociación real, a pesar de que la división por cero no estaba presente en el código y no se había producido durante las pruebas retrospectivas. El programador resolvió el problema escribiendo cada divisor como NormalizeDouble(x,Digits);

2. El acuerdo no se abrió. El viernes se abrió la operación cuando el backtest estaba en marcha, pero no se abrió ninguna operación durante la negociación real. Además, el diario del Asesor Experto no ha mostrado ningún error. No sé cuál puede ser el problema aquí, pero tengo un par de cosas. En primer lugar, recibí advertencias como "el valor de retorno de 'ordersend' debe ser comprobado", pero si entiendo correctamente, esto no debería afectar a la ejecución del código? ¿O se trata de un deslizamiento? Mi valor es 1, que no es demasiado pequeño. Y la barra en la que debería realizar una entrada se abrió sin un hueco.

Tomé la línea "if(Volumen[0]>1) return;" del ejemplo estándar con resbalones y la inserté al principio del código. Es decir, mi código se ejecuta sólo durante el primer tick cuando aparece una nueva barra. ¿Puede ser que una barra se abra con un volumen y mi código no se ejecute?

4. Por favor, aconseje sobre las cosas a las que hay que prestar atención o los errores típicos cuando se trabaja con EA con el historial y el tiempo real, por favor


 
LuckySith:

Me han surgido varias preguntas, espero mucho su ayuda. He encontrado una cosa muy triste, que el rendimiento de EA durante las pruebas y en tiempo real es muy diferente, por lo que me gustaría analizar los errores más comunes y típicos. Primero escribiré sobre los que me he encontrado. Os agradecería que compartierais vuestras experiencias con el programador que sabe lo que debe tener en cuenta y lo que debe mantener en su código.

1. El error de división por cero aparecía en el modo de negociación real, a pesar de que la división por cero no estaba presente en el código y no se había producido durante las pruebas retrospectivas. El programador resolvió el problema escribiendo cada divisor como NormalizeDouble(x,Digits);

2. El acuerdo no se abrió. El viernes se abrió la operación cuando el backtest estaba en marcha, pero no se abrió ninguna operación durante la negociación real. Además, el diario del Asesor Experto no ha mostrado ningún error. No sé cuál puede ser el problema aquí, pero tengo un par de cosas. En primer lugar, recibí advertencias como "el valor de retorno de 'ordersend' debe ser comprobado", pero si entiendo correctamente, esto no debería afectar a la ejecución del código? ¿O se trata de un deslizamiento? Mi valor es 1, que no es demasiado pequeño. Y la barra en la que debería realizar una entrada se abrió sin un hueco.

Tomé la línea "if(Volumen[0]>1) return;" del ejemplo estándar con resbalones y la inserté al principio del código. Es decir, mi código se ejecuta sólo durante el primer tick cuando aparece una nueva barra. ¿Puede ser que una barra se abra con un volumen y mi código no se ejecute?

4. Por favor, aconsejen sobre las cosas a las que hay que prestar atención o los errores típicos cuando se trabaja con EA con el historial y el tiempo real, por favor

Sustituye esta construcción salvaje "if(Volumen[0]>1) return;" por una comprobación normal de "Nueva Barra", el foro está lleno de ellas.

Las advertencias del tipo "hay que comprobar el valor de retorno de 'ordersend'" no son errores hasta ahora, son errores potenciales para el futuro. No debería haber ninguna advertencia en el código, y mucho menos cuando se trabaja en línea.

"Tengo 1, que no es poco" - puede ser muy poco en la apertura de un nuevo bar, y sobre todo en la apertura de una media hora o una hora, en este momento el spread se amplía mucho.

Lo que necesitamos: hacer una comprobación en el nuevo bar, y si es nuevo, entonces ver las condiciones de entrada, si coincidieron - hacer un trato. Después hay que registrar que el bar funcionó y esperar el nuevo.

Lo que tenemos ahora: if(Volume[0]>1) return; = si hay una nueva barra, buscamos las condiciones, la condición no encajaba == spread grande = salir de nuevo en OnTick(), en el siguiente tick if(Volume[0]>1) return; no irá más allá, por lo que la operación ya se ha perdido, aunque el spread sea de 0.0001

 

Hola. Por favor, pueden decirme cómo describir lo siguiente con el código: Hay un piso, delimitado por las líneas horizontales superior e inferior. El Asesor Experto los detecta y fija por sí mismo.

Necesitamos que el EA detecte cuando el precio sale de la zona plana y luego vuelve a esta zona. Y sólo después de eso abre una posición.

Para filtrar el ruido, utilizo un blanco móvil con el parámetro 2 o 3

 
Vitaly Muzichenko:

Sustituya esas construcciones salvajes "if(Volumen[0]>1) return;" por una comprobación normal de "Nueva barra", hay muchas aquí en el foro.

Avisos como "el valor de retorno de 'ordersend' debería ser comprobado" - esto no es un error todavía, es un error potencial para el futuro. No debería haber ninguna advertencia en el código, y mucho menos cuando se trabaja en línea.

"Tengo 1, que no es poco" - puede ser muy poco en la apertura de un nuevo bar, y sobre todo en la apertura de una media hora o una hora, en este momento el spread se amplía mucho.

Lo que necesitamos: hacer una comprobación en el nuevo bar, y si es nuevo, entonces ver las condiciones de entrada, si coincidieron - hacer un trato. Después hay que registrar que el bar funcionó y esperar el nuevo.

Lo que tenemos ahora: if(Volume[0]>1) return; = si hay una nueva barra, entonces mira las condiciones, la condición no encaja == spread grande = salir de nuevo en OnTick(), en el siguiente tick if(Volume[0]>1) return; no se perderá más, por lo que la operación se perderá aunque el spread sea de 0.0001


Sobre la apertura de un nuevo bar. ¿Sería bueno? :

datetime counted_bar = 0;

int OnInit()
{
   counted_bar = 0; // если нужно, чтоб при перезапуске последний бар был проанализирован
   ...

void OnTick()
{
   // Если появился новый бар
   if ( iTime( _Symbol, _Period, 0 ) > counted_bar )
   {
      counted_bar = iTime( _Symbol, _Period, 0 );

      // Анализируем индикаторы
      ...
   }
 
LuckySith:

Sobre la apertura de un nuevo bar. ¿Sería una buena opción? :

Que sea así inicialmente.

A continuación, tenemos que hacer una fijación adecuada que la barra se resuelve, pero aquí tenemos que calcular toda la aproximación a la TOR.

Por lo que veo en tu post, hay que hacerlo así:

void OnTick()
{
   // Если появился новый бар
   if ( iTime( _Symbol, _Period, 0 ) > counted_bar )
   {
      // Анализируем индикаторы
      if(SpreadMax > текущий спред) return;

      counted_bar = iTime( _Symbol, _Period, 0 );
      ...
   }

La esencia es esta: si el spread es más alto de lo normal, entonces salimos de nuevo aOnTick, y en un nuevo tick comprobamos el spread, si es normal - enviamos una orden y recordamos que hubo una operación en esta barra.

También hay una segunda vía:

void OnTick()
{
   // Если появился новый бар
   if ( iTime( _Symbol, _Period, 0 ) > counted_bar )
   {
      if(SpreadMax > текущий спред) return;
      // Анализируем индикаторы
      ...
      result = OrderSend(...);
      // если открылась позиция, то result будет тикет позиции
       if(result>0) counted_bar = iTime( _Symbol, _Period, 0 );
   }

En general, es necesario definir la lógica, cuando debe grabar, y no comprobar de nuevo antes de la formación de un "Nuevo Bar".

Razón de la queja: