preview
From Novice to Expert: Collaborative Debugging in MQL5

From Novice to Expert: Collaborative Debugging in MQL5

MetaTrader 5Examples | 3 October 2024, 14:16
361 0
Clemence Benjamin
Clemence Benjamin

Core Content 


Introduction:

Typically, every author aims to address a specific problem from the beginning to the end of an article. Our title today is "Debugging," but I encourage you not to take it lightly, as we will explore much more than just the basics of the process. I will share the techniques I have employed over the years in multiple successful projects. In all areas of software programming, debugging is a topic that cannot be overlooked. I’ve noticed that many authors focus on presenting a polished final product without sharing the struggles they faced to get the code working correctly.

Whether it’s in neural network systems, artificial intelligence, or other related software disciplines, debugging is essential. I believe that the most valuable skill you can develop is the ability to solve problems as they arise, and this skill becomes an integral part of you for future challenges of a similar nature. Thus, problem-solving can build a strong skill set, gradually transforming someone into an expert.

Collaborative Debugging

Collaborative Debugging

When I committed to writing this article, I was working on a project in which I encountered several errors while trying to compile the code. At times, the debugger would present me with 50 error lines to address. Through trial and error, I developed a routine for tackling bugs that allows me to resolve issues in just a few minutes, if not seconds, and get the program running smoothly.

My goal is to make you aware of the technologies that can accelerate the debugging process. In my experience, one of the most valuable lessons I've learned is that mastering MQL5 can be quick and effective when you actively engage in debugging projects. I have preserved a buggy program that we will walk through together and refine.

One of the most enduring challenges is that many people struggle to endure the lengthy MQL5 books available for free, but that doesn’t make them any less valuable. These books contain essential knowledge ranging from basic to advanced MQL5 programming concepts. To achieve the best results, it’s wise to participate in active projects while referring to these books for specific topics related to your ongoing work. As you complete these projects, you will naturally absorb a wealth of knowledge.

Typically, our bug reports are organized into four columns, as described in the table below.

Column (Names) Explanation
Description This column provides a brief explanation of the error or warning encountered in the code. It can describe the nature of the issue, such as syntax errors, undeclared variables, type mismatches, or other coding mistakes. Understanding the description helps the programmer to quickly identify the problem.
File Here, the name of the file where the error occurred is indicated (e.g. D1 PriceMarker.mq5). In the case of multiple files in a project, knowing which file contains the issue is crucial for effective debugging and correction.
Line Specifies the exact line number within the indicated file where the error is found. This pinpointing allows the programmer to quickly navigate to the specific part of the code that requires attention, reducing the time needed to locate the issue.
Column, This indicates the specific column number on the line where the error was detected. Although it's less commonly referenced than the previous columns, it can be particularly useful for identifying errors that occur in complex statements or when the line contains many elements (like multiple function calls or parameters).

They are typically arranged from left to right, as shown below. We have also included the complete error report, which comprises 20 errors and 4 warnings (see the bottom of the snippet), for the program we will debug in this discussion, just below the table layout. You will find it easy to identify the features of the report. If you read to the end, we will discuss how to resolve the errors presented in the code snippet below.

Description File Line Column

'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

Here are some common terms to understand when discussing this topic:

  • Syntax: refers to the specific set of rules that dictate how programs (such as trading algorithms, indicators, and scripts) must be written in order for the MetaTrader 5 platform to understand and execute them correctly.
  • Error: refers to a mistake or an issue in the code that prevents it from executing correctly. Errors can be categorized into several types as Syntax Errors, Runtime Errors, Logical Errors, Type Errors, and Compilation Errors.


What is Debugging?

I am sure most of you are familiar with this vibrant term, but it is essential for beginners to grasp the concept in detail. Now, I will define a bug so that you can better understand the process of debugging.

  • Bug:

An error, or defect, in a computer program or system, that causes it to behave unexpectedly or incorrectly. 

  • Debugging:

It is the process of identifying, isolating, and fixing errors or bugs in a computer program or system with the goal to ensure that the program behaves as intended and produces the correct outputs under various conditions.

Debugging in the Context MQL5 Programming

Here are some aspects of debugging specifically related to MQL5:

 1. Common Types of Bugs in MQL5:

  • Syntax Errors: Mistakes in MQL5 code structure that prevent the script from compiling.

This example displays a simple syntax error where the closing parenthesis for the Print() function is missing. As a result, the script will fail to compile, highlighting the need to check code structure carefully.

