Diskussion zum Artikel "Wie man den Berechnungsblock eines Indikators in den Code eines Expert Advisors überträgt" - Seite 4

 
Aleksey Vyazmikin #:
Ich habe nicht verstanden, aus dem Artikel, hat die Klasse-Indikator Schutz gegen fehlende Bars? Wenn zum Beispiel die Verbindung für 5 Takte unterbrochen wurde und dann die Historie geladen wurde, füllt der Klassenindikator dann nur den letzten Wert im Puffer auf oder führt er eine vollständige Neuberechnung durch?

Wenn Sie sich die Standard-Indikatorenklasse ansehen, verwendet sie beim Aktualisieren von Daten die Funktion CopyBuffer. D.h. sie füllt den gesamten Puffer aus der Terminal-Historie, nicht nur einen Teil davon.

bool CIndicatorBuffer::Refresh(const int handle,const int num)
  {
//--- prüfen
   if(handle==INVALID_HANDLE)
     {
      SetUserError(ERR_USER_INVALID_HANDLE);
      return(false);
     }
//---
   m_data_total=CopyBuffer(handle,num,-m_offset,m_size,m_data);
//---
   return(m_data_total>0);
  }
 
Dmitriy Gizlyk #:

In der Standard-Indikatorenklasse wird bei der Datenaktualisierung die Funktion CopyBuffer verwendet. Das heißt, sie füllt den gesamten Puffer aus der Terminal-Historie, nicht nur einen Teil davon.

Und die Neuberechnung der gesamten Historie bei jedem neuen Takt?

Ist das nicht zu aufwendig? Warum nicht das Datum der letzten Berechnung ermitteln und die Daten für diesen bestimmten Zeitraum kopieren?

 
Aleksey Vyazmikin #:

Und die ganze Geschichte bei jedem neuen Takt neu zu berechnen?

Ist das dann nicht zu aufwendig? Warum nicht das Datum der letzten Berechnung ermitteln und die Daten für diese Zeitspanne kopieren?

Ich entschuldige mich, der vorherige Beitrag bezog sich nicht auf den Artikel, sondern auf die Standardbibliothek.
Im Artikel wird der Indikator in der Methode Calculate berechnet. Hier wird zunächst die Anzahl der Balken der letzten Neuberechnung ermittelt und erst dann der restliche Teil neu berechnet.

  • cur_date - aktuelle Zeit;
  • m_last_calculate - Zeitpunkt der letzten Neuberechnung.

bool CMA::Calculate(void)
  {
   datetime cur_date=(datetime)SeriesInfoInteger(m_Symbol,m_Timeframe,SERIES_LASTBAR_DATE);
   if(m_last_calculate==cur_date && ArraySize(m_source_data)==m_history_len)
      return true;
//---
   if(!LoadHistory())
      return false;
//---
   int shift=Bars(m_Symbol,m_Timeframe,m_last_calculate,cur_date)-1;
 
Dmitriy Gizlyk #:

Ich entschuldige mich, der vorherige Beitrag bezog sich nicht auf den Artikel, sondern auf die Standardbibliothek.
Im Artikel wird der Indikator mit der Methode Calculate berechnet. Hier wird zunächst die Anzahl der Balken aus der letzten Neuberechnung ermittelt und erst dann der restliche Teil neu errechnet.

  • cur_date - aktuelle Zeit;
  • m_last_calculate - Zeitpunkt der letzten Neuberechnung.

Vielen Dank für die Klarstellung!

 

vielen Dank

Sehr schönes Konzept, aber wenn ich einen Preis-Aktion-Indikator mit mehreren Preisen (hoch, niedrig, schließen, öffnen), die Indikator-Wert berechnet, basierend auf z.B. Differenz von hoch und niedrig gibt es ein Problem der mit nur einem Array von Daten (m_source_data in CIndicator-Klasse), gibt es eine Möglichkeit, dies zu umgehen oder schlagen Sie vor, die CIndicator-Klasse zu ändern und die m_source_data ein Array von (mqlRates oder CArrayBuffer,...)?

 
Mehrdad Sarrafi Indikator-Wert berechnet, basierend auf z.B. Differenz von hoch und niedrig gibt es ein Problem der mit nur einem Array von Daten (m_source_data in CIndicator-Klasse), gibt es eine Möglichkeit, dies zu umgehen oder schlagen Sie vor, die CIndicator-Klasse zu ändern und die m_source_data ein Array von (mqlRates oder CArrayBuffer,...)?

Ja, Sie können CIndicator ändern, um m_source_data als Array von MqlRates zu erstellen. Ich empfehle MqlRates, weil Sie auf andere Weise einige Aktionen benötigen, um Daten in verschiedenen Arrays zu synchronisieren.