prev_calculado - página 2

 
Alexey Kozitsyn:
¿Qué tal si simplemente se recalcula todo el indicador cuando es 0? A mí me parece la mejor solución.
Para un indicador pesado con toneladas de gráficos - no es lo mejor. No, la solución es sencilla: utilizar una variable propia en lugar de prev_calculada, estática o global. Pero es una muleta y queremos otra cosa.
 
Alexey Kozitsyn:
:) Eso es lo que hago...
Eso es lo que entendí, sólo estaba citando su pregunta, pero en realidad estaba respondiendo aAlexander Puzanov. :)
 
Alexander Puzanov:
Para un indicador pesado con toneladas de gráficos no es la mejor solución. La solución es sencilla: utilizar una variable propia en lugar de prev_calculada, estática o global. Pero es una muleta y queremos otra cosa.

Una persona que utiliza la palabra "muleta":

  • es demasiado perezoso para leer la documentación
  • o no sabe todavía cómo debe ser correcto.
La única solución correcta: en prev_calculate==0 recalcular el indicador.

 
Alexander Puzanov:
Para un indicador pesado con toneladas de gráficos - no es lo mejor. No, la solución es sencilla: utilizar una variable propia en lugar de prev_calculada, estática o global. Pero es una muleta y queremos otra cosa.
No es una muleta en absoluto. Así es como lo hago yo.
 
Karputov Vladimir:
Y si el historial se ha intercambiado, significa que puede haber nuevas barras que se hayan perdido o que no se hayan calculado antes, es decir, las lecturas del indicador ya estarán equivocadas.

Slawa:

Si prev_calculated=0, significa que hay que hacer un recálculo completo. Todos los indicadores estándar se recalculan completamente en este caso.

Todo está claro, pero, por desgracia, todo no cancela esto:

Alexander Puzanov:

Todo esto es útil, pero no se puede utilizar de acuerdo con su propósito directo - mostrar cuántas "barras se procesaron en la llamada anterior" - prev_calculated

Los indicadores son diferentes; algunos no necesitan barras para los cálculos en absoluto, algunos necesitan sólo ticks en vivo, algunos tienen limitaciones en la profundidad de la conversión - no les importa lo que ha cambiado a continuación en la historia, algunos necesitan seguir los objetos gráficos, etc. No necesitan funciones adicionales para rastrear los cambios en la historia adjunta a prev_calculated, sólo necesitan esto - 'barras procesadas en la llamada anterior'. No lo necesitan.

De todos modos, señor programador, por favor, no distraiga al que se une para "captar el evento".

 
Alexey Kozitsyn:
¿Y si simplemente recalculo todo el indicador a 0? En mi opinión, es la mejor solución.

No diría que es la mejor solución. Al menos, todavía no.

He decidido escribir un indicador que registre la reducción actual de la cuenta, para no tener que recalcular nada en el historial. La primera línea tenía este aspecto al principio.

if(prev_calculated == 0)  return(rates_total);
Pero después de iniciar me encontré con que los búferes no están vacíos y no se ponen a cero. Hay algún precio en los topes de origen desconocido. Tuve que forzar los topes a cero... A continuación, se descubrió otro problema. El prev_calculate se pone a cero y el indicador se recalcula, respectivamente, poniendo a cero todos los buffers hasta la última barra. De todos modos, he abandonado la idea por ahora.
 
Alexey Viktorov:

No diría que es la mejor solución. Al menos, todavía no.

He decidido escribir un indicador que registre la reducción actual de la cuenta, para no tener que recalcular nada en el historial. Al principio, la primera línea tenía este aspecto.

if(prev_calculated == 0)  return(rates_total);
Pero después de la puesta en marcha me encontré con que los búferes no están vacíos y no se ponen a cero. Hay algún precio en los topes que no sé de dónde ha salido. Tuve que forzar los topes a cero... A continuación, se descubrió otro problema. El prev_calculate se pone a cero y el indicador se recalcula, respectivamente, poniendo a cero todos los buffers hasta la última barra. De todos modos, he abandonado la idea por ahora.

