Richtung des Indizierens in Feldern, Puffern und Zeitreihen

Alle Felder und Indikatorpuffer haben als Vorgabe die Richtung des Indizierens von links nach rechts. Index des ersten Elementes ist immer der Null gleich. So befindet sich das erste Element eines Feldes oder eines Indikatorpuffers mit Index 0 als Vorgabe an der linken Grenzstelle, das letzte Element befindet sich an der rechten Grenzstelle.

Indikatorpuffer ist ein dynamisches Feld des Typs double, dessen Größe vom Client-Terminal verwaltet wird, damit er der Anzahl von Bars entspricht, die für Berechnung des Indikators verwendet werden.  Das normale dynamische Feld des Typs double wird als Indikatorpuffer durch die Funktion SetIndexBuffer() vorgegeben. Für Indikatorpuffer braucht man nicht die Größe durch die Funktion ArrayResize() vorgeben, das ausführende System des Terminals wird das selbsstaendig machen.  

Zeitreihen sind Felder mit dem umgekehrten Indizieren, d.h. das erste Element einer Zeitreihe befindet sich an der linken Grenzstelle, das letzte Element befindet sich an der rechten Grenzstelle. Da Zeitreihen dafür bestimmt sind, historische Preisdaten für Finanzinstrumente aufzubewahren und unbedingt zeitbezogene Information enthalten, kann man sagen, dass sich die neuesten  Daten in der Zeitreihe an der rechten Grenzstelle und die aeltesten an der linken Grenzstelle befinden.

Darum hat Element mit Index 0 in der Zeitreihe Information über die letzte Quotation für Instrument. Wenn eine Zeitreihe Daten für für taegliches Timeframe darstellt, werden in der Null-Position Daten des laufenden nicht beendeten Tages geben, und in der Position mit Index 1 werden Daten von gestern aufbewahren.

Veränderung der Richtung des Indizierens  

Funktion ArraySetAsSeries() erlaubt Zugangsverfahren zu Elementen eines dynamischen Feldes zu verändern, dabei wird die Ordnung der Datenaufbewahrung im Computerspeicher physisch nicht verändert. Die Funktion verändert Adressierungsart zu Feldelementen, darum wird der Inhalt des Feld-Rezipienten beim Kopieren eines Feldes in ein anderes Feld durch die Funktion ArrayCopy() nicht von der Richtung des Indizierens im Feld-Quelle abhängen.

Man darf nicht Richtung des Indizierens für statisch verteilte Felder verändern. Auch wenn ein Feld als Parameter in die Funktion übertragen wurde, werden die Versuche, Indizieren innerhalb dieser Funktion zu verändern, zum nichts führen.  

für Indikatorpuffer ist es auch wie für normale Felder moeglich, Richtung des Indizierens umgekehrt wie in einer Zeitreihe einzustellen, d.h. Zugang zur Null-Position in Indikatorpuffer wird Zugang zum letzten Wert im entsprechenden Indikatorpuffer bedeuten und das wird dem Indikatorwert in der allerletzten Bar entsprechen.  Dabei wird physisch Ordnung der Daten im Indikatorpuffer nicht verändern, wie es schon erwaehnt wurde.

Erhalten von Preisdaten in Indikatoren

Jeder Benutzerindikator muss unbedingt die Funktion OnCalculate() haben, der Preisdaten übertragen werden, die für Berechnung der Werte in Indikatorpuffern notwendig sind. Richtung des Indizierens in diesen übertragenen Feldern kann man durch die Funktion ArrayGetAsSeries() erfahren .

Die in die Funktion übertragenen Felder stellen Preisdaten dar, d.h. diese Felder haben das Zeichen der Zeitreihe und die Funktion ArrayIsSeries() gibt true bei der Pruefung dieser Felder zurück. Aber Richtung des Indizierens muss auf jeden Fall nur durch die Funktion ArrayGetAsSeries() geprueft werden.

Um nicht von den Default-Werten abhängig zu sein, muss man die Funktion ArraySetAsSeries() für die Felder aufrufen, mit denen es zu arbeiten soll und die notwendige Richtung des Indizierenz einstellen.  

