spezifische Frage zur OnCalculate()

 

Hallo miteinander,

ich programmiere gerade einen Indikator und bin mir bezüglich der Berechnung der OnCalculate() unschlüssig.
Bevor Ich das Thema ausweiten kann, müsste ich zuerst heruasfinden, was in dem time[] Buffer der OnCalculate() hinterlegt ist.

Sind das immer die Timestamps der Eröffnungspreise der einzelnen Kerzen in dem jeweiligen Timeframe?

Also bei M1:

time[0] == 2020.05.10 14:00:00

time[1] == 2020.05.10 14:01:00

...

und bei M15:

time[0] == 2020.05.10 14:00:00

time[1] == 2020.05.10 14:15:00

...

Als weitere möglichkeit, dachte ich die iTime() zu verwenden, um mir die jeweiligen Timestamps der eröffnungskurse zu geben. Geht das ohne weiteres?


Als nächstes werde ich mit den Timestamps dann auf eine Datenbank zugreifen, welche pro Minute eine Spalte an Daten bereithält:

Für das M1er tf könnte ich den Indikator direkt mit den Rohdaten (z.B. Number of Trades) füttern, da in der DB alles im M1 format in vorliegt. Für das M15er tf müsste ich allerdings jweils 15 Spalten miteinander addieren, um die korrekten Werte für das tf zu erhalten. Sehe ich das richtig?

Dankeschön!

 

Steht alles hier: https://www.mql5.com/de/docs/series.