void OnStart()
{
    Print("Hello, World!" // Missing closing parenthesis
}
  • Logical Errors: Issues where the code compiles and runs but produces incorrect trade signals or behaves unexpectedly.

Here's, a logical error where the conditions wrongly trigger a buy order. The programmer intended to leverage a more complex logic that depends on market conditions, but the current implementation leads to unnecessary trades.

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);
    }
}
  • Runtime Errors: Errors that occur during execution, such as attempting to access an out-of-bounds array or not properly handling trading orders.
In this example, an attempt is made to access the sixth element of an array that only has five valid indices. This will result in a runtime error, which illustrates the importance of bounds-checking when working with arrays.
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. Debugging Tools in MQL5:

  • MetaEditor: This is the integrated development environment (IDE) for MQL5. It provides syntax highlighting, code completion, and error indication that can help identify syntax errors quickly.
The code, below, allows for the setting of a breakpoint on the result variable calculation. When debugging in MetaEditor, you can inspect variables at this point to confirm they're set as expected, facilitating line-by-line execution to analyze the program's flow.
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
}
  • Print Statements: Using the Print() function to output variable values and execution flow logs to the Experts log. This is a straightforward way to trace issues.
In this example code snippet, we use the Print() function to log the current bid and ask prices. This approach is beneficial for tracing variable values during execution and can help diagnose logical errors by comparing expected vs. actual values.
void OnTick()
{
    double bidPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
    double askPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
    
    // Logging prices for debugging
    Print("Bid: ", bidPrice, ", Ask: ", askPrice);
}
  • Commenting Out Code: Temporarily disabling sections of code to isolate the problem area.
In this example, a line of code is commented out to focus on the alternate logic. This technique is useful for isolating bugs and testing different sections of the code without complete removal.
void OnTick()
{
    // double result = SomeFunction(); // Temporarily disabling this line
    
    // Run alternate logic while debugging
    Print("Running alternative logic.");
}
3. Using the Debugger in MetaEditor:

MetaEditor includes a built-in debugger that allows for:
  • Breakpoints: Setting breakpoints in your code allows you to pause execution at specific lines and inspect variable values.
  • Step Through Execution: You can step through the code line by line to observe how variables change and how the flow of logic follows.
  • Watch Expressions: Monitoring the values of specific variables throughout the execution of the code.
 4. Testing and Optimization:
  • Strategy Tester: MQL5 provides a Strategy Tester that allows you to conduct back-tests on trading strategies using historical data. It helps simulate trades and analyzes the performance, which can reveal hidden bugs.
  • Optimization: You can optimize parameters to improve the performance of your trading algorithm, which may also highlight potential bugs in logic or execution.
 5. Error Handling:
  • Handling MQL5-specific error codes, such as checking the return values of functions related to trading operations. Common functions include order execution functions (OrderSend, OrderClose, etc.), where proper error handling can prevent crashes or undesired outcomes.

Best Practices for Debugging in MQL5:

1. Code Modularity: Write modular code by breaking it down into functions. This makes it easier to test and debug individual components. 2. Documenting Code: Comment your code to explain what each part does, which can help when revisiting code after some time. 3. Regular Testing: Frequently test the code during development instead of waiting until everything is complete. This helps catch bugs early.


Implementation of Debugging in MQL5

Not long ago, my friend and I created a rough draft of a script to draw labeled price lines for the previous daily (D1) candlestick, marking critical price levels such as High, Low, Open, and Close. This is the version I have set aside for this article. 

Typically, when writing as an expert, MetaEditor provides templates and parameter suggestions to assist developers and help reduce the chances of errors, provided the details are entered according to the correct language syntax. However, there are instances when you might receive code from a forum, that is cluttered with errors. Below is a code snippet from our buggy script program:

//+------------------------------------------------------------------+
//|                                               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) Locating a Bug

I have found MetaEditor’s built-in debugger to be quite user-friendly when I attempt to compile a faulty program. Most bugs are caught when you click the Compile or Real-time Profiling button in MetaEditor. However, there are some performance errors that do not prevent the program from compiling; these can only be identified on the platform or tester when you try to run the program.

A developer may either write the entire program from scratch and then debug it, or simply debug a pre-existing program. In the image below, we take advantage of the built-in compiler and debugger in MetaEditor to obtain an error summary (see the bottom of the toolbox window in the image). By double-clicking on an error line, the cursor moves to and highlights the corresponding line of code with the error. I have rarely noticed errors in the code until I hit the Compile button, at which point the debugger reports any issues that arise.

Locating errors

Locating Errors in MetaEditor