Erhalten von Preisdaten und Indikatorwerten

In Experten, Indikatoren und Scripts haben alle Felder als Default die Richtung des Indizierens von links nach rechts. Wenn notwendig können die Werte der Zeitreihen für jedes Symbol und Timeframe in jedem mql5-Programm angefordert werden aber auch Indikatorwerte, die in jedem  Symbol und Timeframe berechnet werden können.

für Erhaltung dieser Daten sind die Funktionen  Copy...() bestimmt:

  • CopyBuffer – Kopieren der Werte des Indikatorpuffers ins Feld des Typs double;
  • CopyRates – Kopieren der Preisgeschichte ins Feld der Strukturen MqlRates;
  • CopyTime – Kopieren der Werte Time ins Feld des Typs datetime;
  • CopyOpen – Kopieren der Werte Open ins Feld des Typs double;
  • CopyHigh –Kopieren der Werte High ins Feld des Typs double;
  • CopyLow – Kopieren der Werte Low ins Feld des Typs double;
  • CopyClose – Kopieren der Werte Close ins Feld des Typs double;
  • CopyTickVolume – Kopieren der Tickvolumen ins Feld des Typs long;
  • CopyRealVolume – Kopieren der Boersenvolumen ins Feld des Typs long;
  • CopySpread – Kopieren der Spreadgeschichte ins Feld des Typs int;

 

Alle diese Funktionen funktioniren gleich, darum reicht es, Mechanismuss der Datenerhaltung am Beispiel CopyBuffer() zu betrachten.  Es wird angenommen, dass alle angeforderten Daten dieselbe Richtung des Indizierens haben, wie in der Zeitreihe, dabei wird angenommen, dass in der Position mit Index 0 (Null) Daten der unbeendeten Bar aufbewahren werden. Für Erhaltung des Zuganges zu diesen Daten muss man das notwendige Volumen ins Feld-Rezipient kopieren, ZB ins Feld buffer.

copyBuffer

Beim Kopieren ist es notwendig, Startposition im Ausgangsfeld anzugeben, von der Daten ins Feld-Rezipient kopiert werden. Im Erfolgsfall wird ins Feld-Rezipient die angegebene Anzahl der Elementen vom Ausgangsfeld kopiert, in diesem Fall vom Indikatorpuffer. Dabei wird Kopieren immer so durchgeführt, wie es auf dem Bild gezeigt, unabhängig davon, welche Richtung des Indizierens im Feld-Rezipient angegeben wird.

Wenn Preisdaten voraussichtlich in einer Schleife mit einer großen Anzahl von Iterationen behandelt werden, ist es ratsam, dass Sie die Tatsache der erzwungenen Beendigung des Programms mit der Funktion IsStopped() überprüfen:

int copied=CopyBuffer(ma_handle,// Handle von Indikator
                      0,        // Index der Indikator-Puffer
                      0,        // Startposition für das Kopieren
                      number,   // Anzahl der Werten für das Kopieren 
                      Buffer    // Das Array, das die Werte erhält
                      );
if(copied<0) return;
int k=0;
while(k<copied && !IsStopped())
  {
   //--- Erhalten den Wert für den Index k
   double value=Buffer[k];
   // ... 
   // Arbeit mit dem Wert value
   k++;
  }

Beispiel:

input int per=10; // Periode der Exponente
int ma_handle;    // handle des Indikators 
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   ma_handle=iMA(_Symbol,0,per,0,MODE_EMA,PRICE_CLOSE);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   double ema[10];
   int copied=CopyBuffer(ma_handle,// handle des Indikators  
                         0,        // Index des Indikatorpuffers  
                         0,        // Anfangsposition für Kopieren  
                         10,       // Anzahl der Werte für Kopieren  
                         ema       // Feld-Rezipient der Werte 
                         );
   if(copied<0) return;
// .... weiterer Kode             
  }

Sehen Sie auch

Datenzugang organisieren