und werden Sie Mitglied unserer Fangruppe
Veröffentliche einen Link auf das Skript, damit die anderen ihn auch nutzen können
Bewerten Sie es im Terminal MetaTrader 5
- Ansichten:
- 29
- Rating:
- Veröffentlicht:
- 2025.06.18 12:06
-
Benötigen Sie einen Roboter oder Indikator, der auf diesem Code basiert? Bestellen Sie ihn im Freelance-Bereich Zum Freelance
Dieser Expert Advisor-Code scannt die Marktbeobachtung des Brokers des Benutzers und extrahiert Symbole, für die er alle verfügbaren Ticks oder Ticks bis zu einem bestimmten Datum herunterlädt.
Es kann Ihnen helfen, die gesamte Symbolhistorie für Ihren Backtest herunterzuladen oder einen benutzerdefinierten Chart aus diesen Ticks zu erstellen.
Die Terminals zwischenspeichern die Ticks im Datenordner, also stellen Sie sicher, dass Sie über ausreichend Festplattenspeicher verfügen.
Um das Herunterladen der Symbole zu erleichtern, benötigen wir zunächst einen Download-Manager.
Die Struktur CDownloadManager enthält alle Informationen, die wir benötigen, um sie zu speichern.
struct CDownloadManager { bool m_started,m_finished; string m_symbols[],m_current; int m_index;
- den Status des Downloads (gestartet/abgeschlossen)
- die Liste der zu scannenden Symbole
- das aktuelle Symbol
- und den Index des gerade gescannten Symbols
Da wir mit Symbolen arbeiten, erstellen wir 2 schnelle Funktionen, um Strings aus Binärdateien zu lesen und zu schreiben.
Die Funktion Zeichenkette in Datei speichern :
void writeStringToFile(int f,string thestring) { //Symbolzeichenfolge speichern 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); } }
Sie empfängt :
- Dateihandle f, einer zum Schreiben geöffneten Datei und Binärflags FILE_WRITE|FILE_BIN
- die Zeichenkette, die in die Datei geschrieben werden soll
Sie schreibt eine ganzzahlige Länge, die angibt, wie viele Zeichen die Zeichenkette hat, und speichert dann jedes Zeichen in der Zeichenkette.
Die Funktion load string from file:
string readStringFromFile(int f) { string result=""; //Zeichenfolge laden 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); }
Sie empfängt:
- Datei-Handle f einer Datei, die zum Lesen als Binärdatei geöffnet ist, Flags FILE_READ|FILE_BIN
Sie liest eine ganzzahlige Länge, die angibt, wie viele Zeichen an dieser Stelle in der Datei zu erwarten sind, liest jedes Zeichen in ein char-Array und erstellt dann aus diesem char-Array einen String, der als Ergebnis des Ladevorgangs als String zurückgegeben wird.
Zurück zur CDownloadManager-Struktur. Wir brauchen eine Möglichkeit, den Manager zu initialisieren und ihn mit Daten aus der Marktüberwachung zu füllen:
//+------------------------------------------------------------------+ //| Symbole aus der Marktbeobachtung übernehmen| //+------------------------------------------------------------------+ 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); } }
Ziemlich einfach:
- Abfrage, wie viele Symbole in der Marktbeobachtung sind (aktiv)
- Ändern Sie die Größe unseres m_symbols-Arrays, um sie zu erhalten
- Schleife in der Gesamtzahl der Symbole und Abfrage des Namens des Symbols
Wir sind auch für die Verwaltung des Herunterladens der Symboldaten verantwortlich, also brauchen wir eine Funktion, die im Wesentlichen der Manager ist:
//+------------------------------------------------------------------+ //| Verwalten des Downloads von Symbolen| //+------------------------------------------------------------------+ void manage(string folder,string filename) { //im Wesentlichen wird damit das nächste Symbol gestartet oder angesteuert //wenn festgelegt if(ArraySize(m_symbols)>0) { //wenn nicht gestartet if(!m_started) { m_started=true; //geht 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("Finished"); ExpertRemove(); return; } } } else { Print("Please grab symbols first"); } //wenn der Satz hier endet }
Wie das System funktioniert:
- Der Chart wird geöffnet, wir brauchen 1 Chart, und ein Timer wird gesetzt.
- Dieser Timer wird ausgeführt, wir brechen den Timer ab.
- Wir prüfen, ob es sich um einen neuen Download oder einen fortlaufenden Download handelt.
- Wenn es sich um einen neuen Download handelt, richten wir ihn ein, indem wir alle Symbole abrufen.
- Wenn es sich um einen fortlaufenden Download handelt, laden wir die Daten für das aktuelle Symbol herunter.
Dies ist der Teil des Codes, der das Herunterladen mit dem Timer durchführt:
//+------------------------------------------------------------------+ //|Timer| //+------------------------------------------------------------------+ void OnTimer() { //--- wenn synchronisiert if(SymbolIsSynchronized(_Symbol)&&TerminalInfoInteger(TERMINAL_CONNECTED)==1) { EventKillTimer(); //--- das System hier laden if(MANAGER.load(MANAGER_FOLDER,MANAGER_STATUS_FILE)) { //--- System geladen, daher wird hier ein Symbol gescannt Comment("System loaded and we are processing "+MANAGER.m_current); //--- tick load //--- zuerst den ältesten im Broker verfügbaren Tick suchen 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("PleaseWait"); 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("Oldest Tick : "+TimeToString((datetime)(oldest/1000),TIME_DATE|TIME_MINUTES|TIME_SECONDS)+"\nCursor("+TimeToString((datetime)(cursorMSC/1000),TIME_DATE|TIME_MINUTES|TIME_SECONDS)+")\nAttempts("+IntegerToString(attempts)+")\nPlease wait for response..."); } //--- zu diesem Zeitpunkt haben wir den ältesten Tick //--- Beginn der Abfrage von Ticks vom ältesten zum neuesten if(oldest!=LONG_MAX) { ArrayFree(receiver); datetime newest_tick=0; //--- empfange 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) { //--- Anforderung einer neuen Charge ab der ältesten Zeit mit der angegebenen Tickgrenze int pulled=CopyTicks(_Symbol,receiver,COPY_TICKS_ALL,oldest,tick_packets); if(pulled>0) { //--- wenn wir einen neuen Stapel ziehen, aktualisieren wir die heruntergeladenen Zeiten newest_tick=receiver[pulled-1].time; oldest=receiver[pulled-1].time_msc; ArrayFree(receiver); } //--- Zeitüberschreitung bei Serveranfragen, ändern Sie diese, wenn Sie wollen Sleep(44); Comment("Pulled up to "+TimeToString(newest_tick,TIME_DATE|TIME_MINUTES|TIME_SECONDS)+" so far"); } } else { Alert("Please close the terminal \n head over to the ticks folder \n and delete the empty folders"); ExpertRemove(); } //--- den Manager aktualisieren und weitermachen MANAGER.manage(MANAGER_FOLDER,MANAGER_STATUS_FILE); } else { //--- Wählen Sie die Marktbeobachtungssymbole, um den Download zu starten Comment("Grabbing MW and starting"); MANAGER.grab_symbols(); MANAGER.manage(MANAGER_FOLDER,MANAGER_STATUS_FILE); } } }
Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalpublikation: https://www.mql5.com/en/code/56324

Der MACD Coloured Histogram ist eine verbesserte Version des klassischen MACD-Indikators (Moving Average Convergence Divergence), die eine klarere und intuitivere visuelle Analyse der Marktdynamik ermöglicht. Dieser Indikator kombiniert die traditionellen MACD-Funktionen mit einem dynamischen Histogramm, das seine Farbe je nach dem Verhältnis zwischen der MACD-Linie und der Signallinie ändert und es dem Händler ermöglicht, Trends, Umkehrpunkte und Momente der Unentschlossenheit auf dem Markt schnell zu erkennen.

Unabhängig davon, ob Sie mehrere Handelsroboter gleichzeitig oder nur eine ausgefeilte Strategie einsetzen, kann es überraschend zeitaufwändig sein, die Leistung der einzelnen Expert Advisors zu verfolgen. MetaTrader 5 (MT5) zeigt Aufträge und Positionen bequem in seiner "Toolbox" an, aber wenn sich mehrere Roboter dasselbe Konto teilen, wird es schwieriger zu wissen, welcher EA Ihre Gewinne - oder Verluste - generiert. Ein einziges Konto kann Dutzende oder Hunderte von Geschäften enthalten, die von verschiedenen EAs eröffnet wurden, so dass es schwierig ist, die Ergebnisse eines Roboters von denen eines anderen zu unterscheiden.

Dies sind einige #define-Anweisungen, die für die Durchführung von Operationen in Ihrem EA nützlich sind. Sie müssen nur den Namen Ihrer Variablen am Anfang der Datei zuweisen und dann die anderen #define-Anweisungen die Arbeit erledigen lassen. Um diese Datei zu verwenden, fügen Sie #include <DEFINE_statements.mqh> in die erste Zeile Ihrer EA-Datei ein.

Der Indikator stellt zwei Linien dar. Die untere Linie wird auf der Grundlage der letzten SMA-Periode berechnet, die einen Aufschwung verursacht hat. Die obere Linie wird auf der Grundlage der letzten SMA-Periode berechnet, die einen Abprall nach unten verursacht hat.