Enums and strings are fundamental data types in MQL4. Mastering their use is crucial for writing robust, readable, and maintainable trading programs. This article explores effective ways to leverage enums and strings in MQL4, with a focus on practical applications and best practices.
Introduction to Enums in MQL4
What are Enums and Why Use Them?
Enums (enumerations) provide a way to define a set of named integer constants. They significantly improve code readability and maintainability. Instead of using magic numbers scattered throughout your code, you can use descriptive names. For example, instead of 1 for BUY and 2 for SELL, enums allow you to define enum { BUY, SELL };. This makes the code self-documenting and reduces the risk of errors.
Declaring and Defining Enums in MQL4
Enums are declared using the enum keyword followed by the enumeration name and a list of named constants enclosed in curly braces. Each constant is assigned an integer value, starting from 0 by default. You can also explicitly assign values to the constants.
enum OrderType {
ORDER_TYPE_BUY, // Value is 0
ORDER_TYPE_SELL, // Value is 1
ORDER_TYPE_BUY_LIMIT, // Value is 2
ORDER_TYPE_SELL_LIMIT // Value is 3
};
enum OrderState {
ORDER_OPEN = 1,
ORDER_PENDING = 2,
ORDER_CLOSED = 3
};
Scope of Enum Variables
Enum variables, like other variables, have a scope that determines where they can be accessed. An enum declared outside any function has global scope. An enum declared inside a function has local scope. An enum can also be declared within a class (MQL5).
Working with Strings in MQL4
String Declaration and Initialization
Strings in MQL4 are sequences of characters terminated by a null character. They are declared using the string keyword. Strings can be initialized directly with a string literal or assigned a value later.
string myString = "Hello, MQL4!";
string emptyString;
emptyString = "This is an empty string that gets filled later.";
String Manipulation Functions (StringConcatenate, StringSubstr, etc.)
MQL4 provides a rich set of functions for manipulating strings:
StringConcatenate(): Joins multiple strings into a single string.StringSubstr(): Extracts a substring from a string.StringLen(): Returns the length of a string.StringFind(): Searches for a substring within a string.StringReplace(): Replaces occurrences of a substring with another substring.StringTrimLeft()/StringTrimRight(): Removes leading/trailing whitespace.
string str1 = "Hello";
string str2 = "World";
string combinedString = StringConcatenate(str1, ", ", str2, "!"); // combinedString = "Hello, World!"
string subString = StringSubstr(combinedString, 0, 5); // subString = "Hello"
String Comparison
Strings can be compared using the == and != operators. The comparison is case-sensitive.
string strA = "apple";
string strB = "Apple";
if (strA == "apple") { // This condition is true
Print("Strings are equal (case-sensitive).");
}
if (strA != strB) { // This condition is also true
Print("Strings are not equal.");
}
Converting Enums to Strings and Vice Versa
Converting Enum Values to String Representations
MQL4 doesn’t have built-in functions to directly convert enum values to strings. However, you can create a custom function using a switch statement or an array of strings to achieve this.
enum TradeType {
TRADE_BUY,
TRADE_SELL,
TRADE_CLOSE
};
string TradeTypeToString(TradeType type) {
switch (type) {
case TRADE_BUY:
return "Buy";
case TRADE_SELL:
return "Sell";
case TRADE_CLOSE:
return "Close";
default:
return "Unknown";
}
}
void OnStart() {
TradeType myTrade = TRADE_SELL;
string tradeString = TradeTypeToString(myTrade);
Print("Trade Type: ", tradeString); // Output: Trade Type: Sell
}
Parsing Strings to Obtain Enum Values
Similarly, converting a string to an enum value requires a custom function, usually using a series of if statements or a switch statement.
TradeType StringToTradeType(string str) {
if (str == "Buy") {
return TRADE_BUY;
} else if (str == "Sell") {
return TRADE_SELL;
} else if (str == "Close") {
return TRADE_CLOSE;
} else {
return -1; // Or some other invalid enum value or handle the error.
}
}
void OnStart() {
string tradeString = "Buy";
TradeType myTrade = StringToTradeType(tradeString);
if(myTrade == TRADE_BUY){
Print("The trade is a BUY order.");
}
}
Practical Examples of Using Enums and Strings Together
Example 1: Creating a Custom Order Type Enum and Representing it as a String
This example demonstrates how to define an enum for order types and convert it to a string for logging or display purposes.
enum CustomOrderType {
MARKET_ORDER,
PENDING_ORDER,
STOP_ORDER
};
string CustomOrderTypeToString(CustomOrderType type) {
switch (type) {
case MARKET_ORDER:
return "Market Order";
case PENDING_ORDER:
return "Pending Order";
case STOP_ORDER:
return "Stop Order";
default:
return "Unknown Order Type";
}
}
void OnStart() {
CustomOrderType orderType = PENDING_ORDER;
string orderTypeString = CustomOrderTypeToString(orderType);
Print("Order Type: ", orderTypeString);
}
Example 2: Storing Enum Values in String Format for Configuration
You might store enum values as strings in an external configuration file (e.g., for strategy parameters). This example demonstrates how to read a string from a file or input parameter and convert it back to an enum value.
input string OrderTypeString = "Buy"; // Example Input Parameter
enum OrderTypeConfig {
BUY_CONFIG,
SELL_CONFIG
};
OrderTypeConfig StringToOrderTypeConfig(string str) {
if (str == "Buy") {
return BUY_CONFIG;
} else if (str == "Sell") {
return SELL_CONFIG;
} else {
Print("Invalid OrderTypeString. Defaulting to BUY.");
return BUY_CONFIG; // Default value
}
}
void OnStart() {
OrderTypeConfig configValue = StringToOrderTypeConfig(OrderTypeString);
if (configValue == BUY_CONFIG) {
Print("Configuration: Buying.");
} else {
Print("Configuration: Selling.");
}
}
Example 3: Using strings to represent enum and process external input
This example shows how to receive user input as a string, convert it to an enum, and perform actions accordingly.
input string UserInputCommand = "START";
enum BotCommands {
START_BOT,
STOP_BOT,
PAUSE_BOT
};
BotCommands StringToBotCommands(string command){
if(command == "START"){
return START_BOT;
} else if (command == "STOP"){
return STOP_BOT;
} else if (command == "PAUSE"){
return PAUSE_BOT;
} else {
return -1;
}
}
void OnStart() {
BotCommands userCommand = StringToBotCommands(UserInputCommand);
if (userCommand == START_BOT) {
Print("Starting the bot...");
// Bot start logic here
} else if (userCommand == STOP_BOT) {
Print("Stopping the bot...");
// Bot stop logic here
} else if (userCommand == PAUSE_BOT) {
Print("Pausing the bot...");
// Bot pause logic here
} else {
Print("Invalid command. Please enter START, STOP, or PAUSE.");
}
}
Best Practices and Common Pitfalls
Enum Naming Conventions for Readability
- Use descriptive names for enum constants.
- Use uppercase letters for enum constant names (e.g.,
ORDER_TYPE_BUY). - Prefix enum constants with the enum name to avoid naming conflicts (e.g.,
OrderType.ORDER_TYPE_BUYin other languages – less relevant in MQL4 but good practice).
String Handling Considerations for Performance
- Avoid excessive string concatenation within loops, as it can be performance-intensive. Use
StringBuilder(if available – MQL5) or other efficient techniques for building strings incrementally. - Be mindful of string length, as very long strings can consume significant memory.
Error Handling When Converting Between Enums and Strings
- Always include a default or error-handling case when converting strings to enum values. This prevents unexpected behavior when an invalid string is encountered.
- Consider logging errors or using error codes to indicate conversion failures.
- Validate user input to ensure it matches the expected string values for enum conversion.
By understanding and applying these principles, you can effectively use enums and strings to create more robust, readable, and maintainable MQL4 programs. Remember that MQL5 offers more advanced features for string manipulation and object-oriented programming, so consider migrating to MQL5 for more complex trading strategies.