In diesem Artikel zeige ich dir, wie du mit einem Expert Advisor (EA) alle verfügbaren Tick-Daten eines Symbols in MetaTrader 5 herunterladen kannst. Dieser Code durchsucht die Marktplattform deines Brokers und extrahiert die Symbole, für die er alle verfügbaren Ticks oder Ticks bis zu einem bestimmten Datum herunterlädt.
Dies kann dir helfen, die gesamte Symbolhistorie für Backtests herunterzuladen oder benutzerdefinierte Charts aus diesen Ticks zu erstellen. Achte darauf, dass genug Speicherplatz auf deiner Festplatte vorhanden ist, da die Ticks im Datenordner zwischengespeichert werden.
Um den Download der Symbole zu erleichtern, benötigen wir zuerst einen Download-Manager. Die Struktur CDownloadManager enthält alle Informationen, die wir benötigen.
struct CDownloadManager { bool m_started,m_finished; string m_symbols[],m_current; int m_index; }
- Der Status des Downloads (gestart/abgeschlossen)
- Die Liste der zu scannenden Symbole
- Das aktuelle Symbol
- Der Index des gerade gescannten Symbols
Wir müssen auch mit der Festplatte lesen und schreiben, und da wir mit Symbolen arbeiten, erstellen wir zwei Funktionen, um Strings aus Binärdateien zu lesen und zu schreiben.
Die Funktion zum Speichern eines Strings in eine Datei:
void writeStringToFile(int f,string thestring) { // Speichere das Symbol-String char sysave[]; int charstotal=StringToCharArray(thestring,sysave,0,StringLen(thestring),CP_ACP); FileWriteInteger(f,charstotal,INT_VALUE); for(int i=0;i<charstotal;i++) { FileWriteInteger(f,sysave[i],CHAR_VALUE); } }
Die Funktion erhält:
- Die Datei-ID f, einer zum Schreiben geöffneten Datei mit binären Flags FILE_WRITE|FILE_BIN
- Den zu speichernden String
Sie schreibt die Länge der Zeichen in die Datei und speichert dann jedes Zeichen im String.
Die Funktion zum Laden eines Strings aus einer Datei:
string readStringFromFile(int f) { string result=""; // Lade das Symbol-String char syload[]; int charstotal=(int)FileReadInteger(f,INT_VALUE); if(charstotal>0) { ArrayResize(syload,charstotal,0); for(int i=0;i<charstotal;i++) { syload[i]=(char)FileReadInteger(f,CHAR_VALUE); } result=CharArrayToString(syload,0,charstotal,CP_ACP); } return(result); }
Diese Funktion erhält:
- Die Datei-ID f, einer zum Lesen geöffneten Datei mit binären Flags FILE_READ|FILE_BIN
Sie liest die Länge der Zeichen und lädt die Zeichen in ein Char-Array, das dann in einen String umgewandelt und zurückgegeben wird.
Zurück zur Struktur CDownloadManager. Wir benötigen eine Möglichkeit, den Manager zu initialisieren und mit den Daten aus der Marktbeobachtung zu füllen:
//+------------------------------------------------------------------+ //| Symbole von der Marktbeobachtung abrufen | //+------------------------------------------------------------------+ void grab_symbols() { //! nur von der MW! int s=SymbolsTotal(true); ArrayResize(m_symbols,s,0); for(int i=0;i<ArraySize(m_symbols);i++) { m_symbols[i]=SymbolName(i,true); } }
Das ist ziemlich einfach:
- Wir fragen, wie viele Symbole in der Marktbeobachtung aktiv sind
- Wir passen unser m_symbols-Array an, um diese aufzunehmen
- Wir durchlaufen die Symbole und fordern die Namen der Symbole an
Wir sind auch verantwortlich für das Management des Downloads der Symbol-Daten, daher benötigen wir eine Funktion, die im Wesentlichen den Prozess verwaltet:
//+------------------------------------------------------------------+ //| Verwaltung des Downloadprozesses | //+------------------------------------------------------------------+ void manage(string folder,string filename) { // Diese Funktion startet oder wechselt zum nächsten Symbol // falls gesetzt if(ArraySize(m_symbols)>0) { // wenn nicht gestartet if(!m_started) { m_started=true; // gehe zum ersten Symbol m_current=m_symbols[0]; m_index=1; save(folder,filename); if(_Symbol!=m_current) { ChartSetSymbolPeriod(ChartID(),m_current,_Period); } else { ENUM_TIMEFRAMES new_period=PERIOD_M1; for(int p=0;p<ArraySize(TFS);p++) { if(_Period!=TFS[p]) { new_period=TFS[p]; break; } } ChartSetSymbolPeriod(ChartID(),m_current,new_period); } return; }
// Wenn gestartet else { m_index++; if(m_index<=ArraySize(m_symbols)) { m_current=m_symbols[m_index-1]; save(folder,filename); if(_Symbol!=m_current) { ChartSetSymbolPeriod(ChartID(),m_current,_Period); } return; }
else { m_finished=true; FileDelete(folder+"\"+filename); Print("Fertig"); ExpertRemove(); return; } }
}
else { Print("Bitte zuerst Symbole abrufen"); }
}
So funktioniert das System:
- Das Chart öffnet sich, dafür benötigen wir 1 Chart, und ein Timer wird gesetzt.
- Dieser Timer wird ausgeführt, wir stoppen den Timer
- Wir prüfen, ob dies ein neuer Download oder ein fortlaufender Download ist
- Wenn es ein neuer Download ist, richten wir ihn ein, indem wir alle Symbole abrufen
- Wenn es ein fortlaufender Download ist, laden wir die Daten für das aktuelle Symbol herunter
Hier ist der Teil des Codes, der den Download im Timer durchführt:
//+------------------------------------------------------------------+ //| Timer | //+------------------------------------------------------------------+ void OnTimer() { //--- wenn synchronisiert if(SymbolIsSynchronized(_Symbol)&&TerminalInfoInteger(TERMINAL_CONNECTED)==1) { EventKillTimer(); //--- lade das System hier if(MANAGER.load(MANAGER_FOLDER,MANAGER_STATUS_FILE)) { //--- System geladen, wir scannen hier ein Symbol Comment("System geladen und wir verarbeiten "+MANAGER.m_current); //--- Tick laden //--- finde den ältesten Tick, der beim Broker verfügbar ist int attempts=0; int ping=-1; datetime cursor=flatten(TimeTradeServer()); long cursorMSC=((long)cursor)*1000; long jump=2592000000;//60*60*24*30*1000; MqlTick receiver[]; long oldest=LONG_MAX; Comment("Bitte warten"); while(attempts<5) { ping=CopyTicks(_Symbol,receiver,COPY_TICKS_ALL,cursorMSC,1); if(ping==1) { if(receiver[0].time_msc==oldest) { attempts++; } else { attempts=0; } if(receiver[0].time_msc<oldest) { oldest=receiver[0].time_msc; } cursorMSC-=jump; if(limitDate&&receiver[0].time<=oldestLimit) { break; } } else { attempts++; } Sleep(44); Comment("Ältester Tick : "+TimeToString((datetime)(oldest/1000),TIME_DATE|TIME_MINUTES|TIME_SECONDS)+" Cursor("+TimeToString((datetime)(cursorMSC/1000),TIME_DATE|TIME_MINUTES|TIME_SECONDS)+") Versuche("+IntegerToString(attempts)+") Bitte warten auf Antwort..."); } //--- an diesem Punkt haben wir den ältesten Tick //--- beginne Ticks vom ältesten zum neuesten anzufordern if(oldest!=LONG_MAX) { ArrayFree(receiver); datetime newest_tick=0; //--- erhalte die Zeit des letzten Ticks für dieses Symbol, gespeichert in symbol_time datetime most_recent_candle=(datetime)SymbolInfoInteger(_Symbol,SYMBOL_TIME); while(newest_tick<most_recent_candle) { //--- fordere ein neues Batch an, beginnend mit der ältesten Zeit und dem angegebenen Tick-Limit int pulled=CopyTicks(_Symbol,receiver,COPY_TICKS_ALL,oldest,tick_packets); if(pulled>0) { //--- wenn wir ein neues Batch abrufen, aktualisieren wir unsere heruntergeladenen Zeiten newest_tick=receiver[pulled-1].time; oldest=receiver[pulled-1].time_msc; ArrayFree(receiver); } //--- Wartezeit für Serveranfragen, ändere sie, wenn du möchtest Sleep(44); Comment("Bis jetzt bis "+TimeToString(newest_tick,TIME_DATE|TIME_MINUTES|TIME_SECONDS)+" gezogen"); } } else { Alert("Bitte schließe das Terminal \n gehe zum Ticks-Ordner \n und lösche die leeren Ordner"); ExpertRemove(); } //--- aktualisiere den Manager und fahre fort MANAGER.manage(MANAGER_FOLDER,MANAGER_STATUS_FILE); } else { //--- hole die Symbole der Marktbeobachtung, um den Download zu starten Comment("MW abrufen und starten"); MANAGER.grab_symbols(); MANAGER.manage(MANAGER_FOLDER,MANAGER_STATUS_FILE); }
}
Mit dieser Anleitung bist du nun bestens gerüstet, um die Tick-Datenhistorie für deine Backtests herunterzuladen. Viel Erfolg beim Traden!
Verwandte Beiträge
- Handelssignale mit MQL5 Wizard: Bullish und Bearish Harami mit CCI bestätigen
- MQL5 Wizard: Trade Signale auf Basis von Kurs-Crossover mit gleitendem Durchschnitt und ADX Bestätigung
- MQL5 Wizard: Handels-Signale mit 3 schwarzen Krähen / 3 weißen Soldaten + CCI für MetaTrader 5
- MQL5 Wizard: Handelssignale durch 3 Schwarze Krähen/3 Weiße Soldaten + RSI
- MQL5 Wizard: Handelssignale mit 3 schwarzen Krähen/3 weißen Soldaten und Stochastik erstellen