Discusión sobre el artículo "Recetas MQL5 - Creando el búfer circular para calcular rápidamente los indicadores en la ventana móvil" - página 4

 
Otto Pauser:

Un gran artículo, ¡el hombre sabe programar!

¡¡¡¡¡Si la traducción al alemán no fuera tan horrible!!!!!

Hola,

Muchas gracias por el consejo. La traducción ha sido corregida.

Saludos cordiales

 

¡Buenos días, Vasiliy Sokolov!

Sus indicadores creados con la ayuda de la memoria cíclica muestran algo poco claro, supongo que el método ChangeValue no funciona, o tal vez he entendido algo mal?

 
Savio Araujo:

Lo he visto. Como he comprobado los ejemplos que has proporcionado. Muestran el mismo problema que tuve cuando se trata de actualizar los valores mientras el mercado está en marcha. Compruebe el estocástico que ha proporcionado. Agregar un nuevo valor no es un problema, pero cuando tratamos de usar Stoch.ChangeLast() o OnChangeValue() en la clase CRiMaxMin, no funciona. No cambia el valor en consecuencia. Si pudieras comprobarlo o enviar un ejemplo de un código que funcione, estaría muy bien.

Gracias.

Gran trabajo aquí, muchas gracias al autor. Tal vez el error que estás viendo, Savio, está aquí:

int RingBuffer::iToRealInd(int iIndex)

{

   if(iIndex >= iNumElements() || iIndex < 0)

      return iBufferSize-1; //previous bug was caused by no -1 here

...

He añadido el -1 en la última línea citada; antes no estaba y provocaba que se devolviera un índice incorrecto. Ten en cuenta que cambié los nombres de las variables/métodos a mi estilo de programación pero es la misma idea.

 
¿Por qué CRiStoch no tiene un método llamado ChangeValue?
 
brisully:

Gran trabajo aquí, muchas gracias al autor. Tal vez el error que estás viendo, Savio, está aquí:

int RingBuffer::iToRealInd(int iIndex)

{

   if(iIndex >= iNumElements() || iIndex < 0)

      return iBufferSize-1; //previous bug was caused by no -1 here

...

He añadido el -1 en la última línea citada; antes no estaba y provocaba que se devolviera un índice incorrecto. Ten en cuenta que he cambiado los nombres de las variables/métodos a mi estilo de programación pero es la misma idea

He probado tu corrección, pero sigue sin actualizarse bien. Parece que hay algo que falta y no puedo encontrar el problema cuando se trata de ejecutar el búfer de anillo en la formación de una nueva barra. Cuando el mercado se está ejecutando, las líneas High/Low se mezclan completamente. El código funciona muy bien y muy rápido mientras procesa datos antiguos, pero con los nuevos datos que llegan durante la formación de una nueva barra, simplemente no me funciona.

 
Vasily, ¡gracias por el código! Ayuda mucho.
Si se me permite hacer algunos comentarios:

1. En la clase void CRiMaxMin::OnChangeValue(int index, double del_value, double new_value), en el método " OnChangeValue " en la línea
.
if(m_min_ind >= 0 && new_value >= GetValue(m_min_ind))
      m_min_ind = index;

Imagen: ¿error tipográfico?


errata - signo "menor o igual que".

2.Cuando se buscan los elementos Min y Max de un array, si se utiliza exactamente como un buffer anular (cuando se empiezan a escribir nuevos elementos al principio del array), min y mah se definen incorrectamente. El mínimo es mayor que el máximo. En un array. Todo funciona usando los métodos estándar (ArrayMinimum y ArrayMaximum).
Picture: El mínimo es mayor que el máximo

En algún sitio la indexación va por mal camino. No puedo arreglarlo yo mismo. Si alguien puede arreglarlo, sería genial. He adjuntado un asesor de prueba.

#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"

#include  <RingBuffer\RiMaxMin.mqh>

input group "Comprobación a través de búfer de anillo es cierto."
input bool ringBuffer=true;


input group "Tamaño del búfer".
input int pTest=10;

double minValue,maxValue;
int minIndex,maxIndex,lastIndex,indArr;

double arr[];

CRiMaxMin minMaxTest;

int OnInit()
  { 
   if(ringBuffer)minMaxTest.SetMaxTotal(pTest);
   else  
      {
      indArr=-1;
      lastIndex=pTest-1;
      ArraySetAsSeries(arr,true);
      ArrayResize(arr,pTest);
      }
   return(INIT_SUCCEEDED);
  }

void OnDeinit(const int reason)
  {
   
   
  }

void OnTick()
  {
   if(ringBuffer)
      {
      minMaxTest.AddValue(rand());
      minIndex=minMaxTest.MinIndex();
      minValue=minMaxTest.GetValue(minIndex);
      //minValor=minMaxTest.MinValor();
      maxIndex=minMaxTest.MaxIndex();
      maxValue=minMaxTest.GetValue(maxIndex);
      //ValorMáx=ValorMáxTest.MaxValor();
      }
   else
      {
      //arr[0]=rand();
      //ArrayCopy(arr,arr,1,0,lastIndex);
      indArr++;
      if(indArr>lastIndex)indArr=0;
      arr[indArr]=rand();
      minIndex=ArrayMinimum(arr,0,pTest);
      minValue=arr[minIndex];
      //minValor=arr[ArrayMinimo(arr,0,pPrueba)];
      maxIndex=ArrayMaximum(arr,0,pTest);
      maxValue=arr[maxIndex]; 
      //valormax=arr[ArrayMaximum(arr,0,pTest)];
      }  
   Alert("minValue ",DoubleToString(minValue)," --  maxValue ",DoubleToString(maxValue));
   if(minValue>maxValue)
      {
      Alert("Min > Max !!!");
      Print("Min > Max !!!");
      ExpertRemove();
      }
  }
Archivos adjuntos:
 
Pido disculpas. Min y Max tienen razón. Me lo estaba pensando demasiado.
 
Esto es exactamente lo que necesito. Gracias por el código y por un artículo tan detallado. ¡La idea de optimizar la búsqueda de extremos es genial!
 

Tienes un error en ToRealInd(int index).

Debería ser
if(índice >= GetTotal() || índice < 0 )
return m_max_total-1;