Chapter 1
MQL5 Language Foundations
Unlock the power of algorithmic trading by mastering MQL5 at its core. This chapter takes you beneath the surface of MetaTrader 5's programming environment, revealing how robust language constructs, advanced paradigms, and professional tools form the bedrock of every successful trading algorithm. Whether you're migrating from another language or starting anew, this foundation prepares you for high-performance, reliable, and scalable trading system development.
1.1 MQL5 Syntax and Language Constructs
MQL5, the native programming language of the MetaTrader 5 platform, presents a robust set of syntax and language constructs designed for algorithmic trading, technical analysis, and custom indicator development. Rooted in the paradigms of C++, MQL5 introduces specialized features tailored to financial market automation, emphasizing efficiency, precision, and real-time responsiveness.
MQL5 source code files typically end with the extension .mq5 and adhere to a structured format centered on functions, preprocessor directives, and event-handling routines. The language supports compilation into executables called experts, indicators, or scripts, each with a lifecycle managed by predefined event functions.
Every MQL5 program is built around a number of function definitions, with OnInit(), OnDeinit(), and OnTick() being fundamental for expert advisors. Comments follow the C++ style, supporting single-line comments with // and multi-line comments with /* ... */.
Statements are terminated with semicolons, and blocks are enclosed by braces {}. MQL5 enforces case sensitivity and follows conventional rules for identifiers, which may include letters, digits, and underscores but must not start with a digit.
MQL5 provides an extensive variety of variable types, encompassing scalar, compound, and user-defined types to support diverse data manipulation needs in a trading environment.
- bool - Boolean logical type storing true or false.
- char - Represents a single byte character.
- Integer types: short, ushort, int, uint, long, ulong. They differ in size and sign, with int and long being the most commonly used integer types.
- Floating-point: float, double, and long double, with double being the default for real number computations due to its balance between precision and speed.
- string - Unicode string type supporting dynamic length text, critical for handling symbol names, messages, and file operations.
- Arrays - One-dimensional or multidimensional, arrays in MQL5 can be of fixed or dynamic size, with support for both static and dynamic memory allocation.
- Specialized and User-defined Types:
- datetime - A 64-bit integer representing time in seconds elapsed since 1970-01-01 00:00:00 UTC, used extensively for managing bar times and event scheduling.
- ENUM_* - Enumeration types specific to MQL5, often representing market-related constants such as order types, chart properties, or technical indicator modes.
- struct and class - Allow encapsulation and definition of complex data structures and object-oriented programming. Classes support inheritance, polymorphism, and access specifiers.
Variable declaration follows the familiar syntax:
int volume = 1000;
double price = 1.23456;
string symbol = "EURUSD";
datetime tradeTime = D'2024.06.01 14:30';
bool isTradeOpen = false;
MQL5 supports a broad range of operators, many directly inherited from C++, alongside some specialized extensions to cater for trading-specific logic and data types.
- Arithmetic Operators: +, -, *, /, % (modulus). Floating-point arithmetic conforms to IEEE 754 standard.
- Increment and Decrement: Pre- and post-increment (++) and decrement (-) operators are supported.
- Relational Operators: ==, !=, <, >, <=, >= allow comparison of numeric and character variables.
- Logical Operators: && (AND), || (OR), and ! (NOT) for boolean logic.
- Bitwise Operators: &, |, , «, » provide bit-level manipulation, significant for performance-critical algorithmic optimizations.
- Assignment Operators: Basic assignment =, plus compound assignments such as +=, -=, *=, /=, and others for succinct code.
- Ternary Operator: cond ? val1 : val2 allows inline conditional evaluation.
The expression evaluation in MQL5 is left-to-right with precedence and associativity rules consistent with the C++ standard, ensuring predictability and allowing complex expressions with nested parentheses for clarity.
Understanding the scope and lifetime of variables is essential in MQL5 due to the asynchronous nature of market data and event-driven code execution.
- Global Variables: Declared outside functions, with a lifetime spanning the entire runtime of the program; accessible from all functions unless shadowed.
- Local Variables: Defined within a function or block, exist only during the function's execution.
- Static Variables: Declared with the static keyword inside a function, retain their value between function calls but remain limited in scope to that function.
- External Variables: Declared with extern, allowing configuration from outside the program, often visible in the inputs dialog of an expert advisor or indicator.
- Input Variables: Marked with the input keyword, these are constants initialized by the user prior to runtime; they assist parameterizing trading algorithms without recompilation.
The design of MQL5 integrates unique constructs tuned for algorithmic trading and market analysis:
- Event-Handling Model: MQL5 programs rely on predefined event functions such as OnTick(), OnTimer(), OnTrade() among others, triggering code execution based on platform events. This model enforces a reactive style critical for real-time market responsiveness.
- Preprocessor Directives: Directives such as #define, #include, #ifdef control compilation and symbol replacement. Extensions include trading-specific macros and pragmas such as #property to define script metadata.
- Function Overloading and Templates: MQL5 supports function overloading, allowing multiple definitions of functions distinguished by parameter lists. Although template programming is limited, generic programming is partially achievable with careful design.
- Exception Handling and Debugging: Error handling relies on return codes, the GetLastError() function, and the use of Print() for runtime diagnostics.
- Pointers and References: While pointers are supported, their use is constrained and discouraged to avoid unsafe memory access. References are primarily used to pass function parameters by reference, improving performance.
- Classes and Object...