prev_calculado - página 6

 
No es necesario golpear los hierros con las nueces.
 
Alexey Viktorov:
¡Esto NO está en la documentación! En consecuencia, se trata de un ensayo sobre un tema libre. Igual que mi afirmación sobre la inicialización automática, aún más genial. Al menos el mío tenía un descargo de responsabilidad...

Es imposible describir absolutamente todo en la documentación.

Si "prev_calculate==0" - significa que tenemos que recorrer todo el buffer del indicador. Si "prev_calculate!=0", sólo se calculará la barra más a la derecha o varias nuevas (utilizamos el límite):

                const int &spread[])
  {
//---
   if(prev_calculated==0)
     {
      Print("prev_calculated==0");
            for(int i=0;i<rates_total;i++)
              {
               //--- здесь принудительно каждому элементу массива присваиваем значение (мне лень писать эти массивы :) )
      
              }
      return(rates_total);
     }
//--- экономный пересчёт только самого правого бара или новых баров
   int limit=rates_total-prev_calculated+1;

//--- а ниже нужно использовать цикл для обсчета самого правого бара или новых баров
   for(int i=0;i<limit;i++)
     {
      ExtBuffer[i]=чевой-то там;
     }
 
Karputov Vladimir:

Es imposible describir absolutamente todo en la documentación.

Si se obtiene "prev_calculate==0", significa que hay que recorrer todo el buffer del indicador. Si "prev_calculate!=0", sólo se calculará la barra más a la derecha o varias nuevas (utilizamos el límite):

                const int &spread[])
  {
//---
   if(prev_calculated==0)
     {
      Print("prev_calculated==0");
            for(int i=0;i<rates_total;i++)
              {
               //--- здесь принудительно каждому элементу массива присваиваем значение (мне лень писать эти массивы :) )
      
              }
      return(rates_total);
     }
//--- экономный пересчёт только самого правого бара или новых баров
   int limit=rates_total-prev_calculated+1;

//--- а ниже нужно использовать цикл для обсчета самого правого бара или новых баров
   for(int i=0;i<limit;i++)
     {
      ExtBuffer[i]=чевой-то там;
     }




¿Cuál es el valor? No necesito ningún valor excepto la barra de la derecha. ¡¡¡ PERO!!! Entonces, cuando esta derecha se desplaza a la izquierda estos datos deben ser guardados...

No tienes que escribir todos los topes, pero podrías escribir uno con mis deseos en mente. Si es la primera ejecución, todo el historial debería estar vacío. Si prev_calculated se reinició como resultado del intercambio de la historia, TODO lo que se puso en el buffer debe permanecer sin cambios. Aunque haya agujeros.

 
Karputov Vladimir:

Conclusiones preliminares:

1. Los indicadores no pueden confiar en la inicialización de las matrices de indicadores en OnInit():

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
...
   ArrayInitialize(balance, 0.0);    // принудительная
   ArrayInitialize(equityMax, 0.0);  // инициализация
   ArrayInitialize(equityMaxB, 0.0); // всех
   ArrayInitialize(equityMin, 0.0);  // буферов
   ArrayInitialize(equityMinB, 0.0); // индикатора

...
//---
   return(INIT_SUCCEEDED);
  }

2. En los indicadores es obligatorio pasar por todo el array o sólo los elementos modificados en OnCalculate().

¿Qué tonterías dices? Si esta inicialización se implementa en OnCalculate, se inicializará sin ningún bucle. Pero si prev_calculado, borra todos los datos que se acumularon durante el trabajo...
 
Alexey Viktorov:
¿Por qué dices tonterías? Si esta inicialización se pone en OnCalculate, se pone a cero sin ningún ciclo. Pero si ponemos a cero prev_calculado, se borran todos los datos que se han acumulado durante la operación...
Por favor, utilice las expresiones. Y mira los ejemplos de indicadores de la entrega estándar: Catálogo de datos\MQL5\NIndicadores\NEjemplos.
 
Alexey Viktorov:

¿Cuál es el valor? No necesito ningún otro valor que no sea la barra de la derecha. ¡¡¡ PERO!!! Entonces, cuando esta derecha se desplaza a la izquierda, hay que guardar esos datos...

...

Ya he sugerido una manera:

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

prev_calculado

Karputov Vladimir, 2016.10.18 15:11

Disculpe el retraso en la respuesta. La única forma de guardar los valores calculados para un determinado periodo de tiempo es guardarlos en un archivo. Hay que ocuparse de la sincronización, para que al leer del archivo los datos se coloquen en sus barras. Lo más lógico es sincronizarlo con la hora de apertura de la barra, pero puede haber algunos matices: por ejemplo, la hora de apertura de la barra (guardada en un archivo) era 2016.09.05. 25:02, pero ahora el gráfico tiene una barra con hora igual a 2016.09.05. 25:01.

Un indicador no es una base de datos ni un depósito.

Por lo tanto, si el indicador muestra datos que luego no pueden ser calculados en el historial, entonces sólo es necesario guardar el buffer del indicador en un archivo, y luego (en caso de intercambio de historial) leer y sincronizar el archivo y las barras.
 
