Diskussion zum Artikel "Zeitreihen in der Bibliothek DoEasy (Teil 39): Bibliotheksbasierte Indikatoren - Vorbereitung der Daten und Zeitreihen"

 

Neuer Artikel Zeitreihen in der Bibliothek DoEasy (Teil 39): Bibliotheksbasierte Indikatoren - Vorbereitung der Daten und Zeitreihen :

Der Artikel befasst sich mit der Anwendung der DoEasy-Bibliothek zur Erstellung von Mehrsymbol- und Mehrperiodenindikatoren. Wir werden die Bibliotheksklassen auf die Arbeit mit Indikatoren vorbereiten und die Erstellung von Zeitreihen testen, die als Datenquellen in Indikatoren verwendet werden können. Wir werden auch das Erstellen und Versenden von Zeitreihen-Ereignissen implementieren.

Kompilieren Sie den Indikator und starten Sie ihn auf dem Symbolchart, mit dem wir lange Zeit nicht gearbeitet haben (während Sie zuvor in den Einstellungen die Arbeit mit dem aktuellen Symbol eingestellt haben) und wählen Sie die Arbeit mit der angegebenen Zeitrahmenliste. Durch das Starten des Indikators auf lange Zeit unbenutzte Symbole wird der Indikator zum Herunterladen fehlender Daten und zur Information darüber im Journal und auf dem Chart:


Hier können wir sehen, dass jede nächste leere Zeitreihe bei jedem neuen Tick synchronisiert und erstellt wurde. Die folgenden Einträge wurden im Journal angezeigt:

Account 8550475: Artyom Trishkin (MetaQuotes Software Corp.) 10425.23 USD, 1:100, Hedge, MetaTrader 5 demo
--- Initializing "DoEasy" library ---
Working with the current symbol only: "USDCAD"
Working with the specified timeframe list:
"M1"  "M5"  "M15" "M30" "H1"  "H4"  "D1"  "W1"  "MN1"
USDCAD symbol timeseries: 
- Timeseries "USDCAD" M1: Requested: 1000, Actual: 0, Created: 0, On the server: 0
- Timeseries "USDCAD" M5: Requested: 1000, Actual: 0, Created: 0, On the server: 0
- Timeseries "USDCAD" M15: Requested: 1000, Actual: 0, Created: 0, On the server: 0
- Timeseries "USDCAD" M30: Requested: 1000, Actual: 0, Created: 0, On the server: 0
- Timeseries "USDCAD" H1: Requested: 1000, Actual: 0, Created: 0, On the server: 0
- Timeseries "USDCAD" H4: Requested: 1000, Actual: 0, Created: 0, On the server: 0
- Timeseries "USDCAD" D1: Requested: 1000, Actual: 0, Created: 0, On the server: 0
- Timeseries "USDCAD" W1: Requested: 1000, Actual: 0, Created: 0, On the server: 0
- Timeseries "USDCAD" MN1: Requested: 1000, Actual: 0, Created: 0, On the server: 0
Library initialization time: 00:00:01.406
"USDCAD" M1 timeseries created successfully:
- Timeseries "USDCAD" M1: Requested: 1000, Actual: 1000, Created: 1000, On the server: 5001
"USDCAD" M5 timeseries created successfully:
- Timeseries "USDCAD" M5: Requested: 1000, Actual: 1000, Created: 1000, On the server: 5741
"USDCAD" M15 timeseries created successfully:
- Timeseries "USDCAD" M15: Requested: 1000, Actual: 1000, Created: 1000, On the server: 5247
"USDCAD" M30 timeseries created successfully:
- Timeseries "USDCAD" M30: Requested: 1000, Actual: 1000, Created: 1000, On the server: 5123
"USDCAD" H1 timeseries created successfully:
- Timeseries "USDCAD" H1: Requested: 1000, Actual: 1000, Created: 1000, On the server: 6257
"USDCAD" H4 timeseries created successfully:
- Timeseries "USDCAD" H4: Requested: 1000, Actual: 1000, Created: 1000, On the server: 6232
"USDCAD" D1 timeseries created successfully:
- Timeseries "USDCAD" D1: Requested: 1000, Actual: 1000, Created: 1000, On the server: 5003
"USDCAD" W1 timeseries created successfully:
- Timeseries "USDCAD" W1: Requested: 1000, Actual: 1000, Created: 1000, On the server: 1403
"USDCAD" MN1 timeseries created successfully:
- Timeseries "USDCAD" MN1: Requested: 1000, Actual: 323, Created: 323, On the server: 323
New bar on USDCAD M1: 2020.03.19 12:18
New bar on USDCAD M1: 2020.03.19 12:19
New bar on USDCAD M1: 2020.03.19 12:20
New bar on USDCAD M5: 2020.03.19 12:20

Autor: Artyom Trishkin

 

Gibt es einen Fehler in dem Artikel?