Sometimes the program will compile successfully, but may not produce the desired outcome. In such cases, it is wise to identify potential errors by checking the Expert Logs and Journal prints available in the toolbox window on the MetaTrader 5 platform. These logs can provide valuable insights into what might be going wrong during execution, helping you to troubleshoot and resolve issues effectively.

(ii) 3 technics Debugging

Errors can often arise from typing mistakes or the misuse of terms, and the debugger typically provides explanations and partial hints towards a solution. If you can understand these messages, it’s usually straightforward to revisit the code and make the necessary corrections. However, there are more complex situations that can be difficult to diagnose and may require more in-depth knowledge from reference books or expertise from the community.

In my experience, I commonly use a few strategies when debugging complex issues. I categorize these steps into three main approaches, though this list is not exhaustive; it is intended specifically for the purpose of this discussion. Let me explain each step of the procedure in detail.

1. Revisiting the Documentation:

It significantly aids in debugging MQL5 programs by providing clarity on syntax, function usage, and error messages. It offers detailed explanations and examples that help identify incorrect implementations and enhance understanding of built-in functions. Additionally, documentation often includes information on common errors, best practices, and alternative solutions, enabling developers to troubleshoot issues effectively and optimize their code for better performance. For this project, look the image below to see how we easily access documentation.

Revisiting the Documentation

Revisiting the documentation

Error Report:

'ObjectDelete' - wrong parameters count D1 PriceMarker.mq5      70      5

Solution Hint:

   built-in: bool ObjectDelete(long,const string)       D1 PriceMarker.mq5      70      5

Current situation:

   ObjectDelete("PrevCandle_Open");

From the solution hint, it is evident that the function ObjectDelete expects two parameters, but we are currently providing only one. This discrepancy indicates where the problem lies, and we can address it accordingly. According to the documentation, the ObjectDelete function in MQL5 requires two parameters:

  1. Name: The name of the object to delete, specified as a string.
  2. Chart_id: The ID of the chart from which the object should be deleted, specified as an integer. If omitted, the function defaults to the current chart.

