How to Convert ObjectSet in MQL4 to MQL5?

Migrating code from MQL4 to MQL5 often involves understanding subtle yet significant changes in function behavior and philosophy. One such area is the management of graphical object properties, specifically the transition away from the MQL4 ObjectSet() function.

Brief Overview of MQL4 and MQL5

MQL4, the language of MetaTrader 4, is a procedural language with some object-oriented elements. MQL5, for MetaTrader 5, is a more fully-fledged object-oriented language with stricter type checking and a more extensive standard library. This philosophical shift towards explicitness and type safety is evident in how object properties are handled.

The Role of ObjectSet Function in MQL4

In MQL4, ObjectSet(string name, int prop_id, double prop_value) was a versatile, albeit somewhat ambiguous, function. It was used to modify various properties of a graphical object on a chart. A key characteristic was its reliance on implicit type casting: the double prop_value argument would be automatically converted to the required type (integer, boolean, color, datetime) based on the prop_id specified. While convenient, this could sometimes lead to subtle bugs or unexpected behavior if the type conversion wasn’t what the developer intended.

For instance, setting a color property using ObjectSet(name, OBJPROP_COLOR, Red) would work, with Red (an integer constant) being passed as a double and then implicitly cast back. Similarly for boolean properties like OBJPROP_BACK.

Why ObjectSet is Obsolete in MQL5

MQL5 deprecates the generic ObjectSet() function in favor of a set of type-specific functions:

  • ObjectSetInteger()
  • ObjectSetDouble()
  • ObjectSetString()

This change aligns with MQL5’s emphasis on strong typing and explicitness. It eliminates ambiguity in type conversions, makes code easier to read and debug, and provides better compile-time checks. Each function expects a value of the correct type for the property being set, reducing the chances of runtime errors or incorrect property assignments.

Identifying Object Properties and Their MQL4 Equivalents

Most OBJPROP_* constants from MQL4 retain their names and general purpose in MQL5. The primary difference lies in how you set them. You must now choose the correct ObjectSetTYPE() function based on the data type of the property.

Commonly Used Object Properties in MQL4 (OBJPROP_*) and their MQL5 Counterparts

Here’s a list of common MQL4 properties and how they translate to MQL5 usage:

  • Coordinates and Time/Price Values:
    • MQL4: OBJPROP_TIME1, OBJPROP_PRICE1, OBJPROP_TIME2, OBJPROP_PRICE2, etc.
    • MQL5: Use OBJPROP_TIME and OBJPROP_PRICE with a modifier (index of the point: 0, 1, 2…). Set using ObjectSetInteger() for time (datetime) and ObjectSetDouble() for price.
  • Appearance Properties:
    • OBJPROP_COLOR: MQL5 uses ObjectSetInteger(). The value is a color type.
    • OBJPROP_STYLE: MQL5 uses ObjectSetInteger(). The value is an ENUM_LINE_STYLE integer.
    • OBJPROP_WIDTH: MQL5 uses ObjectSetInteger().
    • OBJPROP_BACK (background drawing): MQL5 uses ObjectSetInteger(). The value is bool (0 or 1).
    • OBJPROP_RAY_RIGHT (was OBJPROP_RAY for trendlines): MQL5 uses ObjectSetInteger(). The value is bool (0 or 1). Similarly for OBJPROP_RAY_LEFT.
  • Text and Font Properties:
    • OBJPROP_TEXT: MQL5 uses ObjectSetString().
    • OBJPROP_FONTSIZE: MQL5 uses ObjectSetInteger().
    • OBJPROP_FONT: MQL5 uses ObjectSetString().
  • Level-Based Properties (e.g., for Fibonacci, Gann objects):
    • OBJPROP_LEVELS (number of levels): MQL5 uses ObjectSetInteger().
    • OBJPROP_LEVELCOLOR: MQL5 uses ObjectSetInteger() with a level index as a modifier.
    • OBJPROP_LEVELSTYLE: MQL5 uses ObjectSetInteger() with a level index as a modifier.
    • OBJPROP_LEVELWIDTH: MQL5 uses ObjectSetInteger() with a level index as a modifier.
    • OBJPROP_LEVELVALUE: MQL5 uses ObjectSetDouble() with a level index as a modifier (e.g., 0.5, 0.618 for Fibo).
    • OBJPROP_LEVELTEXT: MQL5 uses ObjectSetString() with a level index as a modifier (description of the Fibo level).

Mapping MQL4 Object Properties to MQL5

The core principle for mapping is to identify the data type of the MQL4 property you were setting with ObjectSet():

  1. If the property expects an integer, color, boolean, or datetime (which MQL treats as a long integer), use ObjectSetInteger() in MQL5.
  2. If the property expects a floating-point number (e.g., price, level value), use ObjectSetDouble() in MQL5.
  3. If the property expects a text string (e.g., object description, font name), use ObjectSetString() in MQL5.