Die Bibliothek funktioniert im Timer, wenn der Indikator im Symbolchart ausgeführt wird, und in OnCalculate() auf Ticks - wenn der Indikator im Tester ausgeführt wird.

Oder habe ich das falsch verstanden?
 
Сергей Таболин:

Gibt es einen Fehler in dem Artikel?

Die Bibliothek funktioniert im Timer, wenn der Indikator im Symbolchart ausgeführt wird, und in OnCalculate() auf Ticks - wenn der Indikator im Tester ausgeführt wird.

Oder habe ich das falsch verstanden?
Das ist richtig. Genau so ist es.
 

Hallo,

Ich versuche, einige Parameter des letzten "kompletten" Bar in das Journal zu drucken, aber ich würde vermuten, dass ich entweder nicht die gespeicherten Seriendaten aktualisiert haben, oder haben es nicht sortiert (aber ich kann auch nicht herausfinden, wie man es nach Zeit zu sortieren und erhalten Sie die Bar, die ich will), mein Ergebnis ist immer der 2. bar in der Geschichte, nie aktualisiert Echtzeit-Daten des vorherigen kompletten bar... Als Nächstes möchte ich die jüngste vollständige Balkengröße mit den vorherigen 10-20 Balken vergleichen, jeder Anstoß in die richtige Richtung wird geschätzt!

Ichführe diese Aktion auf das Ereignis "New Bar" durch:

   else if(idx>SERIES_EVENTS_NO_EVENT && idx<SERIES_EVENTS_NEXT_CODE)
     {
      //--- Ereignis "Neuer Takt"
      if(idx==SERIES_EVENTS_NEW_BAR)
        {
         Print(TextByLanguage("Новый бар на ","New Bar on "),sparam," ",TimeframeDescription((ENUM_TIMEFRAMES)dparam),": ",TimeToString(lparam));

        
//--- Druck der letzten vollständigen Taktgröße bei jedem neuen Takt 
         // Holt das Symbol-Objekt aus dem übergebenen String param 
         CSymbol *symbol=engine.GetSymbolObjByName(sparam);
         if(symbol==NULL)
            return;
         // Ermittelt den letzten vollständigen Balken (aktuell -1 von rechts im Chart) für diesen Zeitrahmen
         CBar *bar=engine.SeriesGetBar(symbol.Name(),(ENUM_TIMEFRAMES)dparam,1);
         if(bar==NULL)
            return;            
         //--- Anzeige der vom Balkenobjekt empfangenen Daten
         Print(TextByLanguage("Бар \"","Data from Bar \"")+symbol.Name()+"\" "+TimeframeDescription((ENUM_TIMEFRAMES)dparam)+": "+TimeToString(bar.Time(),TIME_DATE|TIME_MINUTES|TIME_SECONDS)+
            " H: "+DoubleToString(bar.High(),symbol.Digits())+
            " L: "+DoubleToString(bar.Low(),symbol.Digits())+
            " Size: "+DoubleToString(bar.Size(),symbol.Digits()));        
        
        }
     }

Angehängter Screenshot der Journal-Ergebnisse

Dateien:
Example.jpg  102 kb
 
iabbott :

Hallo,

Ich versuche, einige Parameter der letzten "kompletten" Bar in das Journal zu drucken, aber ich würde vermuten, dass ich entweder nicht die gespeicherten Seriendaten aktualisiert haben, oder haben es nicht sortiert (aber ich kann auch nicht herausfinden, wie es nach Zeit zu sortieren und erhalten Sie die Bar, die ich will), mein Ergebnis ist immer die 2. bar in der Geschichte, nie aktualisiert Echtzeit-Daten der vorherigen kompletten bar... Als Nächstes möchte ich die Größe des letzten vollständigen Balkens mit den vorherigen 10-20 Balken vergleichen, jeder Anstoß in die richtige Richtung wird geschätzt!

Ich führe diese Aktion auf das Ereignis "New Bar" durch:

Angehängter Screenshot der Journal-Ergebnisse

Fügen Sie bitte den Quellcode des Programms bei, in dem Sie solche Ergebnisse erhalten.

Welche Zeitrahmen-Balken möchten Sie bei der Eröffnung eines neuen Balkens erhalten?

 

Hallo,

Ich habe gerade diesen Codeblock zum neuen Bar-Ereignis des Pt39 TestDoEasy EA hinzugefügt, ohne weitere Änderungen (Zeile 544 im Anhang)

Beim Öffnen eines neuen Balkens möchte ich die Balkenhistorie des Zeitrahmens prüfen, der das Ereignis ausgelöst hat - da das Ereignis für jeden Zeitrahmen separat ausgelöst wird, dachte ich mir, dass es einfacher wäre, diese Prüfung als Teil des Ereignisses einzufügen

Vielen Dank

Dateien:
 

Hey - gibt's was Neues?

