OnCalculate

Die Funktion wird von Indikatoren aufgerufen, wenn das Ereignis Calculate eintritt, um Preisänderungen abzuarbeiten. Es gibt zwei Versionen dieser Funktion. Aber nur eine kann von einem einzelnen Indikator verwendet werden.

Berechnung auf Basis eines Datenarrays

int  OnCalculate(
   const int        rates_total,       // Größe des Preisarrays price[]
   const int        prev_calculated,   // Anzahl der bearbeiteten Bars im letzten Aufruf
   const int        begin,             // Index für den Array price[] für den Beginn
   const double&    price[]            // Wertearray für die Berechnung
   );

Berechnung auf Basis der aktuellen Zeitreihendaten des Zeitrahmens

int  OnCalculate(
   const int        rates_total,       // Umfang der Zeitreihen
   const int        prev_calculated,   // Anzahl der bearbeiteten Bars im letzten Aufruf
   const datetime&  time{},            // Array der Zeit
   const double&    open[],            // Open Array
   const double&    high[],            // High Array
   const double&    low[],             // Low Array
   const double&    close[],           // Close Array
   const long&      tick_volume[],     // Tick Volume Array
   const long&      volume[],          // Real Volume Array
   const int&       spread[]           // Spread Array
   );

Parameter

rates_total

[in] Anzahl der dem Indikator für die Berechnung zur Verfügung stehenden Elemente der Preis-Arrays oder Eingabeserien. Im zweiten Funktionstyp entspricht der Parameterwert der Anzahl der Bars auf dem Chart, auf dem er gestartet wurde.

prev_calculated

[in] Ist der von OnCalculate() im letzten Aufruf zurückgegebenen Wert. Er wurde entwickelt, um die Bars zu überspringen, die sich seit dem letzten Aufruf dieser Funktion nicht geändert haben.

begin

[in] Indexwert im Array price[], ab dem die aussagekräftigen Daten beginnen. Damit können fehlende oder initiale Daten überspringen, für die es keine korrekten Werte gibt.

price[]

[in] Array von Werten für Berechnungen. Einer der Zeitreihen mit Preisen, aber auch ein berechneter Indikatorpuffer kann als Preis-Array übergeben werden. Die Art der zur Berechnung übergebenen Daten kann über die Funktion _AppliedTo vordefinierte Variable definiert werden.

time{}

[in] Array mit Eröffnungszeiten der Bars.

open[]

[in] Array mit Eröffnungspreisen der Bars.

high[]

[in]  Array mit den Hochs der Bars.

low[]

[in]  Array mit den Tiefs der Bars.

close[]

[in]  Array mit den Schlusskursen der Bars.

tick_volume[]

[in]  Array mit der Tick-Volumina der Bars.

volume[]

[in]  Array mit den Handelsvolumina der Bars.

spread[]

[in]  Array mit der Spreizung (spread) der Kurse der Bars.

Rückgabewert

Dieser ganzzahlige Rückgabewert wird mit dem Parameter prev_calculated dem nächsten Aufruf der Funktion übergeben.

Hinweis

Wenn die Funktion OnCalculate() gleich Null ist, werden im DataWindow des Client-Terminals keine Indikatorwerte angezeigt.

Wenn die Preisdaten seit dem letzten Aufruf der Funktion OnCalculate() geändert wurden (eine umfangreichere Historie wurde geladen oder Lücken in der Historie gefüllt), wird der Wert des Eingabeparameters prev_calculated vom Terminal selbst auf Null gesetzt.

Um die Richtung der Indexierung der Zeitreihen time[], open[], high[], low[], close[], tick_volume[], volume[] und spread[] festzulegen, rufen Sie die Funktion ArrayGetAsSeries() auf. Um nicht von Voreinstellungen abhängig zu sein, rufen Sie die Funktion ArraySetAsSeries() für die Arbeit mit den Arrays auf.

Bei Verwendung des ersten Funktionstyps wird beim Start des Indikators eine notwendige Zeitreihe oder ein Indikator vom Benutzer als Preis-Array[] im Register Parameter ausgewählt. Geben Sie dazu in der Auswahlliste des Feldes "Apply to" field." das gewünschte Element an.

