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.
- www.mql5.com
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); }
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
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.
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?
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.
Die frage ist halt, musst du wirklich soviele daten laden? Oder reicht dir nicht die anzahl der kerzen die du im chartfenster siehst?
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
Reiche ich nach, sollte es relevanter werden.
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?
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.
- 2021.05.05
- www.mql5.com
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?
- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.
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!