- Получение списков доступных символов и Обзора рынка
- Редактирование списка Обзора рынка
- Проверка символа на существование
- Проверка актуальности данных по символу
- Получение последнего тика по символу
- Расписания торговых и котировочных сессий
- Маржинальные коэффициенты по символу
- Обзор функций получения свойств символа
- Проверка состояния символа
- Тип цены для построения графиков по символу
- Базовая, котировочная и маржинальная валюты инструмента
- Точность представления и шаг изменения цен
- Разрешенные объемы торговых операций
- Разрешения на торговлю
- Торговые условия и режимы исполнения приказов по символу
- Маржинальные требования
- Правила истечения сроков отложенных ордеров
- Спреды и отступы приказов от текущей цены
- Получение величины свопов
- Текущая рыночная информация (тик)
- Описательные свойства символов
- Глубина стакана цен
- Свойства пользовательских символов
- Специфические свойства (биржа, срочный рынок, облигации)
Обзор функций получения свойств символа
Полная спецификация каждого символа может быть получена путем запроса его свойств: для этой цели в MQL5 API предусмотрено 3 функции — SymbolInfoInteger, SymbolInfoDouble, SymbolInfoString, — каждая из которых ответственна за свойства конкретного типа. Сами свойства описаны как элементы трех перечислений — ENUM_SYMBOL_INFO_INTEGER, ENUM_SYMBOL_INFO_DOUBLE и ENUM_SYMBOL_INFO_STRING, соответственно. Аналогичный технический прием использован в уже знакомых нам API графиков и объектов.
В любую из функций передаются имя символа и идентификатор запрашиваемого свойства.
Каждая из функций представлена в 2-х формах — сокращенной и полной. Сокращенная непосредственно возвращает запрошенное свойство, а полная записывает его в выходной параметр, переданный по ссылке. Например, для свойств, совместимых с целым типом, функции имеют такие прототипы:
long SymbolInfoInteger(const string symbol, ENUM_SYMBOL_INFO_INTEGER property)
bool SymbolInfoInteger(const string symbol, ENUM_SYMBOL_INFO_INTEGER property, long &value)
Вторая форма возвращает логический признак успеха (true) или ошибки (false). К наиболее возможным причинам, по которым функция может вернуть false, относятся неправильное имя символа (MARKET_UNKNOWN_SYMBOL, 4301) или неверный идентификатор запрошенного свойства (MARKET_WRONG_PROPERTY, 4303) — их можно уточнить с помощью _LastError.
Как и ранее, свойства в перечислении ENUM_SYMBOL_INFO_INTEGER относятся к различным типам, совместимым с целым числом: bool, int, long, color, datetime и специальные перечисления (все они будут рассмотрены в отдельных разделах).
Для свойств с типом вещественных чисел определены следующие 2 формы функции SymbolInfoDouble.
double SymbolInfoDouble(const string symbol, ENUM_SYMBOL_INFO_DOUBLE property)
bool SymbolInfoDouble(const string symbol, ENUM_SYMBOL_INFO_DOUBLE property, double &value)
Наконец, для строковых свойств аналогичные функции выглядят так:
string SymbolInfoString(const string symbol, ENUM_SYMBOL_INFO_STRING property)
bool SymbolInfoString(const string symbol, ENUM_SYMBOL_INFO_STRING property, string &value)
Свойства различных типов, наиболее востребованные при будущей разработке экспертов, логически сгруппированы в описаниях следующих разделов этой главы.
На основе вышеописанных функций создадим универсальный класс SymbolMonitor (файл SymbolMonitor.mqh) для получения любых свойств символа. Его основу будет составлять набор перегруженных методов get для 3 перечислений.
class SymbolMonitor
|
Еще три похожих метода дают возможность избавиться от типа перечисления в первом параметре и выбирать компилятором нужную перегрузку за счет второго фиктивного параметра (его тип здесь всегда совпадает с типом результата). Мы воспользуемся этим в будущих классах-шаблонах.
long get(const int property, const long) const
|
Таким образом, создав объект с нужным именем символа, можно единообразно запрашивать его свойства любых типов. Для запроса и вывода в журнал всех свойств одного типа мы могли бы реализовать примерно такой метод.
// проект (черновик)
|
Однако из-за того, что в свойствах типа long на самом деле "скрываются" значения других типов, которые желательно отображать специфическим образом (например, для перечислений — вызывать EnumToString, для даты и времени — TimeToString и т.д.), имеет смысл определить еще одну тройку перегруженных методов, которые возвращали бы строковое представление свойства. Назовем их stringify. Тогда в приведенном наброске list2log можно будет использовать stringify вместо приведения значений к (string), а сам метод избавится от одного шаблонного параметра.
template<typename E>
|
Для вещественного и строкового типов реализация stringify выглядит довольно прямолинейно.
string stringify(const ENUM_SYMBOL_INFO_DOUBLE property, const string format = NULL) const
|
А вот для ENUM_SYMBOL_INFO_INTEGER все немного сложнее. Конечно, когда свойство имеет тип long или int его достаточно привести к (string). Все остальные случаи требуется индивидуально анализировать и преобразовывать внутри оператора switch.
string stringify(const ENUM_SYMBOL_INFO_INTEGER property) const
|
Например, если свойство имеет логический тип, его удобно представить строкой "true" или "false" (таким образом, оно будет визуально отличаться от простых чисел 1 и 0). Немного забегая вперед, для примера скажем, что среди свойств имеется SYMBOL_EXIST, эквивалентное функции SymbolExist, то есть возвращающее логический признак того, существует ли указанный символ. Для его обработки и прочих логических свойств имеет смысл реализовать вспомогательный метод boolean.
static string boolean(const long v)
|
Для свойств, являющихся перечислениями, наиболее подходящим решением будет шаблонный метод, использующий функцию EnumToString.
template<typename E>
|
Например, одно из свойств SYMBOL_SWAP_ROLLOVER3DAYS определяет, в какой день недели на открытые позиции по символу начисляется тройной своп, и это свойство имеет тип ENUM_DAY_OF_WEEK. Значит, для его обработки мы можем написать внутри switch:
case SYMBOL_SWAP_ROLLOVER3DAYS:
|
Особый случай представляют свойства, значения которых являются комбинациями битовых флагов. В частности, по каждому символу брокером устанавливаются разрешения на приказы конкретных типов, такие как рыночные, лимитные, стоплосс, тейкпрофит и другие (мы рассмотрим эти разрешения отдельно). Каждый тип приказов обозначается константой с взведенным одним битом, так что их суперпозиция (объединение битовым оператором ИЛИ '|') хранится в свойстве SYMBOL_ORDER_MODE, и в отсутствие ограничений взведены все биты одновременно. Для подобных свойств мы определим в нашем заголовочном файле собственные перечисления, например:
enum SYMBOL_ORDER
|
Здесь для каждой встроенной константы, такой как SYMBOL_ORDER_MARKET, описан соответствующий элемент, идентификатор которого совпадает с константой, но предваряется символом подчеркивания, чтобы избежать конфликта имен.
Для представления комбинаций флагов из таких перечислений в виде строки мы реализуем еще один шаблонный метод maskstr.
template<typename E>
|
Его суть похожа на enumstr, но функция EnumToString вызывается для каждого взведенного бита в значении свойства, после чего полученные строки "склеиваются".
Теперь обработка SYMBOL_ORDER_MODE в операторе switch возможна по похожей схеме:
case SYMBOL_ORDER_MODE:
|
Приведем полный код метода stringify для ENUM_SYMBOL_INFO_INTEGER. Со всеми свойствами и перечислениями мы поэтапно познакомимся в следующих разделах.
string stringify(const ENUM_SYMBOL_INFO_INTEGER property) const
|
Для проверки работы класса SymbolMonitor создан простой скрипт SymbolMonitor.mq5. Он выводит в журнал все свойства рабочего символа графика.
#include <MQL5Book/SymbolMonitor.mqh>
|
Например, если запустить скрипт на графике EURUSD можем получить следующие записи (приведено с сокращениями).
ENUM_SYMBOL_INFO_INTEGER Count=36
|
В частности, видно, что цены символа транслируются с 5 знаками (SYMBOL_DIGITS), символ существует (SYMBOL_EXIST), размер контракта составляет 100000.0 (SYMBOL_TRADE_CONTRACT_SIZE), и т.д. Вся информация соответствует спецификации.