Converting code from MQL5 to MQL4 is a common challenge for traders transitioning between MetaTrader platforms or needing to maintain compatibility with older systems. While MQL5 offers significant improvements in terms of syntax, object-oriented programming, and backtesting capabilities, MQL4 remains widely used. This guide provides a structured approach to converting MQL5 code to MQL4, covering key differences, conversion strategies, and practical examples.
Understanding the Differences Between MQL5 and MQL4
Key Architectural Differences: Object-Oriented vs. Procedural
The most fundamental difference is that MQL5 supports object-oriented programming (OOP), while MQL4 is primarily procedural. MQL5 allows the creation of classes, inheritance, and polymorphism, enabling more modular and reusable code. MQL4 relies on functions and global variables.
MQL5: Encourages modular design using classes.
MQL4: Uses a procedural approach with functions.
Data Types and Structures: A Detailed Comparison
MQL5 introduces several new data types and structures not available in MQL4, like ENUM, struct and advanced casting rules. Understanding these differences is crucial for a smooth conversion.
- MQL5 offers more explicit type control and advanced type casting.
- MQL4 has fewer data types and implicit conversions, which can lead to unexpected behavior.
Order Execution Model: Differences in Order Management
The order execution model differs significantly between the two languages. MQL5 offers more granular control over order placement and modification using order tickets and handles, whereas MQL4 uses a simpler, less flexible approach. MQL5 uses OrderSend() with a MqlTradeRequest structure for advanced order parameters, which do not exist in MQL4. MQL4 primarily uses the older OrderSend() function, which is also available in MQL5 for compatibility reasons.
MQL5: Utilizes OrderSend() with MqlTradeRequest for flexible control.
MQL4: Employs the simpler OrderSend() function, limited options.
Differences in Built-in Functions and Libraries
MQL5 has an expanded set of built-in functions and standard library. Functions for string manipulation, date/time handling, and mathematical operations are more comprehensive in MQL5. Many functions have different names and parameter lists. Certain MQL5 functions like CopyBuffer (for indicator buffer manipulation) need adaptation in MQL4.
Strategies for Converting MQL5 Code to MQL4
Analyzing MQL5 Code for MQL4 Compatibility
Before starting the conversion, carefully analyze the MQL5 code to identify incompatible features, particularly OOP constructs and advanced data types. Note all instances where specific MQL5 functions are used.
Rewriting Object-Oriented Code to Procedural Style
This is often the most challenging part. Convert classes into structures or global variables and replace method calls with function calls. Consider using function prefixes to emulate namespaces. For example, a class MyClass might be converted into a set of functions prefixed with MyClass_. This ensures that functions that previously belonged to the same class logically remain related.
Replacing MQL5 Functions with MQL4 Equivalents
Identify MQL5 functions that don’t exist in MQL4. Replace these with equivalent MQL4 functions or custom implementations. Refer to the MQL4 documentation for available functions and their usage. For example, StringSubstr in MQL5 is equivalent to StringMid in MQL4.
Handling Data Type Conversions: int, double, string, etc.
Pay close attention to data type conversions, as implicit conversions in MQL4 can lead to errors. Explicitly cast variables where necessary to avoid unexpected results. MQL4 is less strict with type conversions compared to MQL5, meaning that a seemingly valid MQL5 cast may not be compatible. For instance, converting from datetime to string may have subtle differences in format.
Practical Conversion Examples: From MQL5 to MQL4
Converting a Simple Indicator from MQL5 to MQL4
MQL5 (Example):
// MQL5
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
#property indicator_type1 DRAW_LINE
double buffer[];
int OnInit()
{
SetIndexBuffer(0,buffer,INDICATOR_DATA);
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[])
{
for(int i=prev_calculated; i<rates_total; i++)
{
buffer[i] = (high[i] + low[i]) / 2.0;
}
return(rates_total);
}
MQL4 (Equivalent):
// MQL4
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
#property indicator_type1 DRAW_LINE
double ExtMapBuffer[];
int init()
{
SetIndexBuffer(0,ExtMapBuffer);
return(0);
}
int start()
{
int counted_bars=IndicatorCounted();
for(int i=Bars-counted_bars-1; i>=0; i--)
{
ExtMapBuffer[i]=(High[i]+Low[i])/2;
}
return(0);
}
Converting an Expert Advisor: A Step-by-Step Guide
- Identify OOP components: Determine which parts use classes and objects.
- Rewrite to procedural: Convert classes to structures and methods to standalone functions.
- Adapt OrderSend: Modify the order placement logic to use the MQL4
OrderSend()function, accounting for differences in parameters. - Handle MarketInfo: Adapt
SymbolInfoDouble()or similar functions toMarketInfo()in MQL4. - Thoroughly test: Backtest the converted EA extensively to ensure functionality.
Example: Converting a Custom Function
Let’s say you have an MQL5 function to calculate the average of an array:
MQL5:
double CalculateAverage(const double &arr[]) {
double sum = 0;
for (int i = 0; i < ArraySize(arr); i++) {
sum += arr[i];
}
return sum / ArraySize(arr);
}
MQL4 Equivalent:
double CalculateAverage(double arr[]) {
double sum = 0;
int size = ArraySize(arr);
for (int i = 0; i < size; i++) {
sum += arr[i];
}
return sum / size;
}
Troubleshooting Common Conversion Issues
Debugging MQL4 Code After Conversion
Use the MQL4 IDE’s debugger to step through the code and identify errors. Pay close attention to variable values and function return values. Incorrect data type conversions are a common source of errors. Use Print() statements strategically to track variables during execution.
Addressing Compatibility Issues with Libraries and Includes
Ensure that any included libraries are compatible with MQL4. Replace MQL5-specific includes with MQL4 equivalents or find alternative libraries. If no equivalent exists, you might need to rewrite the library functionality.
Handling Errors Related to Order Management
Order management is a frequent source of problems. Double-check the order parameters passed to OrderSend() and ensure they are valid for the current market conditions. Verify trade context settings and error codes returned by OrderSend().
Tools and Resources for MQL5 to MQL4 Conversion
Using MQL4 IDE for Development and Debugging
The MQL4 IDE is an essential tool for writing, compiling, and debugging MQL4 code. It provides syntax highlighting, code completion, and a debugger for identifying and fixing errors.
Online Forums and Communities for MQL4 Support
Online forums such as the MetaQuotes MQL4 community are valuable resources for getting help with MQL4 programming. You can ask questions, share code, and learn from other developers.
Available Libraries and Code Snippets for MQL4
Various MQL4 libraries and code snippets are available online, offering ready-made solutions for common tasks. These can save time and effort during the conversion process. Consider using libraries for common tasks such as string manipulation or mathematical calculations.