
Vom Neuling zum Experten: Umfassende Fehlersuche in MQL5
Wesentlicher Inhalt
Einleitung:
In der Regel zielt jeder Autor darauf ab, ein bestimmtes Problem vom Anfang bis zum Ende eines Artikels zu behandeln. Unser heutiger Titel lautet „Debugging“, aber ich möchte Sie ermutigen, ihn nicht auf die leichte Schulter zu nehmen, denn wir werden viel mehr als nur die Grundlagen des Prozesses erforschen. Ich werde die Techniken vorstellen, die ich im Laufe der Jahre bei mehreren erfolgreichen Projekten eingesetzt habe. In allen Bereichen der Softwareprogrammierung ist das Debugging ein nicht zu vernachlässigendes Thema. Mir ist aufgefallen, dass viele Autoren sich darauf konzentrieren, ein ausgefeiltes Endprodukt zu präsentieren, ohne die Schwierigkeiten zu schildern, die sie hatten, um den Code korrekt zum Laufen zu bringen.
Ob in neuronalen Netzwerken, künstlicher Intelligenz oder anderen verwandten Software-Disziplinen - Debugging ist unerlässlich. Ich glaube, dass die wertvollste Fähigkeit, die man entwickeln kann, die Fähigkeit ist, Probleme zu lösen, wenn sie auftauchen, und diese Fähigkeit wird ein integraler Bestandteil von Ihnen für zukünftige Herausforderungen ähnlicher Art. So kann das Lösen von Problemen eine starke Kompetenz aufbauen und jemanden allmählich zu einem Experten machen.
Umfassendes Debugging
Als ich mich entschloss, diesen Artikel zu schreiben, arbeitete ich an einem Projekt, bei dem ich beim Versuch, den Code zu kompilieren, auf mehrere Fehler stieß. Manchmal zeigte mir der Debugger 50 Fehlerzeilen an, die ich beheben musste. Durch Versuch und Irrtum habe ich eine Routine für die Fehlerbehebung entwickelt, die es mir ermöglicht, Probleme in wenigen Minuten, wenn nicht sogar Sekunden, zu beheben und das Programm wieder zum Laufen zu bringen.
Mein Ziel ist es, Sie auf die Technologien aufmerksam zu machen, die den Debugging-Prozess beschleunigen können. Meiner Erfahrung nach ist eine der wertvollsten Lektionen, die ich gelernt habe, dass die Beherrschung von MQL5 schnell und effektiv sein kann, wenn man sich aktiv an Debugging-Projekten beteiligt. Ich habe ein fehlerhaftes Programm erhalten, das wir gemeinsam durchgehen und verfeinern werden.
Eine der größten Herausforderungen besteht darin, dass viele Menschen die langen MQL5-Bücher, die kostenlos erhältlich sind, nicht ertragen können, aber das macht sie nicht weniger wertvoll. Diese Bücher enthalten wesentliches Wissen, das von grundlegenden bis zu fortgeschrittenen MQL5-Programmierkonzepten reicht. Um die besten Ergebnisse zu erzielen, ist es ratsam, sich an aktiven Projekten zu beteiligen und gleichzeitig in diesen Büchern nach spezifischen Themen zu suchen, die mit Ihrer laufenden Arbeit zusammenhängen. Wenn Sie diese Projekte durchführen, werden Sie natürlich eine Fülle von Wissen aufnehmen.
Normalerweise sind unsere Fehlerberichte in vier Spalten unterteilt, wie in der folgenden Tabelle beschrieben.
Spalte (Namen) | Erklärung |
---|---|
Beschreibung | Diese Spalte enthält eine kurze Erläuterung des Fehlers oder der Warnung, die im Code aufgetreten ist. Er kann die Art des Problems beschreiben, z. B. Syntaxfehler, nicht deklarierte Variablen, Typinkongruenzen oder andere Codierungsfehler. Das Verständnis der Beschreibung hilft dem Programmierer, das Problem schnell zu erkennen. |
Datei | Hier wird der Name der Datei angegeben, in der der Fehler aufgetreten ist (z. B. D1 PriceMarker.mq5). Bei mehreren Dateien in einem Projekt ist es für eine effektive Fehlersuche und -behebung entscheidend zu wissen, in welcher Datei das Problem auftritt. |
Zeile | Gibt die genaue Zeilennummer innerhalb der angegebenen Datei an, in der der Fehler gefunden wurde. Dadurch kann der Programmierer schnell zu dem spezifischen Teil des Codes navigieren, der behoben werden muss, und so die Zeit für die Fehlersuche verkürzen. |
Kolumne, | Hier wird die spezifische Spaltennummer in der Zeile angegeben, in der der Fehler festgestellt wurde. Obwohl sie weniger häufig als die vorherigen Spalten verwendet wird, kann sie besonders nützlich sein, um Fehler zu identifizieren, die in komplexen Anweisungen auftreten oder wenn die Zeile viele Elemente enthält (wie mehrere Funktionsaufrufe oder Parameter). |
Sie sind in der Regel von links nach rechts angeordnet, wie unten dargestellt. Wir haben auch den vollständigen Fehlerbericht, der 20 Fehler und 4 Warnungen umfasst (siehe unten im Ausschnitt), für das Programm, das wir in dieser Diskussion debuggen werden, direkt unter dem Tabellenlayout eingefügt. Es wird Ihnen leicht fallen, die Merkmale des Berichts zu erkennen. Wenn Sie bis zum Ende lesen, erfahren Sie, wie Sie die im folgenden Codeausschnitt dargestellten Fehler beheben können.
Beschreibung | Datei | Zeile | Spalte |
'D1 PriceMarker.mq5' 1 'ObjectDelete' - wrong parameters count D1 PriceMarker.mq5 70 5 built-in: bool ObjectDelete(long,const string) D1 PriceMarker.mq5 70 5 'ObjectDelete' - wrong parameters count D1 PriceMarker.mq5 71 5 built-in: bool ObjectDelete(long,const string) D1 PriceMarker.mq5 71 5 'ObjectDelete' - wrong parameters count D1 PriceMarker.mq5 72 5 built-in: bool ObjectDelete(long,const string) D1 PriceMarker.mq5 72 5 'ObjectDelete' - wrong parameters count D1 PriceMarker.mq5 73 5 built-in: bool ObjectDelete(long,const string) D1 PriceMarker.mq5 73 5 'ObjectDelete' - wrong parameters count D1 PriceMarker.mq5 74 5 built-in: bool ObjectDelete(long,const string) D1 PriceMarker.mq5 74 5 'ObjectDelete' - wrong parameters count D1 PriceMarker.mq5 75 5 built-in: bool ObjectDelete(long,const string) D1 PriceMarker.mq5 75 5 'ObjectDelete' - wrong parameters count D1 PriceMarker.mq5 76 5 built-in: bool ObjectDelete(long,const string) D1 PriceMarker.mq5 76 5 'ObjectDelete' - wrong parameters count D1 PriceMarker.mq5 77 5 built-in: bool ObjectDelete(long,const string) D1 PriceMarker.mq5 77 5 'ObjectCreate' - wrong parameters count D1 PriceMarker.mq5 15 9 built-in: bool ObjectCreate(long,const string,ENUM_OBJECT,int,datetime,double,...) D1 PriceMarker.mq5 15 9 'ObjectCreate' - wrong parameters count D1 PriceMarker.mq5 27 9 built-in: bool ObjectCreate(long,const string,ENUM_OBJECT,int,datetime,double,...) D1 PriceMarker.mq5 27 9 'ObjectSetText' - undeclared identifier D1 PriceMarker.mq5 37 5 ',' - unexpected token D1 PriceMarker.mq5 37 28 'labelName' - some operator expected D1 PriceMarker.mq5 37 19 '+' - illegal operation use D1 PriceMarker.mq5 37 36 ',' - unexpected token D1 PriceMarker.mq5 37 69 result of expression not used D1 PriceMarker.mq5 37 43 ',' - unexpected token D1 PriceMarker.mq5 37 73 expression has no effect D1 PriceMarker.mq5 37 71 ',' - unexpected token D1 PriceMarker.mq5 37 82 expression has no effect D1 PriceMarker.mq5 37 76 ')' - unexpected token D1 PriceMarker.mq5 37 87 expression has no effect D1 PriceMarker.mq5 37 84 'OBJPROP_Y' - undeclared identifier D1 PriceMarker.mq5 41 36 'ObjectSetInteger' - no one of the overloads can be applied to the function call D1 PriceMarker.mq5 41 5 could be one of 2 function(s) D1 PriceMarker.mq5 41 5 built-in: bool ObjectSetInteger(long,const string,ENUM_OBJECT_PROPERTY_INTEGER,long) D1 PriceMarker.mq5 41 5 built-in: bool ObjectSetInteger(long,const string,ENUM_OBJECT_PROPERTY_INTEGER,int,long) D1 PriceMarker.mq5 41 5 20 errors, 4 warnings 21 5
Hier sind einige gängige Begriffe, die man verstehen sollte, wenn man über dieses Thema spricht:
- Syntax: bezieht sich auf die spezifischen Regeln, die vorschreiben, wie Programme (z. B. Handelsalgorithmen, Indikatoren und Skripte) geschrieben sein müssen, damit die MetaTrader 5-Plattform sie versteht und korrekt ausführt.
- Error: bezieht sich auf einen Fehler oder ein Problem im Code, der/das die korrekte Ausführung des Codes verhindert. Fehler können in verschiedene Kategorien eingeteilt werden: Syntaxfehler, Laufzeitfehler, logische Fehler, Typfehler und Kompilierungsfehler.
Was ist Debugging?
Ich bin sicher, dass die meisten von Ihnen mit diesem lebendigen Begriff vertraut sind, aber für Anfänger ist es wichtig, das Konzept im Detail zu verstehen. Jetzt werde ich einen Fehler definieren, damit Sie den Prozess der Fehlersuche besser verstehen können.
- Bug:
Ein Fehler oder Defekt in einem Computerprogramm oder -system, der dazu führt, dass es sich unerwartet oder falsch verhält.
- Fehlersuche:
Es handelt sich um den Prozess der Identifizierung, Isolierung und Behebung von Fehlern oder Bugs in einem Computerprogramm oder -system mit dem Ziel, sicherzustellen, dass sich das Programm wie beabsichtigt verhält und unter verschiedenen Bedingungen die richtigen Ergebnisse liefert.
Fehlersuche im Rahmen der MQL5-Programmierung
Hier sind einige Aspekte der Fehlersuche, die sich speziell auf MQL5 beziehen:
1. Häufige Arten von Fehlern in MQL5:
- Syntax-Fehler: Fehler in der MQL5-Code-Struktur, die das Kompilieren des Skripts verhindern.
Dieses Beispiel zeigt einen einfachen Syntaxfehler, bei dem die schließende Klammer für die Funktion Print() fehlt. Dies hat zur Folge, dass das Skript nicht kompiliert werden kann, was die Notwendigkeit unterstreicht, die Codestruktur sorgfältig zu überprüfen.
void OnStart() { Print("Hello, World!" // Missing closing parenthesis }
- Logische Fehler: Probleme, bei denen der Code kompiliert und ausgeführt wird, aber falsche Handelssignale erzeugt oder sich unerwartet verhält.
In diesem Fall handelt es sich um einen logischen Fehler, bei dem die Bedingungen fälschlicherweise einen Kaufauftrag auslösen. Der Programmierer wollte eine komplexere Logik nutzen, die von den Marktbedingungen abhängt, aber die derzeitige Umsetzung führt zu unnötigen Handelsgeschäften.
void OnTick() { double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID); double targetPrice = currentPrice + 100; // Intended to use a different logic // Mistakenly placing a buy when conditions aren't right if (currentPrice < targetPrice) // Logic Error { OrderSend(_Symbol, OP_BUY, 0.1, currentPrice, 3, 0, 0, "Buy order", 0, 0, clrGreen); } }
- Laufzeitfehler: Fehler, die während der Ausführung auftreten, wie z. B. der Versuch, auf ein Out-of-Bounds-Array zuzugreifen, oder die nicht ordnungsgemäße Bearbeitung von Handelsaufträgen.
In diesem Beispiel wird versucht, auf das sechste Element eines Arrays zuzugreifen, das nur fünf gültige Indizes hat. Dies führt zu einem Laufzeitfehler, der die Bedeutung der Begrenzungsprüfung bei der Arbeit mit Arrays verdeutlicht.
void OnStart() { double prices[5]; // Attempt to access out-of-range index (e.g., index 5) double value = prices[5]; // Runtime error: Array out of range }
2. Werkzeuge zur Fehlersuche in MQL5:
- MetaEditor: Dies ist die integrierte Entwicklungsumgebung (IDE) für MQL5. Es bietet Syntax-Hervorhebung, Code-Vervollständigung und Fehleranzeige, mit deren Hilfe Syntaxfehler schnell erkannt werden können.
Der nachstehende Code ermöglicht das Setzen eines Haltepunkts bei der Berechnung der Ergebnisvariablen . Beim Debuggen in MetaEditor können Sie die Variablen an dieser Stelle überprüfen, um sicherzustellen, dass sie wie erwartet gesetzt sind, was die zeilenweise Ausführung zur Analyse des Programmablaufs erleichtert.
void OnStart() { double startValue = 10.0; // Set a breakpoint here to inspect value double result = startValue * 2; Print("Result: ", result); // Check the value of result }
- Erklärungen drucken: Verwendung der Funktion Print() zur Ausgabe von Variablenwerten und Ausführungsablaufprotokollen in das Expertenprotokoll. Auf diese Weise lassen sich Probleme leicht aufspüren.
In diesem Beispielcodeausschnitt verwenden wir die Funktion Print(), um die aktuellen Geld- und Briefkurse zu protokollieren. Dieser Ansatz ist vorteilhaft für die Verfolgung von Variablenwerten während der Ausführung und kann helfen, logische Fehler zu diagnostizieren, indem erwartete mit tatsächlichen Werten verglichen werden.
void OnTick() { double bidPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID); double askPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK); // Logging prices for debugging Print("Bid: ", bidPrice, ", Ask: ", askPrice); }
- Auskommentieren von Code: Vorübergehende Deaktivierung von Codeabschnitten, um den Problembereich zu isolieren.
In diesem Beispiel wird eine Codezeile auskommentiert, um sich auf die alternative Logik zu konzentrieren. Diese Technik ist nützlich, um Fehler zu isolieren und verschiedene Abschnitte des Codes zu testen, ohne sie vollständig zu entfernen.
void OnTick() { // double result = SomeFunction(); // Temporarily disabling this line // Run alternate logic while debugging Print("Running alternative logic."); }3. Verwenden des Debuggers im MetaEditor:
MetaEditor enthält einen eingebauten Debugger, der Folgendes ermöglicht:4. Testen und Optimieren:
- Breakpoints: Durch das Setzen von Haltepunkten (Breakpoints) in Ihrem Code können Sie die Ausführung an bestimmten Zeilen anhalten und Variablenwerte überprüfen.
- Schritt für Schritt durch die Ausführung: Sie können den Code Zeile für Zeile durchgehen, um zu sehen, wie sich die Variablen ändern und wie der logische Fluss verläuft.
- Ausdrücke beobachten: Überwachung der Werte bestimmter Variablen während der Ausführung des Codes.
5. Fehlerbehandlung:
- Strategietester: MQL5 bietet einen Strategietester, mit dem Sie Backtests von Handelsstrategien anhand historischer Daten durchführen können. Es hilft bei der Simulation von Handelsgeschäften und der Analyse der Leistung, wodurch versteckte Fehler aufgedeckt werden können.
- Optimierung: Sie können Parameter optimieren, um die Leistung Ihres Handelsalgorithmus zu verbessern, was auch mögliche Fehler in der Logik oder Ausführung aufzeigen kann.
- Behandlung von MQL5-spezifischen Fehlercodes, wie z.B. die Überprüfung der Rückgabewerte von Funktionen im Zusammenhang mit Handelsoperationen. Zu den gängigen Funktionen gehören Funktionen zur Auftragsausführung (OrderSend, OrderClose usw.), bei denen eine angemessene Fehlerbehandlung Abstürze oder unerwünschte Ergebnisse verhindern kann.
Bewährte Praxis für die Fehlersuche in MQL5:
1. Modularität des Codes: Schreiben Sie modularen Code, indem Sie ihn in Funktionen aufgliedern. Dies erleichtert das Testen und Debuggen einzelner Komponenten. 2. Code dokumentieren: Kommentieren Sie Ihren Code, um zu erklären, was die einzelnen Teile bewirken, was hilfreich sein kann, wenn Sie den Code nach einiger Zeit erneut lesen. 3. Regelmäßige Tests: Testen Sie den Code häufig während der Entwicklung, anstatt zu warten, bis alles fertig ist. Dies hilft, Fehler frühzeitig zu erkennen.Implementierung von Debugging in MQL5
Vor nicht allzu langer Zeit haben mein Freund und ich einen groben Entwurf eines Skripts erstellt, um gekennzeichnete Kurslinien für die vorherige Tageskerze (D1) zu zeichnen, die kritische Kursniveaus wie Hoch, Tief, Eröffnung und Schluss markieren. Dies ist die Version, die ich für diesen Artikel beiseite gelegt habe.
Wenn Sie als Experte schreiben, bietet MetaEditor in der Regel Vorlagen und Parametervorschläge, die den Entwickler unterstützen und die Fehlerwahrscheinlichkeit verringern, vorausgesetzt, die Details werden gemäß der korrekten Sprachsyntax eingegeben. Es gibt jedoch Fälle, in denen Sie Code aus einem Forum erhalten, der mit Fehlern überladen ist. Nachfolgend finden Sie einen Codeausschnitt aus unserem fehlerhaften Skriptprogramm:
//+------------------------------------------------------------------+ //| D1 PriceMarker.mq5 | //| Copyright 2024, Clemence Benjamin | //| https://www.mql5.com/en/users/billionaire2024/seller | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, Clemence Benjamin" #property link "https://www.mql5.com/en/users/billionaire2024/seller" #property version "1.00" #property strict // Function to create a price line with a label void CreatePriceLine(string name, double price, color clr, string label) { // Create a horizontal line if(!ObjectCreate(name, OBJ_HLINE, 0, 0, price)) { Print("Failed to create line: ", GetLastError()); return; } // Set line properties ObjectSetInteger(0, name, OBJPROP_COLOR, clr); ObjectSetInteger(0, name, OBJPROP_WIDTH, 2); // Create a label for the price string labelName = name + "_label"; if(!ObjectCreate(labelName, OBJ_LABEL, 0, 0, 0)) { Print("Failed to create label: ", GetLastError()); return; } // Set label properties ObjectSetInteger(0, labelName, OBJPROP_XSIZE, 70); ObjectSetInteger(0, labelName, OBJPROP_FONTSIZE, 10); ObjectSetInteger(0, labelName, OBJPROP_COLOR, clr); ObjectSetText(labelName, label + ": " + DoubleToString(price, 2), 10, "Arial", clr); // Position the label double yPos = price; // Positioning along the price axis ObjectSetInteger(0, labelName, OBJPROP_Y, yPos); ObjectSetInteger(0, labelName, OBJPROP_XDISTANCE, 5); } //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ void OnInit() { // Get the previous D1 candle's open, high, low, and close prices datetime prevCandleTime = iTime(NULL, PERIOD_D1, 1); double openPrice = iOpen(NULL, PERIOD_D1, 1); double highPrice = iHigh(NULL, PERIOD_D1, 1); double lowPrice = iLow(NULL, PERIOD_D1, 1); double closePrice = iClose(NULL, PERIOD_D1, 1); // Draw labeled price lines for open, high, low, and close prices CreatePriceLine("PrevCandle_Open", openPrice, clrBlue, "Open"); CreatePriceLine("PrevCandle_High", highPrice, clrRed, "High"); CreatePriceLine("PrevCandle_Low", lowPrice, clrGreen, "Low"); CreatePriceLine("PrevCandle_Close", closePrice, clrOrange, "Close"); } //+------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { // Remove the drawn price lines and labels upon indicator deinitialization ObjectDelete("PrevCandle_Open"); ObjectDelete("PrevCandle_High"); ObjectDelete("PrevCandle_Low"); ObjectDelete("PrevCandle_Close"); ObjectDelete("PrevCandle_Open_label"); ObjectDelete("PrevCandle_High_label"); ObjectDelete("PrevCandle_Low_label"); ObjectDelete("PrevCandle_Close_label"); } //+------------------------------------------------------------------+
(i) Lokalisierung eines Fehlers
Ich habe festgestellt, dass der in MetaEditor integrierte Debugger recht nutzerfreundlich ist, wenn ich versuche, ein fehlerhaftes Programm zu kompilieren. Die meisten Bugs werden entdeckt, wenn Sie in MetaEditor auf die Schaltfläche Kompilieren oder Echtzeit-Profiling klicken. Es gibt jedoch einige Leistungsfehler, die das Kompilieren des Programms nicht verhindern; diese können nur auf der Plattform oder dem Tester erkannt werden, wenn Sie versuchen, das Programm auszuführen.
Ein Entwickler kann entweder das gesamte Programm von Grund auf neu schreiben und es dann debuggen oder einfach ein bereits vorhandenes Programm debuggen. In der folgenden Abbildung nutzen wir den in MetaEditor eingebauten Compiler und Debugger, um eine Fehlerübersicht zu erhalten (siehe den unteren Teil des Toolbox-Fensters in der Abbildung). Wenn Sie auf eine Fehlerzeile doppelklicken, bewegt sich der Cursor zu der entsprechenden Codezeile mit dem Fehler und hebt diese hervor. Ich habe nur selten Fehler im Code bemerkt, bis ich auf die Schaltfläche „Kompilieren“ drücke, woraufhin der Debugger alle auftretenden Probleme meldet.
Fehler in MetaEditor lokalisieren
Manchmal lässt sich das Programm zwar erfolgreich kompilieren, führt aber möglicherweise nicht zum gewünschten Ergebnis. In solchen Fällen ist es ratsam, mögliche Fehler zu identifizieren, indem Sie die Expertenprotokolle und Journalausdrucke überprüfen, die im Toolbox-Fenster der MetaTrader 5-Plattform verfügbar sind. Diese Protokolle können wertvolle Erkenntnisse darüber liefern, was bei der Ausführung schief laufen könnte, und helfen Ihnen bei der effektiven Fehlersuche und -behebung.
(ii) 3 Techniken der Fehlersuche
Fehler können oft durch Tippfehler oder die falsche Verwendung von Begriffen entstehen, und der Debugger liefert in der Regel Erklärungen und teilweise Hinweise zur Lösung. Wenn Sie diese Meldungen verstehen können, ist es in der Regel einfach, den Code zu überarbeiten und die notwendigen Korrekturen vorzunehmen. Es gibt jedoch auch komplexere Situationen, die schwer zu diagnostizieren sind und möglicherweise tiefer gehendes Wissen aus Fachbüchern oder Fachwissen aus der Gemeinschaft erfordern.
Meiner Erfahrung nach verwende ich bei der Fehlersuche in komplexen Problemen häufig einige Strategien. Ich unterteile diese Schritte in drei Hauptansätze, wobei diese Liste keinen Anspruch auf Vollständigkeit erhebt; sie ist speziell für den Zweck dieser Diskussion gedacht. Ich möchte die einzelnen Schritte des Verfahrens im Detail erläutern.
1. Überarbeitung der Dokumentation:
Es hilft erheblich bei der Fehlersuche in MQL5-Programmen, indem es Klarheit über Syntax, Funktionsverwendung und Fehlermeldungen schafft. Es bietet detaillierte Erklärungen und Beispiele, die helfen, fehlerhafte Implementierungen zu erkennen und das Verständnis für integrierte Funktionen zu verbessern. Darüber hinaus enthält die Dokumentation häufig Informationen zu häufigen Fehlern, bewährten Verfahren und alternativen Lösungen, die es den Entwicklern ermöglichen, Probleme effektiv zu beheben und ihren Code für eine bessere Leistung zu optimieren. Für dieses Projekt sehen Sie in der nachstehenden Abbildung, wie wir leicht auf die Dokumentation zugreifen können.
Überarbeitung der Dokumentation
Fehlerbericht:
'ObjectDelete' - wrong parameters count D1 PriceMarker.mq5 70 5
Lösungstipp:
built-in: bool ObjectDelete(long,const string) D1 PriceMarker.mq5 70 5
Aktuelle Situation:
ObjectDelete("PrevCandle_Open");
Aus dem Lösungshinweis geht hervor, dass die Funktion ObjectDelete zwei Parameter erwartet, wir aber derzeit nur einen angegeben haben. Dieser Unterschied zeigt, wo das Problem liegt, und wir können es entsprechend angehen. Der Dokumentation zufolge benötigt die Funktion ObjectDelete in MQL5 zwei Parameter:
- Name: Der Name des zu löschenden Objekts, angegeben als Zeichenkette.
- Chart_id: Die ID des Charts, aus dem das Objekt gelöscht werden soll, angegeben als Ganzzahl. Wenn diese Funktion nicht angegeben wird, wird standardmäßig das aktuelle Chart verwendet.
Um dieses Problem zu lösen, müssen wir sicherstellen, dass wir beim Aufruf von ObjectDelete beide Parameter übergeben. Auf diese Weise richten wir unseren Funktionsaufruf an der erwarteten Syntax aus und beseitigen so den Fehler.
Auflösung:
ObjectDelete(0, "PrevCandle_Open");
Wenn wir uns nun den Hauptcode ansehen, stellen wir fest, dass es mehrere Instanzen der Funktion ObjectDelete gibt. Anhand der Informationen, die wir bei unseren Nachforschungen gesammelt haben, können wir die notwendigen Anpassungen vornehmen. Indem wir sicherstellen, dass wir beide erforderlichen Parameter für jede Instanz angeben, können wir diese Fehler wirksam beheben.
In der folgenden Abbildung sehen Sie, wie es uns gelungen ist, die Gesamtzahl der Fehler um 10 zu reduzieren. Dies ist ein deutlicher Fortschritt bei der Fehlersuche in unserem Skript und zeigt, wie wichtig eine gründliche Prüfung und Korrektur auf der Grundlage einer angemessenen Dokumentation ist.
Fehler in der ObjectDelete-Funktion behoben
Es ist vollbracht! Wenn ein Fehler auftritt, empfiehlt es sich, nach jedem Lösungsversuch die Schaltfläche Kompilieren zu drücken. Auf diese Weise können Sie überprüfen, ob der Fehler weiterhin besteht, und Sie können alle verbleibenden Probleme ermitteln.
Kommen wir nun zu unserem nächsten Fehler.
Fehlerbericht:
'ObjectSetText' - undeclared identifier D1 PriceMarker.mq5 29 5 'ObjectSetText' - undeclared identifier D1 PriceMarker.mq5 29 5 ',' - unexpected token D1 PriceMarker.mq5 29 28 'labelName' - some operator expected D1 PriceMarker.mq5 29 19 '+' - illegal operation use D1 PriceMarker.mq5 29 36 ',' - unexpected token D1 PriceMarker.mq5 29 69 result of expression not used D1 PriceMarker.mq5 29 43 ',' - unexpected token D1 PriceMarker.mq5 29 73 expression has no effect D1 PriceMarker.mq5 29 71 ',' - unexpected token D1 PriceMarker.mq5 29 82 expression has no effect D1 PriceMarker.mq5 29 76 ')' - unexpected token D1 PriceMarker.mq5 29 87 expression has no effect D1 PriceMarker.mq5 29 84
Diesmal habe ich mehrere Berichte gesammelt, denn die Fehler treten in derselben Zeile auf. Dies deutet häufig auf ein gemeinsames Problem hin, das in diesem speziellen Teil des Codes behoben werden muss. Schauen wir uns die betreffende Zeile genauer an, um das zugrunde liegende Problem zu ermitteln und die notwendigen Korrekturen vorzunehmen.
Hinweise zur Lösung:
In diesem Szenario treten die folgenden Fehler auf: (undeclared identifier, expected operator, expression has no effect und unexpected token).
Aktuelle Situation:
ObjectSetText(labelName, label + ": " + DoubleToString(price, 2), 10, "Arial", clr);
Ich habe in der Dokumentation nachgesehen und konnte keinen Hinweis auf ObjectSetText finden. Als ich jedoch begann, ObjectSet... einzugeben, erschienen mehrere Vorschläge, wobei ObjectSetString die beste Option war. Diese Funktion erwies sich als die richtige, und sie funktionierte wie erwartet.
Im Folgenden können Sie sehen, wie unsere Bemühungen aussehen.
ObjectSetText in der Dokumentation nicht verfügbar
ObjectSetString
ObjectSetString-Funktionsparameter entsprechend der Dokumentation:
bool ObjectSetString( long chart_id, // chart identifier string name, // object name ENUM_OBJECT_PROPERTY_STRING prop_id, // property int prop_modifier, // modifier string prop_value // value );
Auflösung:
Indem wir die notwendigen Anpassungen vornahmen, ähnlich wie bei dem ersten Fehler, konnten wir fast alle Probleme lösen. Jetzt müssen nur noch einige wenige Zeilen korrigiert werden. Konzentrieren wir uns auf diese letzten Anpassungen, um die verbleibenden Fehler vollständig zu beseitigen.
ObjectSetString(0, labelName, OBJPROP_TEXT, label + ": " + DoubleToString(price, 2));
Noch ein paar Bugs:
2 verbleibende Fehler
Schließlich werden die verbleibenden Fehler behoben:
ObjectSetInteger(0, labelName, OBJPROP_YDISTANCE, price); // Position label at the price level
Es sollte OBJPROP_YDISTANCE heißen, nicht OBJPROP_Y.
Erfolgreiches Debugging mit Verweis auf die Dokumentation
Unser endgültiger bereinigter Code befindet sich hier:
//+------------------------------------------------------------------+ //| D1 PriceMarker.mq5 | //| Copyright 2024, Clemence Benjamin | //| https://www.mql5.com/en/users/billionaire2024/seller | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, Clemence Benjamin" #property link "https://www.mql5.com/en/users/billionaire2024/seller" #property version "1.00" #property strict // Function to create a price line with a label void CreatePriceLine(string name, double price, color clr, string label) { // Create a horizontal line if(!ObjectCreate(0, name, OBJ_HLINE, 0, 0, price)) { Print("Failed to create line: ", GetLastError()); return; } // Set line properties ObjectSetInteger(0, name, OBJPROP_COLOR, clr); ObjectSetInteger(0, name, OBJPROP_WIDTH, 2); // Create a label for the price string labelName = name + "_label"; if(!ObjectCreate(0, labelName, OBJ_LABEL, 0, 0, 0)) { Print("Failed to create label: ", GetLastError()); return; } // Set label properties ObjectSetInteger(0, labelName, OBJPROP_XSIZE, 70); ObjectSetInteger(0, labelName, OBJPROP_FONTSIZE, 10); ObjectSetInteger(0, labelName, OBJPROP_COLOR, clr); ObjectSetInteger(0, labelName, OBJPROP_YDISTANCE, price); // Position label at the price level ObjectSetInteger(0, labelName, OBJPROP_XDISTANCE, 5); // Set the text of the label ObjectSetString(0, labelName, OBJPROP_TEXT, label + ": " + DoubleToString(price, 2)); } //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ void OnInit() { // Get the previous D1 candle's open, high, low, and close prices datetime prevCandleTime = iTime(NULL, PERIOD_D1, 1); double openPrice = iOpen(NULL, PERIOD_D1, 1); double highPrice = iHigh(NULL, PERIOD_D1, 1); double lowPrice = iLow(NULL, PERIOD_D1, 1); double closePrice = iClose(NULL, PERIOD_D1, 1); // Draw labeled price lines for open, high, low, and close prices CreatePriceLine("PrevCandle_Open", openPrice, clrBlue, "Open"); CreatePriceLine("PrevCandle_High", highPrice, clrRed, "High"); CreatePriceLine("PrevCandle_Low", lowPrice, clrGreen, "Low"); CreatePriceLine("PrevCandle_Close", closePrice, clrOrange, "Close"); } //+------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { // Remove the drawn price lines and labels upon indicator deinitialization ObjectDelete(0, "PrevCandle_Open"); ObjectDelete(0, "PrevCandle_High"); ObjectDelete(0, "PrevCandle_Low"); ObjectDelete(0, "PrevCandle_Close"); ObjectDelete(0, "PrevCandle_Open_label"); ObjectDelete(0, "PrevCandle_High_label"); ObjectDelete(0, "PrevCandle_Low_label"); ObjectDelete(0, "PrevCandle_Close_label"); } //+------------------------------------------------------------------+
D1 PriceMarker ist ein MQL5-Skriptprogramm, das wir entwickelt haben, um die technische Analyse auf einem Handelschart zu verbessern, indem es horizontale Linien an den Hoch-, Tief-, Eröffnungs- und Schlusskursen der vorherigen Tageskerze (D1) zeichnet. Bei der Initialisierung ruft das Skript diese vier Kurspunkte ab und verwendet eine Hilfsfunktion, um entsprechende Kurslinien in verschiedenen Farben zu erstellen (blau für die Eröffnung, rot für das Hoch, grün für das Tief und orange für den Schluss), die jeweils von einem beschrifteten Text begleitet werden, der den Kurswert angibt. Wenn das Skript aus dem Chart entfernt wird, löscht es automatisch alle gezeichneten Linien und Beschriftungen und sorgt so für einen aufgeräumten Arbeitsbereich für den Händler.
2. Fehlersuche mit KI:
Ich weiß, dass alle sehr daran interessiert sind, zu erfahren, wie wir die verfügbaren KI-Modelle nutzen, daher werde ich dieses Thema nur kurz anreißen, um später eine ausführlichere Diskussion zu ermöglichen. Wir haben das Glück, dass die meisten dieser Modelle die Syntax schneller und genauer verstehen können als wir. Es ist jedoch wichtig zu wissen, dass sie manchmal unerwartete Ergebnisse liefern können und möglicherweise eine engere menschliche Aufsicht benötigen, um ihre nächsten Schritte zu steuern. Nichtsdestotrotz sind sie ausgezeichnete Werkzeuge, wenn sie klug eingesetzt werden, und ich habe viele Programmierprobleme gelöst, indem ich ihre Vorschläge sorgfältig berücksichtigt habe.
Wenn Sie eine KI-Eingabeaufforderung erstellen, sollten Sie zunächst das Programm bereitstellen, das Sie debuggen möchten. Wenn Sie dann die Möglichkeit nutzen, Fehlerzeilen aus dem MetaEditor-Bericht zu kopieren, können Sie diese Zeilen in die Eingabeaufforderung einfügen, damit die KI bei der Fehlersuche helfen kann. Diese Methode kann zwar zu erfolgreichen Ergebnissen führen, aber auch zu weiteren Komplikationen. Deshalb ist es wichtig, kritisch zu denken und über das hinauszugehen, was die KI vorschlägt. Die Ergebnisse, die wir zuvor erzielt haben, stimmen mit denen überein, die andere Debugging-Tools liefern sollten, vorausgesetzt, sie werden effektiv eingesetzt.
Kopieren von Fehlern in eine AI-Eingabeaufforderung
3. Besuchen Sie das Forum:
Ähnlich wie oben beschrieben, benötigen die Mitglieder des Forums Informationen, um wertvolle Erkenntnisse zur Fehlersuche zu gewinnen. Die Teilnahme an Diskussionen über Programmieraufgaben ist eine fantastische Möglichkeit, von anderen Experten zu lernen. Indem Sie Ihr Programm einreichen, laden Sie andere dazu ein, ihre klugen Vorschläge und Lösungen zu teilen. Dieser umfassende Ansatz hilft Ihnen nicht nur bei der Lösung Ihrer Probleme, sondern verbessert auch die Kenntnisse und Fähigkeiten aller Beteiligten.
Programm auf MetaTrader 5:
Das Skript D1 PriceMarker
Schlussfolgerung
Teamarbeit bei der MQL5-Programmierung erweist sich als wesentliche Praxis zur Verbesserung der Entwicklung robuster Handelsalgorithmen, wie unsere Reise zur Erstellung des D1 PriceMarker-Skripts gezeigt hat. Der Debugging-Prozess stützte sich stark auf Fehlerberichte und die umfassende MQL5-Referenzdokumentation, die es uns ermöglichte, Probleme, die während der Entwicklung auftraten, systematisch zu identifizieren und zu lösen.
Diese Methode erleichterte die Behebung bestimmter Fehler und förderte ein tieferes Verständnis der Programmierumgebung. Darüber hinaus haben wir kurz das Potenzial des Einsatzes von künstlicher Intelligenz als künftige Hilfe bei der Fehlersuche angesprochen und ihre Fähigkeit hervorgehoben, Erkenntnisse und Empfehlungen zu liefern, die den Fehlersuchprozess rationalisieren könnten.
Die Unterstützung durch die Gemeinschaft, insbesondere durch das MQL5-Forum, ist von unschätzbarem Wert, da sie es uns ermöglicht, Ratschläge einzuholen und Wissen mit anderen erfahrenen Entwicklern auszutauschen. Durch diese umfassende und ressourcenorientierten Ansätze können wir die Effektivität unserer Fehlerbehebungsbemühungen erheblich steigern, was letztlich zur Entwicklung zuverlässigerer und innovativerer Handelslösungen im wettbewerbsintensiven Umfeld des algorithmischen Handels führt. Fröhliches Handeln, liebe Kollegen!
Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/15325





- 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.