"... algún precio de origen desconocido... " - es una basura de elementos no inicializados de la matriz del buffer de indicadores. Lo que hay que hacer:

  • en prev_calculate==0 recorre todos los elementos del buffer de indicadores en el bucle y les asigna valores. En este caso, es necesario controlar la situación cuando aparece una nueva barra (rates_total menos prev_calculate será mayor que cero) - el buffer del indicador aumenta en consecuencia y este nuevo elemento también debe ser inicializado.

 

Foro sobre trading, sistemas de trading automatizados y pruebas de estrategias de trading

Bichos, errores, preguntas

Alexey Viktorov, 2016.10.17 09:58

¿Entiendes lo que has escrito?

Mejor explicar cómo deshacerse de la basura PRIMERA carrera del indicador. ¿De dónde viene esta basura? ¿No debería haber una inicialización al enlazar el buffer con el array? ¿O es durante la inicialización cuando la basura espacial entra en el array? ¿Por qué no hay esa basura en mql4?

Dame un ejemplo de cómo cribar la basura de los valores normales sin usar variables estáticas o globales adicionales.

Todo el mundo es lo suficientemente bueno como para citar la documentación.


 

Nadie debe nada a nadie. Así que habrá basura en el buffer del indicador, después de la vinculación, hasta que se inicialicen todos los elementos de la matriz por sí mismo.

Añadido:

Voy a crear un ejemplo ahora...

//+------------------------------------------------------------------+
//|                                              prev_calculated.mq5 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrGray
#property indicator_label1  "prev_calculated"
//---- buffers
double ExtBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,ExtBuffer,INDICATOR_DATA);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| 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[])
  {
//---
   if(prev_calculated==0)
     {
      //--- инициализация элементов индикаторного буфера при первом запуске или при подкачке истории
      for(int i=0;i<rates_total;i++)
         ExtBuffer[i]=1.01;
      return(rates_total);
     }
//--- пересчитываем самый правый бар или самый правый бар и один предыдущий при появлении нового бара
   int limit=rates_total-prev_calculated+1;
   for(int i=rates_total-limit;i<rates_total;i++)
     {
      //--- визуализация пересчёта самого правого бара
      static bool drive=false;
      if(!drive)
         ExtBuffer[i]=1.03;
      else
         ExtBuffer[i]=1.02;
      drive=!drive;
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
Hazlo en M1. Verá que sólo se recalcula la barra de la derecha.
Archivos adjuntos:
 
Karputov Vladimir:

Nadie debe nada a nadie. Así que habrá basura en el buffer del indicador, después de la vinculación, hasta que se inicialicen todos los elementos de la matriz por sí mismo.

Añadido:

Voy a crear un ejemplo ahora...

//+------------------------------------------------------------------+
//|                                              prev_calculated.mq5 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrGray
#property indicator_label1  "prev_calculated"
//---- buffers
double ExtBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,ExtBuffer,INDICATOR_DATA);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| 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[])
  {
//---
   if(prev_calculated==0)
     {
      //--- инициализация элементов индикаторного буфера при первом запуске или при подкачке истории
      for(int i=0;i<rates_total;i++)
         ExtBuffer[i]=1.01;
      return(rates_total);
     }
//--- пересчитываем самый правый бар или самый правый бар и один предыдущий при появлении нового бара
   int limit=rates_total-prev_calculated+1;
   for(int i=rates_total-limit;i<rates_total;i++)
     {
      //--- визуализация пересчёта самого правого бара
      static bool drive=false;
      if(!drive)
         ExtBuffer[i]=1.03;
      else
         ExtBuffer[i]=1.02;
      drive=!drive;
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
Hazlo en M1. Verá que sólo se recalcula la barra de la derecha.

Increíble habilidad para responder a la pregunta equivocada...

Ahora explícame qué pasa si:

1. Contado 100 barras, introducidas en los buffers de 0 a 99 inclusive (consideremos la dirección como serie temporal) valor 1.03

2. De repente se carga el historial y prev_calculado pasa a ser 0

¿A partir de qué barra será 1,03?