Diskussion zum Artikel "Die Rezepte MQL5 - Die Erstellung des Ringpuffers für eine schnelle Berechnung der Indikatoren im gleitenden Fenster" - Seite 4

 
Otto Pauser:

Ein super Artikel, der Mann kann programmieren!

Wenn doch die deutsche Übersetzung nicht so grauenhaft wäre!!!!!

Hallo,

vielen Dank für den Hinweis. Die Übersetzung wurde korrigiert.

Beste Grüße

 

Guten Tag, Vasiliy Sokolov!

Ihre Indikatoren, die mit Hilfe des Ringpuffers erstellt wurden, zeigen etwas Unklares, ich vermute, die ChangeValue-Methode funktioniert nicht, oder habe ich vielleicht etwas falsch verstanden?

 
Savio Araujo:

Ich habe es gesehen. Ich habe die von Ihnen angeführten Beispiele geprüft. Sie zeigen das gleiche Problem, das ich hatte, wenn es um die Aktualisierung der Werte geht, während der Markt läuft. Prüfen Sie die von Ihnen bereitgestellte Stochastik. Das Hinzufügen eines neuen Wertes ist kein Problem, aber wenn wir versuchen, Stoch.ChangeLast() oder OnChangeValue() in der CRiMaxMin-Klasse zu verwenden, funktioniert es nicht. Der Wert wird nicht entsprechend geändert. Wenn Sie das überprüfen oder ein Beispiel für einen funktionierenden Code schicken könnten, wäre das sehr nett.

Ich danke Ihnen.

Großartige Arbeit hier, vielen Dank an den Autor. Vielleicht ist der Fehler, den Sie sehen, Savio, hier zu finden:

int RingBuffer::iToRealInd(int iIndex)

{

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

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

...

Ich habe das -1 in der letzten zitierten Zeile hinzugefügt; es war vorher nicht da und führte dazu, dass ein falscher Index zurückgegeben wurde. Beachten Sie, dass ich die Namen der Variablen/Methoden an meinen Programmierstil angepasst habe, aber die Idee ist dieselbe.

 
Warum verfügt CRiStoch nicht über eine Methode namens ChangeValue?
 
brisully:

Großartige Arbeit hier, vielen Dank an den Autor. Vielleicht ist der Fehler, den Sie sehen, Savio, ist hier:

int RingBuffer::iToRealInd(int iIndex)

{

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

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

...

Ich habe das -1 in der letzten zitierten Zeile eingefügt; es war vorher nicht da und führte dazu, dass ein falscher Index zurückgegeben wurde. Beachten Sie, dass ich die Namen der Variablen/Methoden an meinen Programmierstil angepasst habe, aber die Idee ist die gleiche

Ich habe Ihre Korrektur ausprobiert, aber es wird immer noch nicht richtig aktualisiert. Es scheint etwas zu fehlen, und ich kann das Problem nicht finden, wenn ich versuche, den Ringpuffer bei der Bildung eines neuen Balkens auszuführen. Wenn der Markt läuft, werden die High/Low-Linien komplett durcheinander gebracht. Der Code funktioniert sehr gut und sehr schnell bei der Verarbeitung von alten Daten, aber mit neuen Daten ankommen während der Bildung eines neuen bar, es funktioniert einfach nicht für mich.

 
Vasily, danke für den Code! Er hilft mir sehr.
Wenn ich einige Anmerkungen machen darf:

1. In der Klasse void CRiMaxMin::OnChangeValue(int index, double del_value, double new_value), in der Methode " OnChangeValue" in der Zeile
.
if(m_min_ind >= 0 && new_value >= GetValue(m_min_ind))
      m_min_ind = index;

Bild: Tippfehler?


Tippfehler - Vorzeichen "kleiner oder gleich".

2. Bei der Suche nach Min- und Max-Elementen eines Arrays, wenn es genau als Ringpuffer verwendet wird (wenn neue Elemente an den Anfang des Arrays geschrieben werden), sind min und mah falsch definiert. Das Minimum ist größer als das Maximum. In einem Array. Alles funktioniert mit den Standardmethoden (ArrayMinimum und ArrayMaximum).
Bild: Minimum ist größer als Maximum

Irgendwo geht die Indizierung in die Irre. Ich kann es nicht selbst beheben. Wenn es jemand beheben kann, wäre das großartig. Ich habe einen Test-Ratgeber angehängt.

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

#include  <RingBuffer\RiMaxMin.mqh>

input group "Die Überprüfung durch den Ringspeicher ist richtig."
input bool ringBuffer=true;


input group "Puffergröße".
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);
      //minValue=minMaxTest.MinValue();
      maxIndex=minMaxTest.MaxIndex();
      maxValue=minMaxTest.GetValue(maxIndex);
      //maxValue=minMaxTest.MaxValue();
      }
   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];
      //minValue=arr[ArrayMinimum(arr,0,pTest)];
      maxIndex=ArrayMaximum(arr,0,pTest);
      maxValue=arr[maxIndex]; 
      //maxValue=arr[ArrayMaximum(arr,0,pTest)];
      }  
   Alert("minValue ",DoubleToString(minValue)," --  maxValue ",DoubleToString(maxValue));
   if(minValue>maxValue)
      {
      Alert("Min > Max !!!");
      Print("Min > Max !!!");
      ExpertRemove();
      }
  }
Dateien:
 
Ich bitte um Entschuldigung. Min und Max haben recht. Ich habe selbst zu viel darüber nachgedacht.
 
Das ist genau das, was ich brauche. Vielen Dank für den Code und diesen ausführlichen Artikel. Die Idee, die Suche nach Extremen zu optimieren, ist großartig!
 

Sie haben einen Fehler in ToRealInd(int index).

Es sollte lauten:
if(index >= GetTotal() || index < 0 )
return m_max_total-1;