Ist es etwas, das ich nicht richtig mache? Mir scheint, wenn es ein Problem mit der Bibliothek wäre, hätte es jemand schon viel früher gefunden :)

Danke!

 
iabbott:

Hey - gibt's was Neues?

Ist es etwas, das ich nicht richtig mache? Mir scheint, wenn es ein Problem mit der Bibliothek wäre, hätte es jemand viel früher gefunden :)

Danke!

Ich entschuldige mich. Ich war beschäftigt. Ich werde bald sehen, was Ihr Problem ist.
 

Hallo Artyom, haben Sie spezielle Ideen für die Bibliothek, um in die Diagrammkommentare zu schreiben, indem Sie ::Comment() verwenden, wie Sie es in CEngine::SeriesSync() tun?

void CEngine::SeriesSync(SDataCalculate &data_calculate,const uint required=0)
  {
//...
      //--- Die leeren Zeitreihendaten als Diagrammkommentar anzeigen und versuchen, die Zeitreihe mit den Serverdaten zu synchronisieren
      ::Comment(series.Header(),": ",CMessage::Text(MSG_LIB_TEXT_TS_TEXT_WAIT_FOR_SYNC));
      ::ChartRedraw(::ChartID());

//...
            //--- Anzeige des Diagrammkommentars und des Journaleintrags mit den neu erstellten Zeitreihendaten
            ::Comment(series.Header(),": OK");
            ::ChartRedraw(::ChartID());
            Print(series.Header()," ",CMessage::Text(MSG_LIB_TEXT_TS_TEXT_CREATED_OK),":");
            series.PrintShort();

//...
     //--- Alle Kommentare löschen
      ::Comment("");
      ::ChartRedraw(::ChartID());
  }

Meiner bescheidenen Meinung nach ist es wahrscheinlich am besten, dies dem Benutzer der Bibliothek zu überlassen... Ich habe meine eigene Bibliothek, die die Chart-Kommentare manipuliert, um wichtige operative Aspekte meiner EAs auszugeben, und würde es daher stark bevorzugen, eine Einmischung der DoEasy-Bibliothek zu vermeiden. Was sind Ihre zukünftigen Pläne in dieser Hinsicht?

 
Dima Diall :

Hallo Artyom, haben Sie spezifische Ideen für die Bibliothek, um in den Diagrammkommentaren zu schreiben, mit ::Comment() wie Sie in CEngine::SeriesSync() tun?

Meiner bescheidenen Meinung nach ist es wahrscheinlich am besten, dies dem Benutzer der Bibliothek zu überlassen... Ich habe meine eigene Bibliothek, die die Chart-Kommentare manipuliert, um wichtige operative Aspekte meiner EAs auszugeben, und würde es daher stark bevorzugen, eine Einmischung der DoEasy-Bibliothek zu vermeiden. Was sind Ihre zukünftigen Pläne in dieser Hinsicht?

Wenn in Zukunft mit Grafiken gearbeitet wird, wird es keine Standardkommentare geben.

 

Hallo - bei der Überprüfung der Event-Handler-Code genauer, habe ich bemerkt, dass Sie verschiedene Methoden verwenden, um die Quelle des Ereignisses zu analysieren... in einigen Fällen ist es auf der Chart-Ereignis-ID-Parameter von OnChartEvent() basiert, während in anderen Sie es aus dem Parameter lparam über engine.EventSource(lparam) extrahieren - gibt es einen bestimmten Grund, warum es in jedem Fall unterschiedlich ist?

void OnDoEasyEvent(const int id,
                   const long &lparam,
                   const double &dparam,
                   const string &sparam)
  {
   int idx=id-CHARTEVENT_CUSTOM;
//--- Abrufen von (1) Ereigniszeit in Millisekunden, (2) Grund und (3) Quelle aus lparam, sowie (4) Setzen der genauen Ereigniszeit
   ushort msc=engine.EventMSC(lparam);
   ushort reason=engine.EventReason(lparam);
   ushort source=engine.EventSource(lparam);
   long time=TimeCurrent()*1000+msc;
   
//--- Behandlung von Symbolereignissen
   if(source==COLLECTION_SYMBOLS_ID)
     {
      //...
     }
//--- Handling account events
   else if(source==COLLECTION_ACCOUNT_ID)
     {
      //...
     }
//--- Handling market watch window events
   else if(idx>MARKET_WATCH_EVENT_NO_EVENT && idx<SYMBOL_EVENTS_NEXT_CODE)
     {
      //...
     }
//--- Handling timeseries events
   else if(idx>SERIES_EVENTS_NO_EVENT && idx<SERIES_EVENTS_NEXT_CODE)
     {
      //...
     }
//--- Handling trading events
   else if(idx>TRADE_EVENT_NO_EVENT && idx<TRADE_EVENTS_NEXT_CODE)
     {
      //...
     }