Es geht darum in welcher Reihenfolge die neuen Preise (und Zeiten) an das Array mit diesen Daten angehängt wird vorne [0] (beim MT4 oder hinten [rates_total-1] in MT5.

Ist etwas verwirrend, weshalb ich das immer im Debugger überprüfe.

Dokumentation zu MQL5: Zugang zu Zeitreihen und Indikatoren
Dokumentation zu MQL5: Zugang zu Zeitreihen und Indikatoren
  • www.mql5.com
Zugang zu Zeitreihen und Indikatoren - Nachschlagewerk MQL5 - Nachschlagewerk über die Sprache des algothitmischen/automatischen Handels für MetaTrader 5
 
Dankeschön Carl.

Mein Indikator funktioniert jetzt, allerdings braucht er sage und schreibe 5 minuten, um das M15 Tf zu laden. Für den Daily Chart sind es villeicht 5 sek. was wohl daran liegt, dass ständig auf die Datenbank zugegriffen werden muss.
Anbei befindet sich der code und meine Frage ist nun, ob sich an der Performance irgendetwas drehen lässt..

Code Indikator:
//---Indikator Einstellungen
#property indicator_buffers 1
#property indicator_plots   1
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_label1  "Number of trades"

double    tradesBuffer[];
double    quoteAssetVolume;
int       numberOfTrades;
double    takerBuyBaseAssetVolume;
double    takerBuyQuoteAssetVolume;
datetime  candleOne;
datetime  lastM1Bar;
datetime  newM1Bar;
int       db;
string    filename="AAVEUSDT.db"; 

int OnInit()
  {
   //--- indicator buffers mapping
   SetIndexBuffer(0,tradesBuffer,INDICATOR_DATA);

   //--- sets first bar from what index will be drawn
   
   return(INIT_SUCCEEDED);
  }

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {



int limit = rates_total - prev_calculated;
   if(limit == 0) limit++;
    
    
   for(int i = 0; i < limit; i++)
      {   
       //--- Öffnen einer Datenbank im Verzeichnis Common des Terminals
       db=DatabaseOpen(filename, DATABASE_OPEN_READONLY | DATABASE_OPEN_COMMON);
       if(db==INVALID_HANDLE)
        {
         Print("DB: ", filename, " open failed with code Database open ", GetLastError());
        }
       
       //--- Zeit und Datum der 1. Kerze abfragen und in eine String variable convertieren
       candleOne = time[i];
      // Print("Timestamp: ",time[i]);
      
       string sqlCommand = " SELECT * FROM test3 WHERE OpenTime='";
       StringAdd(sqlCommand,TimeToString(candleOne));
       StringAdd(sqlCommand,":00'");
       
       //---Handle für DatabaseRead() erzeugen
       int request=DatabasePrepare(db, sqlCommand);  
       if(request==INVALID_HANDLE)
        {
         Print("DB: ", filename, " request failed with code Database prepare ", GetLastError());
         DatabaseClose(db);    
        }
   
       //--- Printe die Spalte mit dem candleOne Datum
       for(int j=0; DatabaseRead(request); j++)
        {
        //--- read the values of each field from the obtained entry
         if(//DatabaseColumnDouble(request, 1, quoteAssetVolume)       && 
            DatabaseColumnInteger(request, 2, numberOfTrades)        
            //DatabaseColumnDouble(request, 3, takerBuyBaseAssetVolume)&&
            //DatabaseColumnDouble(request, 4, takerBuyQuoteAssetVolume)
            )
             {
              tradesBuffer[i] = numberOfTrades;
             // Print("Anzahl der Trades: ",tradesBuffer[i]);
             }
         else
             {
             Print(j, ": DatabaseRead() failed with code database read ", GetLastError());
             DatabaseFinalize(request);
             DatabaseClose(db);
             }
         }
       //--- Anfrage beenden
       DatabaseFinalize(request);
   
       //--- Datenbank schließen
       DatabaseClose(db);
      }
   return(rates_total);
  }
 
Der Editor bietet genau dafür das Profiling, dass vor Kurzem erst verbessert wurde: Editor => Debug => Profiling. Man erhält den Zeitaufwand für verschiedene Methoden und Prozeduren.
 

Super einwand!

Nur leider bestätigt das nur meine Theorie

Die OnCalculate() frisst wohl durch die berechnung von rates_total einiges weg,  die DatabaseRead() gibt der CPU dann wohl den rest.  Ich muss aber irgendwas falsch machen. Ich lebe nämlich in der Erwartung, dass die Arbeit mit Datenbanken viel effektver sein sollte

 
Claudius Marius Walter:

Super einwand!

Nur leider bestätigt das nur meine Theorie

Die OnCalculate() frisst wohl durch die berechnung von rates_total einiges weg,  die DatabaseRead() gibt der CPU dann wohl den rest.  Ich muss aber irgendwas falsch machen. Ich lebe nämlich in der Erwartung, dass die Arbeit mit Datenbanken viel effektver sein sollte

Also, in OnCalculate() passiert ja alles, alles hat da auch praktisch nicht reduzierbare ~100%.

Der Durchgang von 0- rates_total passiert ja nur einmal nach dem Start - ist also nicht kritisch!

Danach sollte nur die neuesten 1, 2 Bars aktualisiert werden - das ist entscheidend.

Die Frage ist also wie sind die Zeiten der Datenbank-Funktionen nach der ersten Intialisierung.

 
Carl Schreiber:

Also, in OnCalculate() passiert ja alles, alles hat da auch praktisch nicht reduzierbare ~100%.

Der Durchgang von 0- rates_total passiert ja nur einmal nach dem Start - ist also nicht kritisch!

Danach sollte nur die neuesten 1, 2 Bars aktualisiert werden - das ist entscheidend.

Die Frage ist also wie sind die Zeiten der Datenbank-Funktionen nach der ersten Intialisierung.

Die frage ist halt, musst du wirklich soviele daten laden? Oder reicht dir nicht die anzahl der kerzen die du im chartfenster siehst?

 
Carl Schreiber:

Also, in OnCalculate() passiert ja alles, alles hat da auch praktisch nicht reduzierbare ~100%.

Der Durchgang von 0- rates_total passiert ja nur einmal nach dem Start - ist also nicht kritisch!

Danach sollte nur die neuesten 1, 2 Bars aktualisiert werden - das ist entscheidend.

Die Frage ist also wie sind die Zeiten der Datenbank-Funktionen nach der ersten Intialisierung.

Reiche ich nach, sollte es relevanter werden.

amando:

Die frage ist halt, musst du wirklich soviele daten laden? Oder reicht dir nicht die anzahl der kerzen die du im chartfenster siehst?

Wenn ich das richtig verstehe, rechnet der EA zu beginn (beim ersten aufruf der OnCalc() ) doch ersteinmal alles für die vorhergehenden Balken aus, richtig?

Danach wird jeweils nur die neueste Kerze ermittelt, oder?

Ob ich all diese Daten für den Strategietester brauche, kann ich garnicht so recht beantworten, da ich die zugrundeliegende Berechnung des Strategietesters noch nicht verstehe. Was ich sicher weiß, ist dass die Strategie mit einem maximalen Lookback von etwa 20,30 Kerzen arbeiten wird. w
 
Claudius Marius Walter:

Reiche ich nach, sollte es relevanter werden.

Wenn ich das richtig verstehe, rechnet der EA zu beginn (beim ersten aufruf der OnCalc() ) doch ersteinmal alles für die vorhergehenden Balken aus, richtig?

Danach wird jeweils nur die neueste Kerze ermittelt, oder?

Ob ich all diese Daten für den Strategietester brauche, kann ich garnicht so recht beantworten, da ich die zugrundeliegende Berechnung des Strategietesters noch nicht verstehe. Was ich sicher weiß, ist dass die Strategie mit einem maximalen Lookback von etwa 20,30 Kerzen arbeiten wird. w

Dann brauchst du aktuell auch nur die letzten 20-30 kerzen

was ladest du da für daten? Kursdaten? Von was?

 
Alles klar, danke. Bin gespannt, wie lange er damit zu rechnen hat...

Ich greife auf eine Mt5 interne SQL Datenbank zu, welche zusätzliche Daten, wie die "Anzahl der Trades" oder das "Taker buy base asset volume" zur verfügung stellt.

in diesem Beitrag: https://www.mql5.com/de/forum/368700  habe ich mir eine SQL Abfrage erarbeitet, welche ich dazu verwende, um  jeder 1min Kerze mit den zusätzlichen Kursdaten zu füttern.
Files lesen
Files lesen
  • 2021.05.05
  • www.mql5.com
Hallo Zusammen, kennt sich jemand mit dem lesen von files aus? ich habe eine...
 
Claudius Marius Walter:
Alles klar, danke. Bin gespannt, wie lange er damit zu rechnen hat...

Ich greife auf eine Mt5 interne SQL Datenbank zu, welche zusätzliche Daten, wie die "Anzahl der Trades" oder das "Taker buy base asset volume" zur verfügung stellt.

in diesem Beitrag: https://www.mql5.com/de/forum/368700  habe ich mir eine SQL Abfrage erarbeitet, welche ich dazu verwende, um  jeder 1min Kerze mit den zusätzlichen Kursdaten zu füttern.

Was ist das taker buy asset value?