For properties that refer to specific parts of an object (like anchor points of a trendline or levels of a Fibonacci object), MQL5 functions often use an additional prop_modifier argument. This argument specifies the index of the point or level being modified.

Implementing Object Property Modifications in MQL5

To effectively modify object properties in MQL5, you’ll primarily use the ObjectSetInteger(), ObjectSetDouble(), and ObjectSetString() functions. Their counterparts, ObjectGetInteger(), ObjectGetDouble(), and ObjectGetString(), are used for retrieving property values.

Using ObjectGetInteger, ObjectGetDouble, and ObjectGetString in MQL5

These functions retrieve property values. Their signatures are typically:

bool ObjectGetInteger(long chart_id, string object_name, int prop_id, int prop_modifier, long& long_var)
bool ObjectGetDouble(long chart_id, string object_name, int prop_id, int prop_modifier, double& double_var)
bool ObjectGetString(long chart_id, string object_name, int prop_id, int prop_modifier, string& string_var)

For properties that are not indexed (e.g., OBJPROP_COLOR), the prop_modifier is often omitted or set to 0, and a simpler overload is used:

long ObjectGetInteger(long chart_id, string object_name, int prop_id)
double ObjectGetDouble(long chart_id, string object_name, int prop_id)
string ObjectGetString(long chart_id, string object_name, int prop_id)

Using ObjectSetInteger, ObjectSetDouble, and ObjectSetString in MQL5

These are the direct replacements for MQL4’s ObjectSet() functionality.

  • bool ObjectSetInteger(long chart_id, string object_name, int prop_id, long prop_value)

  • bool ObjectSetInteger(long chart_id, string object_name, int prop_id, int prop_modifier, long prop_value)

    • Used for integer-based properties like colors, styles, widths, counts, boolean flags, and datetime values.
  • bool ObjectSetDouble(long chart_id, string object_name, int prop_id, double prop_value)

  • bool ObjectSetDouble(long chart_id, string object_name, int prop_id, int prop_modifier, double prop_value)

    • Used for double-precision floating-point properties like prices and level values.
  • bool ObjectSetString(long chart_id, string object_name, int prop_id, string prop_value)

  • bool ObjectSetString(long chart_id, string object_name, int prop_id, int prop_modifier, string prop_value)

    • Used for string properties like text, descriptions, and font names.

The chart_id is typically 0 for the current chart. The prop_modifier argument is used for properties that are indexed, such as levels in a Fibonacci object or anchor points of a trendline.

Code Examples: Converting ObjectSet Functionality to MQL5

Let’s illustrate with common scenarios:

Example 1: Changing the color of a trendline

MQL4:

string objectName = "MyTrendLine";
// ... object creation ...
ObjectSet(objectName, OBJPROP_COLOR, clrRed);

MQL5:

string objectName = "MyTrendLine";
// ... object creation ...
ObjectSetInteger(0, objectName, OBJPROP_COLOR, clrRed);

Example 2: Setting the price of the first anchor point of a trendline

MQL4:

string objectName = "MyTrendLine";
double price1 = 1.12345;
// ... object creation ...
ObjectSet(objectName, OBJPROP_PRICE1, price1);

MQL5:

string objectName = "MyTrendLine";
double price1 = 1.12345;
// ... object creation ...
// The first anchor point has index 0 for prop_modifier
ObjectSetDouble(0, objectName, OBJPROP_PRICE, 0, price1);

Example 3: Setting the text for a label object

MQL4:

string objectName = "MyLabel";
string labelText = "Important Level";
// ... object creation ...
ObjectSet(objectName, OBJPROP_TEXT, labelText); // Implicit cast of string to double (problematic), 
                                              // better to use ObjectSetText directly in MQL4.
                                              // For the sake of ObjectSet general conversion:
// if OBJPROP_TEXT was handled by the generic ObjectSet(name, prop_id, double_value)
// MQL4 actually does not have a direct OBJPROP_TEXT that accepts double. 
// ObjectSetText() is the proper MQL4 function for this.
// However, if we imagine a scenario where one tried to misuse ObjectSet:
// ObjectSet(objectName, OBJPROP_TEXT, StringToDouble(labelText)); // This would be wrong.

// Correct MQL4 for individual text property:
// ObjectSetText(objectName, labelText, 10, "Arial", clrNONE); 
// To just set the text value using a generic property setter (which MQL4 `ObjectSet` isn't ideal for text):
// It's more direct to use ObjectSetString in MQL4 too if available, or ObjectSetText.
// Assuming the user meant `ObjectSetString(0, objectName, OBJPROP_TEXT, labelText);` conceptually

MQL5:

string objectName = "MyLabel";
string labelText = "Important Level";
// ... object creation ...
ObjectSetString(0, objectName, OBJPROP_TEXT, labelText);

Example 4: Setting a Fibonacci level’s value and description

MQL4 (using specialized functions, as ObjectSet was less direct for specific level properties):

string fiboName = "MyFibo";
int levelIndex = 1; // Second level (0-indexed)
double levelValue = 0.618;
string levelDescription = "61.8% Retracement";
// ... object creation with some levels ...
ObjectSetFiboDescription(fiboName, levelIndex, levelDescription);
ObjectSetLevelValue(fiboName, levelIndex, levelValue);

MQL5:

string fiboName = "MyFibo";
int levelIndex = 1; // Second level (0-indexed)
double levelValue = 0.618;
string levelDescription = "61.8% Retracement";
// ... object creation with some levels ...
ObjectSetDouble(0, fiboName, OBJPROP_LEVELVALUE, levelIndex, levelValue);
ObjectSetString(0, fiboName, OBJPROP_LEVELTEXT, levelIndex, levelDescription);

Advanced Techniques and Considerations

Beyond direct conversion, keep these points in mind for robust MQL5 object management.

Handling Object Existence and Errors

Always verify that an object exists before attempting to modify its properties. Use ObjectFind(chart_ID, name) which returns the subwindow index if found, or -1 if not.

string objectName = "MyObject";
if (ObjectFind(0, objectName) < 0)
{
    PrintFormat("Error: Object '%s' not found.", objectName);
    return;
}

// Proceed with ObjectSet... functions
if (!ObjectSetInteger(0, objectName, OBJPROP_COLOR, clrBlue))
{
    PrintFormat("Error setting color for object '%s'. Error code: %d", objectName, GetLastError());
}

All ObjectSet* functions return true on success and false on failure. Use GetLastError() to retrieve detailed error information when a function fails.

Performance Optimization Tips in MQL5 Object Management

  • Minimize Redundant Calls: Avoid setting properties repeatedly to the same value within a loop or frequent event handler like OnTick(). Check the current value with ObjectGet* if necessary, or manage state within your EA/indicator.
  • Group Visual Updates: While MQL5 doesn’t offer a batch property update function, consider if multiple property changes can be logically grouped. After all modifications, call ChartRedraw() once if immediate visual update is required, rather than relying on implicit redraws after each change, or calling it multiple times.
  • Cache Object Handles/Names: If dealing with many objects or frequent access, caching names or relevant data can be beneficial, though direct object handles are not exposed in MQL5 in the same way as in some other graphical systems.

Handling Properties with Modifiers (Indexed Properties)

As shown in the examples for trendline anchor points and Fibonacci levels, many MQL5 ObjectSet* functions include a prop_modifier argument. This integer argument specifies which part of a complex object you are targeting. Common uses include:

  • Anchor point index (0, 1, 2…) for objects like trendlines, rectangles, channels (OBJPROP_TIME, OBJPROP_PRICE).
  • Level index for objects like Fibonacci, Gann, Andrew’s Pitchfork (OBJPROP_LEVELCOLOR, OBJPROP_LEVELSTYLE, OBJPROP_LEVELWIDTH, OBJPROP_LEVELVALUE, OBJPROP_LEVELTEXT).

Consult the MQL5 documentation for OBJPROP_* constants to understand when a prop_modifier is required and what it signifies for a particular property and object type.

Conclusion: Embracing MQL5’s Object Management System

The transition from MQL4’s ObjectSet to MQL5’s type-specific ObjectSetInteger, ObjectSetDouble, and ObjectSetString functions is a positive step towards more robust and maintainable code.

Recap of MQL4 to MQL5 Object Property Conversion

The key is to identify the data type of the property you intend to set and use the corresponding MQL5 function (ObjectSetInteger, ObjectSetDouble, or ObjectSetString). For properties that apply to specific parts of an object (e.g., anchor points, levels), utilize the prop_modifier argument in the MQL5 function call.

Benefits of Using MQL5’s Approach

  • Type Safety: Reduces errors caused by implicit type conversions.
  • Code Clarity: Makes the programmer’s intent clearer regarding the type of data being set.
  • Improved Debugging: Type mismatches can often be caught at compile-time or lead to more predictable runtime behavior.
  • Consistency: Aligns with the overall design philosophy of MQL5, which favors explicit operations.

Further Learning Resources for MQL5 Object Functions

For detailed information on all object functions, properties, and their usage in MQL5, the official MetaQuotes documentation is indispensable. Specifically, look for sections related to:

  • Object Functions
  • Object Properties (OBJPROP_* constants)
  • Standard Constants, Enumerations, and Structures (for ENUM_LINE_STYLE, etc.)

Familiarizing yourself with these resources will ensure you can leverage the full power and precision of MQL5’s object management capabilities.


Leave a Reply