Karputov Vladimir:

Ya he sugerido una manera:

Un indicador no es una base de datos ni un depósito.

Por lo tanto, si el indicador muestra los datos, que luego no se pueden calcular en el historial, entonces sólo tenemos que guardar el buffer del indicador en un archivo, y luego (en el caso de la paginación del historial) realizar la lectura y sincronizar el archivo y las barras.

Alexey Viktorov:

... y preferiblemente sin escribir en un archivo o incluso más en GV.

prev_calculated
prev_calculated
  • www.mql5.com
Форум трейдеров MQL5.community
 

Vladimir, ya que has dedicado este tema específicamente a prev_calculated, hazlo útil en este tema. En primer lugar, hay que especificar el problema que se suele producir con esta variable. Si no está familiarizado con estos problemas, formularé

---

a... aunque dice en la ayuda

prev_calculated  // обработано баров на предыдущем вызове

La razón es (está escrito en la ayuda + dicho por los desarrolladores) que la variable se pone a cero cuando la suma de comprobación cambia, por lo general debido al intercambio de la historia.

---

b - tampoco se puede utilizar prev_calculado == 0 como bandera de la primera ejecución de onCalculate. Por la misma razón

---

c - y tampoco se puede utilizar prev_calculated == 0 como bandera de paginación del historial

---

Para reducir el desgaste de los usuarios, la redacción debe ser breve y sin ambigüedades: si la paginación de la historia no ha ocurrido en la llamada actual de OnCalculate, prev_calculated contiene el número de barras procesadas en la llamada anterior. Si ha pasado - se pone a cero

---

Los 3 problemas mencionados se pueden resolver con muletas. Sin embargo, dado que MT5 no puede tener muletas por definición, Vladimir, ¿podría crear una solución atractiva para estos tres problemas? Una fea es algo así:

#property indicator_chart_window
#property indicator_buffers  0
#property indicator_plots    0


struct BROWNIE {
  int   i_Prew_Calculated;  // кол-во посчитанных баров
  bool  b_First_Run;        // флаг первого запуска
  bool  b_History_Updated;  // флаг обновления истории
  
  BROWNIE() {
    i_Prew_Calculated = WRONG_VALUE;
    b_First_Run = true;
    b_History_Updated = false;
  }
  
  void f_Reset(bool b_Reset_First_Run = true) {
    i_Prew_Calculated = WRONG_VALUE;
    if(b_Reset_First_Run) b_First_Run = true;
    b_History_Updated = false;
  }
  
  void f_Update(int i_New_Prew_Calculated = WRONG_VALUE) {
    if(i_New_Prew_Calculated > -1) {
      b_History_Updated = i_New_Prew_Calculated == 0 && i_Prew_Calculated > WRONG_VALUE;
      if(b_First_Run) b_First_Run = false;
      
      if(i_Prew_Calculated == WRONG_VALUE) i_Prew_Calculated = i_New_Prew_Calculated;
      else if(i_New_Prew_Calculated > 0) i_Prew_Calculated = i_New_Prew_Calculated;
    }
  }
};
BROWNIE go_Brownie;


int OnInit(void) {return(INIT_SUCCEEDED);}


void OnDeinit(const int reason) {
  go_Brownie.f_Reset(reason != REASON_CHARTCHANGE);
}



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 &TickVolume[],
    const long &Volume[],
    const int &Spread[]
) {
  if(go_Brownie.b_First_Run) {/* обработка 1го запуска */}
  if(go_Brownie.b_History_Updated) {/* обработка обновления истории */}
  go_Brownie.f_Update(prev_calculated);
  
  return(rates_total);
}

Descargo de responsabilidad: Código - sólo una idea, no lo he probado en un gráfico.

En OnDeinit hay un ejemplo - procesamiento para el indicador que no usa buffers, no le importa el TF y el símbolo, en cada cambio de TF/símbolo no hay necesidad de empezar de cero. Por ejemplo, trabaja con los elementos gráficos existentes, emite información sobre el estado de las cuentas, los pedidos, etc.

---

Por cierto

Karputov Vladimir:

Si el buffer del indicador se guardara en un archivo, y luego (en caso de carga del historial) habría que leer y sincronizar el archivo y las barras.

No tienes que destruir el disco, puedes guardarlo en un elemento de la carta
 
Alexey Viktorov:
... y preferiblemente sin escribir en un archivo o más aún en un GV.
¿Le parece bien?
 
Konstantin Gruzdev:
¿Quizás esto te sirva?

No he entrado en detalles, pero esto se soluciona con esta línea de código. Copiar un array en sí mismo con un desplazamiento de índice.

double arr[5];
ArrayCopy(arr, arr, 0, 1, 4);
// и дальнейшее заполнение 4го индекса массива.
Puedes invertirlo y copiar desde el índice cero y pegar desde el primero. Entonces se rellenará el índice cero de la matriz. Y esto es algo muy diferente...))
Razón de la queja: