Preise in der DoEasy-Bibliothek (Teil 61): Kollektion der Tickserien eines Symbols

23 März 2021, 15:13
Artyom Trishkin
2
169

Inhalt


Konzept

Im vorherigen Artikel, habe ich die Objektklasse der Liste der Tickdaten erstellt, um die Ticks eines Symbols für eine bestimmte Anzahl von Tagen zu sammeln und zu speichern. Da ein Programm bei seiner Arbeit verschiedene Symbole verwenden kann, sollte für jedes dieser Symbole eine eigene Liste erstellt werden. In diesem Artikel werde ich solche Listen zu einer Tickdatenkollektion zusammenfassen. Dies wird eine reguläre Liste sein, die auf der Klasse des dynamischen Arrays von Zeigern auf Instanzen der CObject-Klasse und ihrer Abkömmlinge der Standardbibliothek basiert. Die Liste soll die Zeiger auf erstellte Tick-Datenlisten für jedes Symbol speichern, dessen Objektklasse ich im vorherigen Artikel vorbereitet habe.

Das Konzept ist identisch mit dem des Aufbaus der vorherigen Sammelklassen in der Bibliothek. Es wird uns erlauben, Tick-Daten von beliebigen Symbolen, die in der Datenbank der Bibliothek vorhanden sind, zu speichern, zu aktualisieren, zu empfangen und in der statistischen Analyse zu verwenden.


Kollektionsklasse der Tickdaten

Erstellen wir in \MQL5\Include\DoEasy\Collections\ eine neue Kollektionsklasse der Tickdaten namens TickSeriesCollection.mqh.

Die Klasse soll von der Klasse des Basisobjekts aller Bibliotheksobjekte abgeleitet werden.

Werfen wir einen Blick auf den Klassenkörper und analysieren wir seine Variablen und Methoden:

//+------------------------------------------------------------------+
//|                                         TickSeriesCollection.mqh |
//|                        Copyright 2021, MetaQuotes Software Corp. |
//|                             https://mql5.com/en/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Software Corp."
#property link      "https://mql5.com/en/users/artmedia70"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Include files                                                    |
//+------------------------------------------------------------------+
#include "ListObj.mqh"
#include "..\Objects\Ticks\TickSeries.mqh"
#include "..\Objects\Symbols\Symbol.mqh"
//+------------------------------------------------------------------+
//| Collection of symbol tick series                                 |
//+------------------------------------------------------------------+
class CTickSeriesCollection : public CBaseObj
  {
private:
   CListObj                m_list;                                   // List of used symbol tick series
//--- Return the tick series index by symbol name
   int                     IndexTickSeries(const string symbol);
public:
//--- Return (1) itself and (2) tick series collection list and (3) the number of tick series in the list
   CTickSeriesCollection  *GetObject(void)                              { return &this;               }
   CArrayObj              *GetList(void)                                { return &this.m_list;        }
   int                     DataTotal(void)                        const { return this.m_list.Total(); }
//--- Return the pointer to the tick series object (1) by symbol and (2) by index in the list
   CTickSeries            *GetTickseries(const string symbol);
   CTickSeries            *GetTickseries(const int index);
//--- Create a collection list of symbol tick series
   bool                    CreateCollection(const CArrayObj *list_symbols,const uint required=0);
//--- Set the flag of using the tick series of (1) a specified symbol and (2) all symbols
   void                    SetAvailableTickSeries(const string symbol,const bool flag=true);
   void                    SetAvailableTickSeries(const bool flag=true);
//--- Return the flag of using the tick series of (1) a specified symbol and (2) all symbols
   bool                    IsAvailableTickSeries(const string symbol);
   bool                    IsAvailableTickSeries(void);

//--- Set the number of days of the tick history of (1) a specified symbol and (2) all symbols
   bool                    SetRequiredUsedDays(const string symbol,const uint required=0);
   bool                    SetRequiredUsedDays(const uint required=0);

//--- Return the last tick object of a specified symbol (1) by index, (2) by time and (4) by time in milliseconds
   CDataTick              *GetTick(const string symbol,const int index);
   CDataTick              *GetTick(const string symbol,const datetime tick_time);
   CDataTick              *GetTick(const string symbol,const long tick_time_msc);

//--- Return the new tick flag of a specified symbol
   bool                    IsNewTick(const string symbol);

//--- Create a tick series of (1) a specified symbol and (2) all symbols
   bool                    CreateTickSeries(const string symbol,const uint required=0);
   bool                    CreateTickSeriesAll(const uint required=0);
//--- Update (1) a tick series of a specified symbol and (2) all symbols
   void                    Refresh(const string symbol);
   void                    Refresh(void);

//--- Display (1) the complete and (2) short collection description in the journal
   void                    Print(void);
   void                    PrintShort(void);
   
//--- Constructor
                           CTickSeriesCollection();
  };
//+------------------------------------------------------------------+

Die Klassenvariable der Klasse m_list ist vom Typ CListObj — die Klasse, die ein Abkömmling der Klasse CArrayObj der Standardbibliothek ist, genau wie viele andere in der Bibliothek erstellte Listen. Die einzige Aufgabe der Klasse CListObj ist es, die Arbeit der virtuellen Methode Type() der Klasse CObject zu implementieren — die Basisklasse der Objekte der Standardbibliothek. Die Methode soll die Typ-ID der Klasse zurückgeben. In diesem Fall ist es die Array-Typ-ID.
Die virtuelle Methode Type() ist in der Klasse CListObj implementiert, die schon vor längerer Zeit zur Bibliothek hinzugefügt wurde:

//+------------------------------------------------------------------+
//|                                                      ListObj.mqh |
//|                        Copyright 2019, MetaQuotes Software Corp. |
//|                             https://mql5.com/en/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link      "https://mql5.com/en/users/artmedia70"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Include files                                                    |
//+------------------------------------------------------------------+
#include <Arrays\ArrayObj.mqh>
//+------------------------------------------------------------------+
//| Class of collection lists                                        |
//+------------------------------------------------------------------+
class CListObj : public CArrayObj
  {
private:
   int               m_type;                    // List type
public:
   void              Type(const int type)       { this.m_type=type;     }
   virtual int       Type(void)           const { return(this.m_type);  }
                     CListObj()                 { this.m_type=0x7778;   }
  };
//+------------------------------------------------------------------+

Hier weist die Methode Type() den übergebenen Wert der Variablen m_type zu, während die virtuelle Methode Type() den durch diese Variable gesetzten Wert zurückgibt.

Standardmäßig (im Klassenkonstruktor) erhält die Variable den gleichen Wert der Array-Typ-ID wie bei CArrayObj — 0x7778.

Der Zweck aller Klassenmethoden ist in den Codekommentaren beschrieben. Die Implementierung dieser Methoden werde ich im Folgenden beschreiben.

Im Klassenkonstruktor wird die Liste gelöscht, das Flag für sortierte Liste gesetzt und die Listen-ID für Tick-Datensammlung definiert:

//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CTickSeriesCollection::CTickSeriesCollection()
  {
   this.m_list.Clear();
   this.m_list.Sort();
   this.m_list.Type(COLLECTION_TICKSERIES_ID);
  }
//+------------------------------------------------------------------+

Die 'private' Methode IndexTickSeries() gibt den Index der Tickserie des Symbolnamens zurück:

//+------------------------------------------------------------------+
//| Return the tick series index by symbol name                      |
//+------------------------------------------------------------------+
int CTickSeriesCollection::IndexTickSeries(const string symbol)
  {
   const CTickSeries *obj=new CTickSeries(symbol==NULL || symbol=="" ? ::Symbol() : symbol);
   if(obj==NULL)
      return WRONG_VALUE;
   this.m_list.Sort();
   int index=this.m_list.Search(obj);
   delete obj;
   return index;
  }
//+------------------------------------------------------------------+

Die Methode erhält den Namen des Symbols, dessen Tickserienindex aus der Liste zurückgegeben werden soll.
Als Nächstes wird ein temporäres leeres Objekt der Tickserie erzeugt. Es soll den Namen eines Symbols haben, der der Methode übergeben wird.
Wir setzen das Flag für die sortierte Liste und
und suchen den Objektindex in der Liste.
Anschließend wird eine temporäres Objekt entfernt und der erhaltene Index übermittelt. Wenn das Objekt nicht gefunden wird oder die Erstellung eines temporären Objekts fehlgeschlagen ist, gibt die Methode NULL zurück.

Die Methode gibt den Zeiger auf das Objekt der Tickserien des Symbols zurück:

//+------------------------------------------------------------------+
//| Return the object of tick series of a specified symbol           |
//+------------------------------------------------------------------+
CTickSeries *CTickSeriesCollection::GetTickseries(const string symbol)
  {
   int index=this.IndexTickSeries(symbol);
   return this.m_list.At(index);
  }
//+------------------------------------------------------------------+

Die Methode erhält den Namen des Symbols, dessen Objekt der Tickserien aus der Liste zurückgegeben werden soll.
Benutzen wir die eben beschriebene Methode, um den Index des Tickserien-Objekts in der Liste zu finden, um den Zeiger auf das Objekt durch den gefundenen Index zu erhalten und diesen zurückzugeben. Wenn der Index nicht gefunden wird, ist er gleich -1, während die NULL zurückgibt.

Die Methode setzt das Flag der Verwendung der Tickserie des angegebenen Symbols:

//+------------------------------------------------------------------+
//| Set the flag of using the tick series of a specified symbol      |
//+------------------------------------------------------------------+
void CTickSeriesCollection::SetAvailableTickSeries(const string symbol,const bool flag=true)
  {
   CTickSeries *tickseries=this.GetTickseries(symbol);
   if(tickseries==NULL)
      return;
   tickseries.SetAvailable(flag);
  }
//+------------------------------------------------------------------+

Die Methode erhält einen Namen des Symbols, dessen Objekt der Tickserie das Verwendungsflag erhalten soll.
Mit der oben beschriebenen Methode GetTickseries() wird der Zeiger auf das Tickserien-Objekt aus der Liste geholt und das an die Methode übergebene Flag auf dieses gesetzt.

Die Methode setzt das Verwendungsflag von Tickserien aller Kollektionssymbole:h

//+------------------------------------------------------------------+
//| Set the flag of using the tick series of all symbols             |
//+------------------------------------------------------------------+
void CTickSeriesCollection::SetAvailableTickSeries(const bool flag=true)
  {
   for(int i=0;i<this.m_list.Total();i++)
     {
      CTickSeries *tickseries=this.m_list.At(i);
      if(tickseries==NULL)
         continue;
      tickseries.SetAvailable(flag);
     }
  }
//+------------------------------------------------------------------+

In der Schleife über die Gesamtzahl der Tickserien in der Liste, holen wir das nächste Objekt der Tickserien durch den Schleifenindex und setzen das der Methode übergebene Flag dafür.

Die Methode gibt das Flag der Verwendung der Tickserien des angegebenen Symbols zurück:

//+------------------------------------------------------------------+
//| Return the flag of using the tick series of a specified symbol   |
//+------------------------------------------------------------------+
bool CTickSeriesCollection::IsAvailableTickSeries(const string symbol)
  {
   CTickSeries *tickseries=this.GetTickseries(symbol);
   if(tickseries==NULL)
      return false;
   return tickseries.IsAvailable();
  }
//+------------------------------------------------------------------+

Die Methode erhält einen Namen des Symbols, dessen Verwendungsflag des Objekts der Tickserien zurückgegeben werden soll.
Wir verwenden die Methode GetTickseries(), um den Zeiger auf das Tickserien-Objekt des benötigten Symbols zu erhalten, und um das für dieses Objekt gesetzte Verwendungsflag zurückzugeben. Wenn es nicht gelingt, das Objekt aus der Liste zu holen, gibt die Methode false zurück.

Die Methode gibt das Flag der Verwendung der Tickserien aller Symbole zurück:

//+------------------------------------------------------------------+
//| Return the flag of using tick series of all symbols              |
//+------------------------------------------------------------------+
bool CTickSeriesCollection::IsAvailableTickSeries(void)
  {
   bool res=true;
   int total=this.m_list.Total();
   for(int i=0;i<total;i++)
     {
      CTickSeries *tickseries=this.m_list.At(i);
      if(tickseries==NULL)
         continue;
      res &=tickseries.IsAvailable();
     }
   return res;
  }
//+------------------------------------------------------------------+

Wir deklarieren die Variable res und initialisieren sie mit dem Wert true.
Als Nächstes holen wir uns in der Schleife über die Gesamtzahl der Objekte in der Liste, den Zeiger auf das nächste Tickserien-Objekt und addieren das für das aktuelle Objekt definierte Verwendungsflag in die Variable res.
Nach Abschluss der Schleife geben wir den erhaltenen Wert res zurück.

Wenn für mindestens eines der Objekte in der Liste kein Verwendungsflag gesetzt ist (false), speichert res nach Abschluss der Schleife false. Die Methode erlaubt es also zu wissen, ob die Verwendungsflags für alle Tickserien gesetzt sind. True wird nur zurückgegeben, wenn die Verwendungsflags für jedes Tickserien-Objekt in der Kollektion auf true gesetzt sind.

Die Methode setzt die Anzahl der Tage der Tick-Historie des angegebenen Symbols:

//+------------------------------------------------------------------+
//| Set the number of days of the tick history of a specified symbol |
//+------------------------------------------------------------------+
bool CTickSeriesCollection::SetRequiredUsedDays(const string symbol,const uint required=0)
  {
   CTickSeries *tickseries=this.GetTickseries(symbol);
   if(tickseries==NULL)
      return false;
   tickseries.SetRequiredUsedDays(required);
   return true;
  }
//+------------------------------------------------------------------+

Die Methode erhält einen Namen des Symbols, dessen Anzahl der Tick-Daten-Tage gesetzt werden soll.
Erhalt des Zeigers auf das Tickserien-Objekt mit der zuvor betrachteten Methode, Setzen der Anzahl der Tage und der Rückgabe von true.
Wenn es nicht gelingt, den Zeiger auf das Tickserien-Objekt aus der Liste zu holen, gibt die Methode false zurück.

Die Methode setzt die Anzahl der Tage der Tick-Historie aller Symbole:

//+------------------------------------------------------------------+
//| Set the number of days of the tick history of all symbols        |
//+------------------------------------------------------------------+
bool CTickSeriesCollection::SetRequiredUsedDays(const uint required=0)
  {
   bool res=true;
   for(int i=0;i<this.m_list.Total();i++)
     {
      CTickSeries *tickseries=this.m_list.At(i);
      if(tickseries==NULL)
        {
         res &=false;
         continue;
        }
      tickseries.SetRequiredUsedDays(required);
     }
   return res;
  }
//+------------------------------------------------------------------+

Wir deklarieren die Variable res und initialisieren sie mit dem Wert true.
Als Nächstes, in der Schleife über die Gesamtzahl der Objekte in der Liste, holen wir uns den Zeiger auf das nächste Tickserien-Objekt und, wenn es nicht gelingt, erhält die Variable res den Wert false. Dann geht es weiter zum nächsten Objekt in der Kollektionsliste.
Ansonsten setzen wir die Anzahl der Tage für die Tickdaten für das aktuelle Objekt.
Nach Abschluss der Schleife geben wir den erhaltenen Wert res zurück.

Wenn die Anzahl der Tage der Tickdaten für mindestens eines der Objekte in der Liste nicht gesetzt ist, speichert res nach Abschluss der Schleife false. Die Methode erlaubt also das Setzen der Anzahl der Tage für alle Tickserien in der Kollektion und gibt eine erfolgreiche Ausführung nur dann zurück, wenn die Anzahl der Tage für jedes in der Liste gespeicherte Tick-Datenobjekt gesetzt ist.

Die Methode gibt das Tick-Objekt des angegebenen Symbols per Index in der Tickserien-Liste zurück:

//+------------------------------------------------------------------+
//| Return the tick object of the specified symbol by index          |
//+------------------------------------------------------------------+
CDataTick *CTickSeriesCollection::GetTick(const string symbol,const int index)
  {
   CTickSeries *tickseries=this.GetTickseries(symbol);
   if(tickseries==NULL)
      return NULL;
   return tickseries.GetTickByListIndex(index);
  }
//+------------------------------------------------------------------+

Die Methode übergibt das Tickserien-Symbol der CTickSeries-Klasse und den Index des benötigten Tick-Objekts, das in der Tickserien-Liste gespeichert ist.
Holen wir den Zeiger auf das Tickserien-Objekt aus der Symbol-Kollektion mit der zuvor beschriebenen Methode GetTickseries() und geben des Zeigers auf das Tick-Objekt aus der Tickserien-Liste mit der Methode GetTickByListIndex() zurück, die ich im vorherigen Artikel besprochen habe.

Wenn es nicht gelingt, das Tickserien-Objekt zu erhalten, gibt die Methode NULL zurück. NULL kann auch die Methode GetTickByListIndex() der Klasse CTickSeries zurückgeben.

Die Methode gibt das letzte Tick-Objekt des angegebenen Symbols nach Zeit aus der Tickserienliste zurück:

//+------------------------------------------------------------------+
//| Return the last tick object of the specified symbol by time      |
//+------------------------------------------------------------------+
CDataTick *CTickSeriesCollection::GetTick(const string symbol,const datetime tick_time)
  {
   CTickSeries *tickseries=this.GetTickseries(symbol);
   if(tickseries==NULL)
      return NULL;
   return tickseries.GetTick(tick_time);
  }
//+------------------------------------------------------------------+

Die Methode übergibt das Tickserien-Symbol der CTickSeries-Klasse und die Zeit des benötigten Tick-Objekts, das in der Tickserien-Liste gespeichert ist.
Wir holen den Zeiger auf das Tickserien-Objekt aus der Kollektion der Symbole mit der zuvor beschriebenen Methode GetTickseries() und geben den Zeiger auf das Tick-Objekt aus der Tickserien-Liste mit der Methode GetTick() zurück, die ich im vorherigen Artikel besprochen habe.

Wenn es nicht gelingt, das Tickserien-Objekt zu erhalten, gibt die Methode NULL zurück. Außerdem kann NULL auch die Methode GetTick() der Klasse CTickSeries zurückgeben.

Die Methode gibt das letzte Tick-Objekt des angegebenen Symbols nach Zeit in Millisekunden aus der Tickserienliste zurück:

//+------------------------------------------------------------------+
//| Return the last tick object of the specified symbol              |
//| by time in milliseconds                                          |
//+------------------------------------------------------------------+
CDataTick *CTickSeriesCollection::GetTick(const string symbol,const long tick_time_msc)
  {
   CTickSeries *tickseries=this.GetTickseries(symbol);
   if(tickseries==NULL)
      return NULL;
   return tickseries.GetTick(tick_time_msc);
  }
//+------------------------------------------------------------------+

Die Methode empfängt das Tickserien-Symbol der CTickSeries-Klasse und die in der Tickserienliste gespeicherte Zeit des benötigten Tick-Objekts in Millisekunden.
Wir holen den Zeiger auf das Tickserien-Objekt aus der Kollektion der Symbole mit der zuvor beschriebenen Methode GetTickseries() und geben den Zeiger auf das Tick-Objekt aus der Tickserien-Liste mit der Methode GetTick() zurück, die ich im vorherigen Artikel besprochen habe.

Wenn es nicht gelingt, das Tickserien-Objekt zu erhalten, gibt die Methode NULL zurück. Außerdem kann NULL auch die Methode GetTick() der Klasse CTickSeries zurückgeben.

Für die letzten beiden Methoden, die Tick-Objekte nach Zeit zurückgeben, kann es mehrere Ticks mit einer ähnlichen Zeit geben, daher gibt die Methode GetTick() der Klasse CTickSeries den allerletzten (mit der neuesten Zeit) als den relevantesten zurück.

Die Methode, die das neue Tick-Flag eines angegebenen Symbols zurückgibt:

//+------------------------------------------------------------------+
//| Return the new tick flag of a specified symbol                   |
//+------------------------------------------------------------------+
bool CTickSeriesCollection::IsNewTick(const string symbol)
  {
   CTickSeries *tickseries=this.GetTickseries(symbol);
   if(tickseries==NULL)
      return false;
   return tickseries.IsNewTick();
  }
//+------------------------------------------------------------------+

Die Methode erhält einen Namen des Symbols, dessen neues Tick-Looking-Flag zurückgegeben werden soll.
Wir holen uns den Zeiger auf das Tickserien-Objekt aus der Symbolsammlung mit der zuvor beschriebenen Methode GetTickseries() und geben des Flags des neuen Ticks der Tickserie mit der Methode IsNewTick() der Klasse CTickSeries zurück, die wir im vorherigen Artikel besprochen haben.
Wenn es nicht gelingt, das Objekt der Tickserie zu erhalten, gibt die Methode false zurück.