Um die Werte eigener Indikatoren zu erhalten, die als mql5-Programme vorliegen, wird die Funktion iCustom() verwendet. Sie gibt das Handle des Indikator für die weiteren Operationen zurück. Es ist auch möglich, das gewünschte Preis-Array[] oder das Handle eines anderen Indikators anzugeben. Dieser Parameter sollte als letzter in der Liste der Eingabevariablen eines benutzerdefinierten Indikators übergeben werden.

Es ist notwendig, die Verbindung zwischen dem Rückgabewert der Funktion OnCalculate() und dem zweiten Eingabeparameter prev_calculated zu verwenden. Beim Aufruf der Funktion enthält der Parameter prev_calculated den Wert, den die Funktion OnCalculate() beim letzten Aufruf zurückgegeben hat. Dadurch ist es möglich, ressourcenschonende Algorithmen zur Berechnung eines benutzerdefinierten Indikators zu implementieren, um wiederholte Berechnungen für die Bars zu vermeiden, die sich seit dem letzten Start dieser Funktion nicht geändert haben.

 

Beispielindikator

//+------------------------------------------------------------------+
//|                                           OnCalculate_Sample.mq5 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property description "Sample Momentum indicator calculation"
 
//---- Indikatoreinstellungen
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
#property indicator_type1   DRAW_LINE
#property indicator_color1  Blue
//---- Eingaben
input int MomentumPeriod=14; // Calculation period
//---- Indikatorpuffer
double    MomentumBuffer[];
//--- globale Variable zur Speicherung der Berechnungsperioden
int       IntPeriod;
//+------------------------------------------------------------------+
//| Initialisierungsfunktion eine nutzerdefinierten Indikators       |
//+------------------------------------------------------------------+
void OnInit()
  {
//--- Prüfen der Eingabeparameter
   if(MomentumPeriod<0)
     {
      IntPeriod=14;
      Print("Period parameter has an incorrect value. The following value is to be used for calculations ",IntPeriod);
     }
   else
      IntPeriod=MomentumPeriod;
//---- Puffer  
   SetIndexBuffer(0,MomentumBuffer,INDICATOR_DATA);
//---- Indikatorname zur Anzeige im DataWindow und im Unterfenster
   IndicatorSetString(INDICATOR_SHORTNAME,"Momentum"+"("+string(IntPeriod)+")");
//--- Setzen des Index der Bar, mit der das Zeichnen beginnt
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,IntPeriod-1);
//--- setzen von 0.0 als 'empty value', der nicht gezeichnet wird
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
//--- Indikatorgenauigkeit für die Anzeige
   IndicatorSetInteger(INDICATOR_DIGITS,2);
  }
//+------------------------------------------------------------------+
//|  Berechnung des Indikators Momentum                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,     // Größe des Arrays price[]
                const int prev_calculated, // Anzahl der vorher bearbeiteten Bars
                const int begin,           // Beginn der signifikanten Bars
                const double &price[])     // Array mit den Werten für die Berechnung
  {
//--- erste Position für die Berechnung
   int StartCalcPosition=(IntPeriod-1)+begin;
//---- bei ungenügenden Daten für die Berechnung
   if(rates_total<StartCalcPosition)
      return(0);  // exit with a zero value - the indicator is not calculated
//--- Korrektur des Beginns der Zeichnung
   if(begin>0)
      PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,StartCalcPosition+(IntPeriod-1));
//--- Beginn der Berechnung, definieren der Startposition
   int pos=prev_calculated-1;
   if(pos<StartCalcPosition)
      pos=begin+IntPeriod;
//--- Hauptschleife der Berechnung
   for(int i=pos;i<rates_total && !IsStopped();i++)
      MomentumBuffer[i]=price[i]*100/price[i-IntPeriod];
//--- OnCalculate Ausführung ist beendet Rückgabe des neuen Wertes von prev_calculated für den nächsten Aufruf
   return(rates_total);
  }

Siehe auch

ArrayGetAsSeries, ArraySetAsSeries, iCustom, Ereignisbearbeiter, Durchführung der Programme, Ereignisse des Client-Terminals, Zugang zu Zeitreihen und Daten der Indikatoren