- Getting available symbols and Market Watch lists
- Editing the Market Watch list
- Checking if a symbol exists
- Checking the symbol data relevance
- Getting the last tick of a symbol
- Schedules of trading and quoting sessions
- Symbol margin rates
- Overview of functions for getting symbol properties
- Checking symbol status
- Price type for building symbol charts
- Base, quote, and margin currencies of the instrument
- Price representation accuracy and change steps
- Permitted volumes of trading operations
- Trading permission
- Symbol trading conditions and order execution modes
- Margin requirements
- Pending order expiration rules
- Spreads and order distance from the current price
- Getting swap sizes
- Current market information (tick)
- Descriptive symbol properties
- Depth of Market
- Custom symbol properties
- Specific properties (stock exchange, derivatives, bonds)
Overview of functions for getting symbol properties
The complete specification of each symbol can be obtained by querying its properties: for this purpose, the MQL5 API provides three functions, namely SymbolInfoInteger, SymbolInfoDouble, and SymbolInfoString, each of which is responsible for the properties of a particular type. The properties are described as members of three enumerations: ENUM_SYMBOL_INFO_INTEGER, ENUM_SYMBOL_INFO_DOUBLE, and ENUM_SYMBOL_INFO_STRING, respectively. A similar technique is used in the chart and object APIs we already know.
The name of the symbol and the identifier of the requested property are passed to any of the functions.
Each of the functions is presented in two forms: abbreviated and full. The abbreviated version directly returns the requested property, while the full one writes it to the out parameter passed by reference. For example, for properties that are compatible with an integer type, the functions have prototypes like this:
long SymbolInfoInteger(const string symbol, ENUM_SYMBOL_INFO_INTEGER property)
bool SymbolInfoInteger(const string symbol, ENUM_SYMBOL_INFO_INTEGER property, long &value)
The second form returns a boolean indicator of success (true) or error (false). The most possible reasons why a function might return false include an invalid symbol name (MARKET_UNKNOWN_SYMBOL, 4301) or an invalid identifier for the requested property (MARKET_WRONG_PROPERTY, 4303). The details are provided in _LastError.
As before, the properties in the ENUM_SYMBOL_INFO_INTEGER enumeration are of various integer-compatible types: bool, int, long, color, datetime, and special enumerations (all of which will be discussed in separate sections).
For properties with a real number type, the following two forms of the SymbolInfoDouble function are defined.
double SymbolInfoDouble(const string symbol, ENUM_SYMBOL_INFO_DOUBLE property)
bool SymbolInfoDouble(const string symbol, ENUM_SYMBOL_INFO_DOUBLE property, double &value)
Finally, for string properties, similar functions look like this:
string SymbolInfoString(const string symbol, ENUM_SYMBOL_INFO_STRING property)
bool SymbolInfoString(const string symbol, ENUM_SYMBOL_INFO_STRING property, string &value)
The properties of various types which will be often used later when developing Expert Advisors are logically grouped in the descriptions of the following sections of this chapter.
Based on the above functions, we will create a universal class SymbolMonitor (fileSymbolMonitor.mqh) to get any symbol properties. It will be based on a set of overloaded get methods for three enumerations.
class SymbolMonitor
|
The other three similar methods make it possible to eliminate the enumeration type in the first parameter and select the necessary overload by the compiler due to the second dummy parameter (its type here always matches the result type). We will use this in future template classes.
long get(const int property, const long) const
|
Thus, by creating an object with the desired symbol name, you can uniformly query its properties of any type. To query and log all properties of the same type, we could implement something like this.
// project (draft)
|
However, due to the fact that in properties of the type long values of other types are actually "hidden", which should be displayed in a specific way (for example, by calling EnumToString for enumerations, imeToString for date and time, etc.), it makes sense to define another three overloaded methods that would return a string representation of the property. Let's call them stringify. Then in the above list2log draft, it is possible to use stringify instead of casting values to (string), and the method itself will eliminate one template parameter.
template<typename E>
|
For real and string types, the implementation of stringify looks pretty straightforward.
string stringify(const ENUM_SYMBOL_INFO_DOUBLE property, const string format = NULL) const
|
But for ENUM_SYMBOL_INFO_INTEGER, everything is a little more complicated. Of course, when the property is of type long or int, it is enough to cast it to (string). All other cases need to be individually analyzed and converted within the switch operator.
string stringify(const ENUM_SYMBOL_INFO_INTEGER property) const
|
For example, if a property has a boolean type, it is convenient to represent it with the string "true" or "false" (thus it will be visually different from the simple numbers 1 and 0). Looking ahead, for the sake of giving an example, let's say that among the properties there is SYMBOL_EXIST, which is equivalent to the SymbolExist function, that is, returning a boolean indication of whether the specified character exists. For its processing and other logical properties, it makes sense to implement an auxiliary method boolean.
static string boolean(const long v)
|
For properties that are enumerations, the most appropriate solution would be a template method using the EnumToString function.
template<typename E>
|
For example, the SYMBOL_SWAP_ROLLOVER3DAYS property determines on which day of the week a triple swap is charged on open positions for a symbol, and this property has the type ENUM_DAY_OF_WEEK. So, to process it, we can write the following inside switch:
case SYMBOL_SWAP_ROLLOVER3DAYS:
|
A special case is presented by properties whose values are combinations of bit flags. In particular, for each symbol, the broker sets permissions for orders of specific types, such as market, limit, stop loss, take profit, and others (we will consider these permissions separately). Each type of order is denoted by a constant with one bit enabled, so their superposition (combined by the bitwise OR operator '|') is stored in the SYMBOL_ORDER_MODE property, and in the absence of restrictions, all bits are enabled at the same time. For such properties, we will define our own enumerations in our header file, for example:
enum SYMBOL_ORDER
|
Here, for each built-in constant, such as SYMBOL_ORDER_MARKET, a corresponding element is declared, whose identifier is the same as the constant but is preceded by an underscore to avoid naming conflicts.
To represent combinations of flags from such enumerations in the form of a string, we implement another template method, maskstr.
template<typename E>
|
Its meaning is like enumstr, but the function EnumToString is called for each enabled bit in the property value, after which the resulting strings are "glued".
Now processing SYMBOL_ORDER_MODE in the statement switch is possible in a similar way:
case SYMBOL_ORDER_MODE:
|
Here is the full code of the stringify method for ENUM_SYMBOL_INFO_INTEGER. With all the properties and enumerations, we will gradually get acquainted in the following sections.
string stringify(const ENUM_SYMBOL_INFO_INTEGER property) const
|
To test the SymbolMonitor class, we have created a simple script SymbolMonitor.mq5. It logs all the properties of the working chart symbol.
#include <MQL5Book/SymbolMonitor.mqh>
|
For example, if we run the script on the EURUSD chart, we can get the following records (given in a shortened form).
ENUM_SYMBOL_INFO_INTEGER Count=36
|
In particular, you can see that the symbol prices are broadcast with 5 digits (SYMBOL_DIGITS), the symbol does exist (SYMBOL_EXIST), the contract size is 100000.0 (SYMBOL_TRADE_CONTRACT_SIZE), etc. All information corresponds to the specification.