Diese Fähigkeit ist in der Klasse CTickSeries noch nicht implementiert. Dies wird in den kommenden Artikeln nachgeholt.

Die Methode erzeugt eine Tickserie des angegebenen Symbols:

//+------------------------------------------------------------------+
//| Create a tick series of a specified symbol                       |
//+------------------------------------------------------------------+
bool CTickSeriesCollection::CreateTickSeries(const string symbol,const uint required=0)
  {
   CTickSeries *tickseries=this.GetTickseries(symbol);
   if(tickseries==NULL)
      return false;
   return(tickseries.Create(required)>0);
  }
//+------------------------------------------------------------------+

Die Methode erhält einen Namen des Symbols, dessen Tickserie erstellt werden soll, und die Anzahl der Tick-Datentage.
Wir holen und den Zeiger auf das Tickserien-Objekt aus der Symbolsammlung mit der zuvor beschriebenen Methode GetTickseries() und geben das Flag zurück, das anzeigt, dass die Methode Create() der Klasse CTickSeries einen Wert größer Null zurückgegeben hat (die Anzahl der erzeugten Tick-Objekte ist nicht Null).

Die Methode erzeugt Tickserien von allen verwendeten Symbolen:

//+------------------------------------------------------------------+
//| Create tick series of all symbols                                |
//+------------------------------------------------------------------+
bool CTickSeriesCollection::CreateTickSeriesAll(const uint required=0)
  {
   bool res=true;
   int total=this.m_list.Total();
   for(int i=0;i<total;i++)
     {
      CTickSeries *tickseries=this.m_list.At(i);
      if(tickseries==NULL)
         continue;
      res &=(tickseries.Create(required)>0);
     }
   return res;
  }
//+------------------------------------------------------------------+

Die Methode erhält die Anzahl der Tick-Datentage.
Wir deklarieren die Variable res und initialisieren sie mit dem Wert true.
Als Nächstes holen wir uns in der Schleife durch die Gesamtzahl der Objekte in der Liste den Zeiger auf das nächste Tickseries-Objekt und fügen das Flag, das anzeigt, dass der von der Methode Create() der Klasse CTickSeries zurückgegebene Wert größer als Null ist (die Tickseries wurde erstellt), in die Variable res ein.
Geben wir nach Abschluss der Schleife den erhaltenen Wert res zurück.

Wenn für mindestens eines der Objekte in der Liste keine Tickserie erzeugt wird, speichert res bei Schleifenabschluss false. Die Methode ermöglicht also die Erstellung von Tickserien-Kollektion für alle Symbole und gibt eine erfolgreiche Ausführung nur dann zurück, wenn für jedes in der Liste gespeicherte Tick-Datenobjekt Tickserien erstellt werden.

Die Methode aktualisiert die Tickserien des angegebenen Symbols:

//+------------------------------------------------------------------+
//| Update a tick series of a specified symbol                       |
//+------------------------------------------------------------------+
void CTickSeriesCollection::Refresh(const string symbol)
  {
   CTickSeries *tickseries=this.GetTickseries(symbol);
   if(tickseries==NULL)
      return;
   tickseries.Refresh();
  }
//+------------------------------------------------------------------+

Die Methode erhält einen Symbolnamen, dessen Tickserie aktualisiert werden soll.
Holen wir uns den Zeiger auf das Tickserien-Objekt aus der Symbolsammlung mit der zuvor beschriebenen Methode GetTickseries() und aktualisieren es mit der Methode Refresh() der Klasse CTickSeries.

Die Methode aktualisiert die Tickserien aller Symbole:

//+------------------------------------------------------------------+
//| Update tick series of all symbols                                |
//+------------------------------------------------------------------+
void CTickSeriesCollection::Refresh(void)
  {
   for(int i=0;i<this.m_list.Total();i++)
     {
      CTickSeries *tickseries=this.m_list.At(i);
      if(tickseries==NULL)
         continue;
      tickseries.Refresh();
     }
  }
//+------------------------------------------------------------------+

In der Schleife über die Gesamtzahl der Objekte in der Liste holen wir uns den Zeiger auf das nächste Tickserien-Objekt durch den Schleifenindex und aktualisieren die Serie mit der Methode Refresh() der Klasse CTickSeries.

Das Aktualisieren von Tickserien ist in der CTickSeries-Klasse noch nicht implementiert. Dies wird in den kommenden Artikeln nachgeholt.

Die Methode, die die vollständige Kollektionsliste an die Zeitschrift zurückgibt:

//+------------------------------------------------------------------+
//| Display complete collection description to the journal           |
//+------------------------------------------------------------------+
void CTickSeriesCollection::Print(void)
  {
   for(int i=0;i<this.m_list.Total();i++)
     {
      CTickSeries *tickseries=this.m_list.At(i);
      if(tickseries==NULL)
         continue;
      tickseries.Print();
     }
  }
//+------------------------------------------------------------------+

In der Schleife durch die Gesamtzahl der Objekte in der Liste holen wir uns den Zeiger auf das nächste Tickserien-Objekt durch den Schleifenindex und zeigen die vollständige Beschreibung der Tickserie im Journal an.

Die Methode, die die kurze Kollektionsliste in das Journal schreibt:

//+------------------------------------------------------------------+
//| Display the short collection description in the journal          |
//+------------------------------------------------------------------+
void CTickSeriesCollection::PrintShort(void)
  {
   for(int i=0;i<this.m_list.Total();i++)
     {
      CTickSeries *tickseries=this.m_list.At(i);
      if(tickseries==NULL)
         continue;
      tickseries.PrintShort();
     }
  }
//+------------------------------------------------------------------+

in der Schleife durch die Gesamtzahl der Objekte in der Liste holen wir uns den Zeiger auf das nächste Tickserien-Objekt durch den Schleifenindex und zeigen die Kurzbeschreibung der Tickserie im Journal an.

Die oben betrachteten Methoden sind für die Arbeit mit der bereits erstellten Kollektionsliste von Zeigern auf Tick-Datenobjekte verschiedener Symbole gedacht. Unsere Programme können unterschiedliche Symbole verwenden. Die folgende Methode dient dazu, das Kollektionsobjekt selbst zu erstellen, um alle benötigten Tickserien darin zu platzieren und die entsprechenden Zeiger aus der Kollektionsliste abzufragen, um mit ihnen zu arbeiten.

Die Methode, die die Kollektionsliste der Tickserien der Symbole erstellt:

//+------------------------------------------------------------------+
//| Create a collection list of symbol tick series                   |
//+------------------------------------------------------------------+
bool CTickSeriesCollection::CreateCollection(const CArrayObj *list_symbols,const uint required=0)
  {
//--- If an empty list of symbol objects is passed, exit
   if(list_symbols==NULL)
      return false;
//--- Get the number of symbol objects in the passed list
   int total=list_symbols.Total();
//--- Clear the tick series collection list
   this.m_list.Clear();
//--- In a loop by all symbol objects
   for(int i=0;i<total;i++)
     {
      //--- get the next symbol object
      CSymbol *symbol_obj=list_symbols.At(i);
      //--- if failed to get a symbol object, move on to the next one in the list
      if(symbol_obj==NULL)
         continue;
      //--- Create a new empty tick series object
      CTickSeries *tickseries=new CTickSeries();
      //--- If failed to create the tick series object, move on to the next symbol in the list
      if(tickseries==NULL)
         continue;
      //--- Set a symbol name for a tick series object
      tickseries.SetSymbol(symbol_obj.Name());
      //--- Set the sorted list flag for the tick series collection list
      this.m_list.Sort();
      //--- If the object with the same symbol name is already present in the tick series collection list, remove the tick series object
      if(this.m_list.Search(tickseries)>WRONG_VALUE)
         delete tickseries;
      //--- otherwise, there is no object with such a symbol name in the collection yet
      else
        {
         //--- Set the number of tick data days for a tick series object
         tickseries.SetRequiredUsedDays(required);
         //--- if failed to add the tick series object to the collection list, remove the tick series object
         if(!this.m_list.Add(tickseries))
            delete tickseries;
        } 
     }
//--- Return the flag indicating that the created collection list has a size greater than zero
   return this.m_list.Total()>0;
  }
//+------------------------------------------------------------------+

Die Methode ist recht einfach — sie erhält die Liste der im Programm verwendeten Symbole (die Liste existiert schon recht lange und wird beim Erstellen der Symbol-Zeitreihen-Kollektion verwendet). Als Nächstes wird in der Schleife durch die Gesamtzahl der Symbole ein neues Tickserien-Objekt erstellt und dessen Symbolname aus der Liste der Symbole an der aktuellen Schleifenposition gesetzt. Wenn das Tickserien-Objekt mit einem solchen Symbol noch nicht in der Liste vorhanden ist, setzen wir die Anzahl der an die Methode übergebenen Tick-Datentage und fügen das Objekt zur Kollektionsliste hinzu. Dies sollte für jedes Symbol in der Liste durchgeführt werden. Hier habe ich das System kurz skizziert. Wenn Sie tiefer einsteigen, sehen Sie die Prüfungen für das erfolgreiche Erstellen und Hinzufügen von Tickserien-Objekten zur Liste und das Löschen von nicht benötigten Objekten, falls erforderlich. Die gesamte Methodenlogik ist in ihrem Listing detailliert beschrieben. Ich überlass es Ihnen, sie zu analysieren.

Die Hauptbibliotheksklasse CEngine wird verwendet, um die erstellte Kollektion mit der "Außenwelt" zu verbinden.
Die Klasse ist in \MQL5\Include\DoEasy\Engine.mqh gespeichert.

Binden Sie die Datei in einer neu erstellten Klasse ein:

//+------------------------------------------------------------------+
//|                                                       Engine.mqh |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                             https://mql5.com/en/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://mql5.com/en/users/artmedia70"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Include files                                                    |
//+------------------------------------------------------------------+
#include "Services\TimerCounter.mqh"
#include "Collections\HistoryCollection.mqh"
#include "Collections\MarketCollection.mqh"
#include "Collections\EventsCollection.mqh"
#include "Collections\AccountsCollection.mqh"
#include "Collections\SymbolsCollection.mqh"
#include "Collections\ResourceCollection.mqh"
#include "Collections\TimeSeriesCollection.mqh"
#include "Collections\BuffersCollection.mqh"
#include "Collections\IndicatorsCollection.mqh"
#include "Collections\TickSeriesCollection.mqh"
#include "TradingControl.mqh"
//+------------------------------------------------------------------+

Wir deklarieren im 'private' Abschnitt der Klasse das Objekt der Kollektionsklasse der Tickserien:

//+------------------------------------------------------------------+
//| Library basis class                                              |
//+------------------------------------------------------------------+
class CEngine
  {
private:
   CHistoryCollection   m_history;                       // Collection of historical orders and deals
   CMarketCollection    m_market;                        // Collection of market orders and deals
   CEventsCollection    m_events;                        // Event collection
   CAccountsCollection  m_accounts;                      // Account collection
   CSymbolsCollection   m_symbols;                       // Symbol collection
   CTimeSeriesCollection m_time_series;                  // Timeseries collection
   CBuffersCollection   m_buffers;                       // Collection of indicator buffers
   CIndicatorsCollection m_indicators;                   // Indicator collection
   CTickSeriesCollection m_tick_series;                  // Collection of tick series
   CResourceCollection  m_resource;                      // Resource list
   CTradingControl      m_trading;                       // Trading management object
   CPause               m_pause;                         // Pause object
   CArrayObj            m_list_counters;                 // List of timer counters

Die Klasse verfügt über die Methode SetUsedSymbols(), mit der wir die Liste der im Programm zu verwendenden Symbole festlegen können.
Übergeben wir die Anzahl der Tage, die Tick-Daten haben sollen in der Bibliothek:

//--- Set the list of used symbols in the symbol collection and create the collection of symbol timeseries
   bool                 SetUsedSymbols(const string &array_symbols[],const uint required=0);

Standardmäßig wird Null übergeben (was einen Tag bedeutet) und in \MQL5\Include\DoEasy\Defines.mqh durch die Konstante TICKSERIES_DEFAULT_DAYS_COUNT gesetzt.

In der Methodenimplementierung fügen wir das Erstellen der Kollektion von Tickserien hinzu.

//+------------------------------------------------------------------+
//| Set the list of used symbols in the symbol collection            |
//| and create the symbol timeseries collection                      |
//+------------------------------------------------------------------+
bool CEngine::SetUsedSymbols(const string &array_symbols[],const uint required=0)
  {
   bool res=this.m_symbols.SetUsedSymbols(array_symbols);
   CArrayObj *list=this.GetListAllUsedSymbols();
   if(list==NULL)
      return false;
   res&=this.m_time_series.CreateCollection(list);
   res&=this.m_tick_series.CreateCollection(list,required);
   return res;
  }
//+------------------------------------------------------------------+

Jetzt werden zwei Kollektionen (Zeitreihen- und Tickserien-Kollektion) beim Aufruf der Methode aus dem Programm erzeugt.

Wir fügen im 'public' Teil der Klasse die Methoden für den Zugriff auf die Tickserien-Kollektionsklasse aus nutzerdefinierten Programmen hinzu:

//--- Copy the specified double property of the specified timeseries of the specified symbol to the array
//--- Regardless of the array indexing direction, copying is performed the same way as copying to a timeseries array
   bool                 SeriesCopyToBufferAsSeries(const string symbol,const ENUM_TIMEFRAMES timeframe,const ENUM_BAR_PROP_DOUBLE property,
                                                   double &array[],const double empty=EMPTY_VALUE)
                          { return this.m_time_series.CopyToBufferAsSeries(symbol,timeframe,property,array,empty);}


//--- Return (1) the tick series collection, (2) the list of tick series from the tick series collection
   CTickSeriesCollection *GetTickSeriesCollection(void)                       { return &this.m_tick_series;                                     }
   CArrayObj           *GetListTickSeries(void)                               { return this.m_tick_series.GetList();                            }


//--- Return (1) the buffer collection and (2) the buffer list from the collection 

Für den Moment reicht es aus, das Kollektionsobjekt der Tickserien selbst und die Kollektionsliste daraus dem Programm zurückzugeben.

Das ist im Moment alles, was wir brauchen, um die Tickserien-Kollektion zu erstellen.


Test

Um das Erstellen der Tickserien-Kollektion für den Symbolprogramm-Betrieb zu testen, nehme ich den EA aus dem vorherigen Artikel und speichere ihn in \MQL5\Experts\TestDoEasy\Part61\ als TestDoEasyPart61.mq5.

Da nun alle Tickserien aus der Bibliothek selbst verfügbar sind, entfernen wir die Einbindung ihrer Klassendatei im Programm:

//+------------------------------------------------------------------+
//|                                             TestDoEasyPart60.mq5 |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                             https://mql5.com/en/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://mql5.com/en/users/artmedia70"
#property version   "1.00"
//--- includes
#include <DoEasy\Engine.mqh>
#include <DoEasy\Objects\Ticks\TickSeries.mqh>
//--- enums

Im Bereich der globalen Programmvariablen entfernen wir die Objektvariablen "New tick" und das Datenobjekt Tickserie des aktuellen Symbols:

//--- global variables
CEngine        engine;
SDataButt      butt_data[TOTAL_BUTT];
string         prefix;
double         lot;
double         withdrawal=(InpWithdrawal<0.1 ? 0.1 : InpWithdrawal);
ushort         magic_number;
uint           stoploss;
uint           takeprofit;
uint           distance_pending;
uint           distance_stoplimit;
uint           distance_pending_request;
uint           bars_delay_pending_request;
uint           slippage;
bool           trailing_on;
bool           pressed_pending_buy;
bool           pressed_pending_buy_limit;
bool           pressed_pending_buy_stop;
bool           pressed_pending_buy_stoplimit;
bool           pressed_pending_close_buy;
bool           pressed_pending_close_buy2;
bool           pressed_pending_close_buy_by_sell;
bool           pressed_pending_sell;
bool           pressed_pending_sell_limit;
bool           pressed_pending_sell_stop;
bool           pressed_pending_sell_stoplimit;
bool           pressed_pending_close_sell;
bool           pressed_pending_close_sell2;
bool           pressed_pending_close_sell_by_buy;
bool           pressed_pending_delete_all;
bool           pressed_pending_close_all;
bool           pressed_pending_sl;
bool           pressed_pending_tp;
double         trailing_stop;
double         trailing_step;
uint           trailing_start;
uint           stoploss_to_modify;
uint           takeprofit_to_modify;
int            used_symbols_mode;
string         array_used_symbols[];
string         array_used_periods[];
bool           testing;
uchar          group1;
uchar          group2;
double         g_point;
int            g_digits;

//--- "New tick" object
CNewTickObj    check_tick;
//--- Object of the current symbol tick series data
CTickSeries    tick_series;
//+------------------------------------------------------------------+

Am Ende von OnInit() entfernen wir das Setzen des aktuellen Symbols für das Objekt "New tick":

//--- Wait for 600 milliseconds
   engine.Pause(600);
   engine.PlaySoundByDescription(TextByLanguage("Звук упавшей монетки 2","Falling coin 2"));

//--- Set the current symbol for "New tick" object
   check_tick.SetSymbol(Symbol());
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+

Entfernen wir den Codeblock zur Überprüfung der Erstellung einer Tickserie des aktuellen Symbols aus der Funktion OnInitDoEasy():

//--- Check created timeseries - display descriptions of all created timeseries in the journal
//--- (true - only created ones, false - created and declared ones)
   engine.GetTimeSeriesCollection().PrintShort(false); // Short descriptions
   //engine.GetTimeSeriesCollection().Print(true);      // Full descriptions

//--- Code block for checking the tick list creation and working with it
   Print("");
//--- Since the tick series object is created with the default constructor,
//--- set a symbol, usage flag and the number of days (the default is 1) to copy the ticks
//--- Create the tick series and printed data in the journal
   tick_series.SetSymbol(Symbol());
   tick_series.SetAvailable(true);
   tick_series.SetRequiredUsedDays();
   tick_series.Create();
   tick_series.Print();
   
   Print("");
//--- Get and display in the journal the data of an object with the highest Ask price in the daily price range
   int index_max=CSelect::FindTickDataMax(tick_series.GetList(),TICK_PROP_ASK);
   CDataTick *tick_max=tick_series.GetList().At(index_max);
   if(tick_max!=NULL)
      tick_max.Print();
//--- Get and display in the journal the data of an object with the lowest Bid price in the daily price range
   int index_min=CSelect::FindTickDataMin(tick_series.GetList(),TICK_PROP_BID);
   CDataTick *tick_min=tick_series.GetList().At(index_min);
   if(tick_min!=NULL)
      tick_min.Print();

//--- Create resource text files

Nun müssen wir hier die Erstellung von Tickserien für alle Symbole der erstellten Tick-Datensammlung einstellen:

//--- Check created timeseries - display descriptions of all created timeseries in the journal
//--- (true - only created ones, false - created and declared ones)
   engine.GetTimeSeriesCollection().PrintShort(false); // Short descriptions
   //engine.GetTimeSeriesCollection().Print(true);      // Full descriptions

//--- Create tick series of all used symbols
   engine.GetTickSeriesCollection().CreateTickSeriesAll();
//--- Check created tick series - display descriptions of all created tick series in the journal
   engine.GetTickSeriesCollection().Print();

//--- Create resource text files

In OnTick() wird beim Eintreffen eines neuen Ticks versucht, für jedes Symbol ein Tick-Objekt mit dem höchsten Ask- und dem niedrigsten Bid-Preis in den Tick-Datenlisten zu finden, sowie die Parameter jedes gefundenen Tick-Objekts im Journal anzuzeigen:

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- Handle the NewTick event in the library
   engine.OnTick(rates_data);

//--- If working in the tester
   if(MQLInfoInteger(MQL_TESTER))
     {
      engine.OnTimer(rates_data);   // Working in the timer
      PressButtonsControl();        // Button pressing control
      engine.EventsHandling();      // Working with events
     }

//--- If the trailing flag is set
   if(trailing_on)
     {
      TrailingPositions();          // Trailing positions
      TrailingOrders();             // Trailing pending orders
     }
     
//--- Check created tick data on the first tick
//--- Get and display in the journal the data of an object with the highest Ask price and the lowest Bid price in the daily price range
   static bool check=false;
   if(!check)
     {
      Print("");
      //--- Get the pointer to the list of tick data of all symbols from the tick collection
      CArrayObj* list=engine.GetTickSeriesCollection().GetList();
      int total=engine.GetTickSeriesCollection().DataTotal();
      //--- In the loop by the number of tick series in the collection
      for(int i=0;i<list.Type();i++)
        {
         //--- Get the next tick series from the collection by index
         CTickSeries *tick_series=engine.GetTickSeriesCollection().GetTickseries(i);
         if(tick_series!=NULL)
           {
            //--- In the obtained tick series, find the indices of tick objects with the highest Ask and the lowest Bid
            int index_max=CSelect::FindTickDataMax(tick_series.GetList(),TICK_PROP_ASK);
            int index_min=CSelect::FindTickDataMin(tick_series.GetList(),TICK_PROP_BID);
            //--- Display the data of the tick objects obtained from the tick series in the journal
            engine.GetTickSeriesCollection().GetTick(tick_series.Symbol(),index_max).Print();
            engine.GetTickSeriesCollection().GetTick(tick_series.Symbol(),index_min).Print();
           }
        }
      check=true;
     }
  }
//+------------------------------------------------------------------+

Kompilieren Sie den EA und starten Sie ihn auf einem Chart mit einem beliebigen Symbol. Stellen Sie vorher sicher, dass Sie den aktuellen Zeitrahmen und die Symbole aus der vordefinierten Liste aktivieren, wobei nur die ersten beiden Symbole von den gesamten vorgeschlagenen Symbolen ausgelassen werden:


Nach einer kurzen Zeit, die benötigt wird, um Tick-Daten für zwei verwendete Symbole in OnInit() zu erzeugen, erhält das Journal Daten über die Programmparameter, die erzeugte Zeitreihe und erstellte Tick-Daten. Bei Ankunft des neuen Ticks empfängt das Journal die Daten über vier erkannte Ticks mit dem höchsten Ask und dem niedrigsten Bid für jedes der beiden Symbole:

Account 8550475: Artyom Trishkin (MetaQuotes Software Corp.) 10426.13 USD, 1:100, Hedge, MetaTrader 5 demo
--- Initializing "DoEasy" library ---
Working with predefined symbol list. The number of used symbols: 2
"AUDUSD" "EURUSD"
Working with the current timeframe only: H1
AUDUSD symbol timeseries: 
- Timeseries "AUDUSD" H1: Requested: 1000, Actual: 1000, Created: 1000, On the server: 6194
EURUSD symbol timeseries: 
- Timeseries "EURUSD" H1: Requested: 1000, Actual: 1000, Created: 1000, On the server: 5675
Tick series "AUDUSD": Requested number of days: 1, Historical data created: 142712
Tick series "EURUSD": Requested number of days: 1, Historical data created: 113985
Library initialization time: 00:00:06.156
 
============= Beginning of parameter list (Tick "AUDUSD" 2021.01.19 10:06:53.387) =============
Last price update time in milliseconds: 2021.01.19 10:06:53.387
Last price update time: 2021.01.19 10:06:53
Volume for the current Last price: 0
Flags: 6
Changed data on the tick:
 - Ask price change
 - Bid price change
------
Bid price: 0.77252
Ask price: 0.77256
Last price: 0.00000
Volume for the current Last price with greater accuracy: 0.00
Spread: 0.00004
------
Symbol: "AUDUSD"
============= End of parameter list (Tick "AUDUSD" 2021.01.19 10:06:53.387) =============
 
============= Beginning of parameter list (Tick "AUDUSD" 2021.01.18 11:51:48.662) =============
Last price update time in milliseconds: 2021.01.18 11:51:48.662
Last price update time: 2021.01.18 11:51:48
Volume for the current Last price: 0
Flags: 130
Changed data on the tick:
 - Bid price change
------
Bid price: 0.76589
Ask price: 0.76593
Last price: 0.00000
Volume for the current Last price with greater accuracy: 0.00
Spread: 0.00004
------
Symbol: "AUDUSD"
============= End of parameter list (Tick "AUDUSD" 2021.01.18 11:51:48.662) =============
 
============= Beginning of parameter list (Tick "EURUSD" 2021.01.19 10:05:07.246) =============
Last price update time in milliseconds: 2021.01.19 10:05:07.246
Last price update time: 2021.01.19 10:05:07
Volume for the current Last price: 0
Flags: 6
Changed data on the tick:
 - Ask price change
 - Bid price change
------
Bid price: 1.21189
Ask price: 1.21189
Last price: 0.00000
Volume for the current Last price with greater accuracy: 0.00
Spread: 0.00000
------
Symbol: "EURUSD"
============= End of parameter list (Tick "EURUSD" 2021.01.19 10:05:07.246) =============

============= Beginning of parameter list (Tick "EURUSD" 2021.01.18 14:57:53.847) =============
Last price update time in milliseconds: 2021.01.18 14:57:53.847
Last price update time: 2021.01.18 14:57:53
Volume for the current Last price: 0
Flags: 134
Changed data on the tick:
 - Ask price change
 - Bid price change
------
Bid price: 1.20536
Ask price: 1.20536
Last price: 0.00000
Volume for the current Last price with greater accuracy: 0.00
Spread: 0.00000
------
Symbol: "EURUSD"
============= End of parameter list (Tick "EURUSD" 2021.01.18 14:57:53.847) =============

Laut Journal dauerte die Initialisierung der Bibliothek und die Erstellung der Tick-Datenlisten 16 Sekunden. Beim Eintreffen eines neuen Ticks fanden wir zwei Ticks — mit dem höchsten Ask- und dem niedrigsten Bid-Preis — für jedes der verwendeten Symbole für den aktuellen Tag.

Was kommt als Nächstes?

Im nächsten Artikel werde ich mich mit der Echtzeitaktualisierung und der Steuerung von Datenereignissen in der heute erstellten Tick-Kollektion beschäftigen.

Alle Dateien der aktuellen Version der Bibliothek sind unten zusammen mit der Test-EA-Datei für MQL5 zum Testen und Herunterladen angehängt.
Die Tickserien-Kollektionsklasse befindet sich in der Entwicklung, daher wird ihre Verwendung in eigenen Programmen zum jetzigen Zeitpunkt nicht empfohlen.
Schreiben Sie Ihre Fragen und Vorschläge in den Kommentaren.

Zurück zum Inhalt

Frühere Artikel dieser Serie:

Zeitreihen in der Bibliothek DoEasy (Teil 35): das Balkenobjekt und die Liste der Zeitreihen eines Symbols
Zeitreihen in der Bibliothek DoEasy (Teil 36): Objekt der Zeitreihe für alle verwendeten Symbolzeitrahmen
Zeitreihen in der Bibliothek DoEasy (Teil 37): Kollektion von Zeitreihen - Datenbank der Zeitreihen nach Symbolen und Zeitrahmen
Zeitreihen in der Bibliothek DoEasy (Teil 38): Kollektion von Zeitreihen - Aktualisierungen in Echtzeit und Datenzugriff aus dem Programm
Zeitreihen in der Bibliothek DoEasy (Teil 39): Bibliotheksbasierte Indikatoren - Vorbereitung der Daten und Zeitreihen
Zeitreihen in der Bibliothek DoEasy (Teil 40): Bibliotheksbasierte Indikatoren - Aktualisierung der Daten in Echtzeit
Zeitreihen in der Bibliothek DoEasy (Teil 41): Beispiel eines Multi-Symbol- und Multi-Zeitrahmen-Indikators
Zeitreihen in der Bibliothek DoEasy (Teil 42): Abstrakte Objektklasse der Indikatorpuffer
Zeitreihen in der Bibliothek DoEasy (Teil 43): Klassen der Objekte von Indikatorpuffern
Zeitreihen in der Bibliothek DoEasy (Teil 44): Kollektionsklasse der Objekte von Indikatorpuffern
Zeitreihen in der Bibliothek DoEasy (Teil 45): Puffer für Mehrperiodenindikator
Zeitreihen in der Bibliothek DoEasy (Teil 46): Mehrperioden-Multisymbol-Indikatorpuffer
Zeitreihen in der Bibliothek DoEasy (Teil 47): Standardindikatoren für mehrere Symbole und Perioden
Zeitreihen in der Bibliothek DoEasy (Teil 48): Mehrperioden-Multisymbol-Indikatoren mit einem Puffer in einem Unterfenster
Zeitreihen in der Bibliothek DoEasy (Teil 49): Standardindikatoren mit mehreren Puffern für mehrere Symbole und Perioden
Zeitreihen in der Bibliothek DoEasy (Teil 50): Verschieben der Standardindikatoren für mehrere Symbole und Perioden
Zeitreihen in der Bibliothek DoEasy (Teil 51): Zusammengesetzte Standardindikatoren für mehrere Symbole und Perioden
Zeitreihen in der Bibliothek DoEasy (Teil 52): Plattformübergreifende Eigenschaft für Standardindikatoren mit einem Puffer für mehrere Symbole und Perioden
Zeitreihen in der Bibliothek DoEasy (Teil 53): Abstrakte Basisklasse der Indikatoren
Zeitreihen in der Bibliothek DoEasy (Teil 54): Abgeleitete Klassen des abstrakten Basisindikators
Zeitreihen in der Bibliothek DoEasy (Teil 55): Die Kollektionsklasse der Indikatoren
Zeitreihen in der Bibliothek DoEasy (Teil 56): Nutzerdefiniertes Indikatorobjekt, das die Daten von Indikatorobjekten aus der Kollektion holt
Zeitreihen in der Bibliothek DoEasy (Teil 57): Das Datenobjekt der Indikatorpuffer
Zeitreihen in der Bibliothek DoEasy (Teil 58): Zeitreihen der Datenpuffer von Indikatoren
Zeitreihen in der Bibliothek DoEasy (Teil 59): Objekt zum Speichern der Daten eines Ticks
Preise in der DoEasy-Bibliothek (Teil 60): Listen von Serien mit Symbol-Tickdaten


Übersetzt aus dem Russischen von MetaQuotes Software Corp.
Originalartikel: https://www.mql5.com/ru/articles/8952

Beigefügte Dateien |
MQL5.zip (3876.08 KB)
Letzte Kommentare | Zur Diskussion im Händlerforum (2)
Christian
Christian | 27 Mrz 2021 in 18:56

Wieder mal ein guter Artikel.



Einen kleinen Fehler gefunden. MetaEditor hängt sich dabei auf.


Wenn das Objekt TickSeries nicht mit Ticks gefüllt wird. (m_amount = 0 )

Gibt die Funktion GetTick() NULL zurück und die Methode .Print() lässt den Editor abstürzen.


 TestDoEasyPart61.mq5

237           engine.GetTickSeriesCollection().GetTick(tick_series.Symbol(),index_max).Print();
238           engine.GetTickSeriesCollection().GetTick(tick_series.Symbol(),index_min).Print();
Artyom Trishkin
Artyom Trishkin | 27 Mrz 2021 in 19:29
Christian :

Wieder mal ein guter Artikel.



Einen kleinen Fehler gefunden. MetaEditor hängt sich dabei auf.


Wenn das Objekt TickSeries nicht mit Ticks gefüllt wird. (m_amount = 0 )

Gibt die Funktion GetTick() NULL zurück und die Methode .Print() lässt den Editor abstürzen.


 TestDoEasyPart61.mq5

Danke, ich werde es reparieren.

Preise in der DoEasy-Bibliothek (Teil 62): Aktualisieren der Tick-Serien in Echtzeit, Vorbereitung für die Arbeit mit Markttiefe Preise in der DoEasy-Bibliothek (Teil 62): Aktualisieren der Tick-Serien in Echtzeit, Vorbereitung für die Arbeit mit Markttiefe
In diesem Artikel werde ich die Aktualisierung der Tick-Daten in Echtzeit implementieren und die Symbol-Objektklasse für die Arbeit mit Markttiefe (Depth of Market, DOM) vorbereiten (das DOM selbst wird im nächsten Artikel implementiert).
Mehrschicht-Perceptron und Backpropagation-Algorithmus Mehrschicht-Perceptron und Backpropagation-Algorithmus
Die Popularität dieser beiden Methoden wächst, sodass viele Bibliotheken in Matlab, R, Python, C++ und anderen entwickelt wurden, die einen Trainingssatz als Eingabe erhalten und automatisch ein passendes Netzwerk für das Problem erstellen. Versuchen wir zu verstehen, wie der Grundtyp des neuronalen Netzes funktioniert (einschließlich Ein-Neuronen-Perzeptron und Mehrschicht-Perzeptron). Wir werden einen spannenden Algorithmus betrachten, der für das Training des Netzes verantwortlich ist - Gradientenabstieg und Backpropagation. Bestehende komplexe Modelle basieren oft auf solchen einfachen Netzwerkmodellen.
Preise in der DoEasy-Bibliothek (Teil 63): Markttiefe und deren abstrakte Anforderungsklasse Preise in der DoEasy-Bibliothek (Teil 63): Markttiefe und deren abstrakte Anforderungsklasse
In diesem Artikel werde ich mit der Entwicklung der Funktionalität für die Arbeit mit der Markttiefe (Depth of Market, DOM) beginnen. Ich werde auch die Klasse des abstrakten Objekts der Markttiefe und seine Nachkommen erstellen.
Preise in der DoEasy-Bibliothek (Teil 60): Listen von Serien mit Symbol-Tickdaten Preise in der DoEasy-Bibliothek (Teil 60): Listen von Serien mit Symbol-Tickdaten
In diesem Artikel werde ich eine Liste zur Speicherung von Tickdaten eines einzelnen Symbols erstellen und deren Erstellung und Abruf der benötigten Daten in einem EA überprüfen. Tickdatenlisten, die für jedes verwendete Symbol individuell sind, werden weiterhin eine Kollektion von Tickdaten darstellen.