To resolve this issue, we need to ensure that we pass both parameters when calling ObjectDelete. By doing so, we align our function call with the expected syntax and thereby eliminate the error.

    Resolution:

    ObjectDelete(0, "PrevCandle_Open");

    Now, looking through the main code, we notice that there are several instances of the ObjectDelete function. Using the information we've gathered from our research, we can make the necessary adjustments to all of them. By ensuring that we provide both required parameters for each instance, we can resolve these errors effectively.

    Refer to the image below to see how we managed to reduce the total number of errors by 10. This indicates significant progress in debugging our script and demonstrates the importance of thorough examination and correction based on proper documentation.

    ObjectDelete Function resolved

    ObjectDelete function error resolved

    It’s done! When you encounter an error, it's a good practice to hit the Compile button after each solution attempt. This allows you to check if the error still persists and helps you identify any remaining issues.

    Now, let’s move on to our next error.

    Error Report:

    '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

    This time, I gathered multiple reports because, if you check, the errors are occurring on the same line. This often indicates a common issue that needs to be addressed in that specific part of the code. Let's take a closer look at the line in question to identify the underlying problem and determine the necessary corrections.

    Solution Hints:

    In this scenario, we encounter the following errors: (undeclared identifier, expected operator, expression has no effect, and unexpected token).

    Current situation:

    ObjectSetText(labelName, label + ": " + DoubleToString(price, 2), 10, "Arial", clr);
                
    

    I checked the documentation and couldn't find any reference to ObjectSetText. However, when I started typing ObjectSet..., several suggestions appeared, with ObjectSetString being the best option. This function turned out to be the correct one, and it worked as expected.

    You can see our efforts reflected below.

    ObjectSetText not available in Documentation

    ObjectSetText not available in documentation


    ObjectSetString

    ObjectSetString

    ObjectSetString functions parameters according to documentation:

    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
       );

    Resolution:

    By making the necessary adjustments, similar to what we did for the first error, we were able to resolve almost all the issues. Now, only a few lines remain to be corrected. Let’s focus on those final adjustments to completely clear up the remaining errors.

     ObjectSetString(0, labelName, OBJPROP_TEXT, label + ": " + DoubleToString(price, 2));

    A few bugs to go:

    2 error to go

    2 Errors remaining

    Finally, fixing the remaining errors:

    ObjectSetInteger(0, labelName, OBJPROP_YDISTANCE, price); // Position label at the price level

    It was supposed to be OBJPROP_YDISTANCE, not OBJPROP_Y.

    Errors cleared and the program compiles now

    Successful Debugging with the reference to Documentation

    Our final cleaned code is here:

    //+------------------------------------------------------------------+
    //|                                               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, is an MQL5 script program we designed to enhance technical analysis on a trading chart by drawing horizontal lines at the high, low, open, and close prices of the previous daily (D1) candle. Upon initialization, the script retrieves these four price points and utilizes a helper function to create corresponding price lines in distinct colors (blue for open, red for high, green for low, and orange for close), each accompanied by a labeled text indicating the price value. When the script is removed from the chart, it automatically cleans up by deleting all the drawn lines and labels, ensuring a tidy workspace for the trader.

    2. Debugging with AI:

    I understand that everyone is eager to learn how we utilize available AI models, so I’ll briefly touch on this topic to save for a more in-depth discussion later. We are fortunate that most of these models can understand syntax more quickly and accurately than we can. However, it's important to note that they can sometimes produce unexpected results and may require closer human oversight to guide their next steps. Nevertheless, they are excellent tools when used wisely, and I have solved many coding challenges by carefully considering their suggestions.

    Essentially, when crafting an AI prompt, you should start by providing the program you want to debug. Then, by utilizing the ability to copy error lines from the MetaEditor report, you can paste those lines into the prompt, allowing the AI to assist with the debugging process. While this method can yield successful results, it can also lead to further complications, so it’s essential to think critically and go the extra mile beyond what the AI suggests. The results we achieved earlier are consistent with what other debugging tools should produce, provided they are used effectively.

    Copy Errors

    Copying Errors to an AI prompts

    3. Visiting the forum:

    Similar to what we did above, forum members need information to provide valuable debugging insights. Engaging in discussions about coding challenges is a fantastic way to learn from other experts. By submitting your program, you invite others to share their wise suggestions and solutions. This collaborative approach not only helps you solve your problems but also enhances everyone's knowledge and skills.

    Program on MetaTrader 5:

    D1 PriceMarker

    D1 PriceMarker script 


    Conclusion

    Teamwork in MQL5 programming proves to be an essential practice for enhancing the development of robust trading algorithms, as illustrated throughout our journey in creating the D1 PriceMarker script. The debugging process relied heavily on error reports and the comprehensive MQL5 reference documentation, allowing us to systematically identify and address issues faced during development.

    This method facilitated the resolution of specific errors and fostered a more profound understanding of the programming environment. Furthermore, we briefly touched on the potential of leveraging artificial intelligence as a future aid in debugging, highlighting its ability to provide insights and recommendations that could streamline the debugging process.

    Community support, particularly through the MQL5 forum, play an invaluable role, enabling us to seek advice and share knowledge with other experienced developers. By embracing these collaborative and resource-driven approaches, we can significantly enhance the effectiveness of our debugging efforts, ultimately leading to the development of more reliable and innovative trading solutions in the competitive landscape of algorithmic trading. Happy trading, fellows!

    Attached files |
    D1_PriceMarker.mq5 (3.31 KB)
    Сode Lock Algorithm (CLA) Сode Lock Algorithm (CLA)
    In this article, we will rethink code locks, transforming them from security mechanisms into tools for solving complex optimization problems. Discover the world of code locks viewed not as simple security devices, but as inspiration for a new approach to optimization. We will create a whole population of "locks", where each lock represents a unique solution to the problem. We will then develop an algorithm that will "pick" these locks and find optimal solutions in a variety of areas, from machine learning to trading systems development.
    MQL5 Wizard Techniques you should know (Part 41): Deep-Q-Networks MQL5 Wizard Techniques you should know (Part 41): Deep-Q-Networks
    The Deep-Q-Network is a reinforcement learning algorithm that engages neural networks in projecting the next Q-value and ideal action during the training process of a machine learning module. We have already considered an alternative reinforcement learning algorithm, Q-Learning. This article therefore presents another example of how an MLP trained with reinforcement learning, can be used within a custom signal class.
    Features of Experts Advisors Features of Experts Advisors
    Creation of expert advisors in the MetaTrader trading system has a number of features.
    Gain An Edge Over Any Market (Part V): FRED EURUSD Alternative Data Gain An Edge Over Any Market (Part V): FRED EURUSD Alternative Data
    In today’s discussion, we used alternative Daily data from the St. Louis Federal Reserve on the Broad US-Dollar Index and a collection of other macroeconomic indicators to predict the EURUSD future exchange rate. Unfortunately, while the data appears to have almost perfect correlation, we failed to realize any material gains in our model accuracy, possibly suggesting to us that investors may be better off using ordinary market quotes instead.