- Главное событие экспертов: OnTick
- Основные принципы и понятия: ордер, сделка, позиция
- Типы торговых операций
- Типы ордеров
- Режимы исполнения ордеров по цене и объемам
- Сроки действия отложенных ордеров
- Расчет залога для будущего ордера: OrderCalcMargin
- Оценка прибыли торговой операции: OrderCalcProfit
- Структура торгового запроса MqlTradeRequest
- Структура проверки запроса MqlTradeCheckResult
- Проверка корректности запроса: OrderCheck
- Результат отправки запроса: структура MqlTradeResult
- Отправка торгового запроса: OrderSend и OrderSendAsync
- Совершение покупки или продажи
- Модификация уровней Stop Loss и/или Take Profit позиции
- Трейлинг стоп
- Полное и частичное закрытие позиции
- Полное и частичное закрытие встречных позиций (хедж)
- Установка отложенного ордера
- Модификация отложенного ордера
- Удаление отложенного ордера
- Получение списка действующих ордеров
- Свойства ордеров (действующих и в истории)
- Функции для чтения свойств действующих ордеров
- Отбор ордеров по свойствам
- Получение списка позиций
- Свойства позиций
- Функции для чтения свойств позиций
- Свойства сделок
- Выборка ордеров и сделок из истории
- Функции для чтения свойств ордеров из истории
- Функции для чтения свойств сделок из истории
- Типы торговых транзакций
- Событие OnTradeTransaction
- Синхронные и асинхронные запросы
- Событие OnTrade
- Контроль за изменениями торгового окружения
- Особенности создания мультисимвольных экспертов
- Ограничения и преимущества экспертов
- Создание заготовки эксперта в Мастере MQL
Функции для чтения свойств позиций
Получить свойства позиции MQL-программа может с помощью нескольких PositionGet-функций, зависящих от типа свойств. Во всех функциях конкретное запрашиваемое свойство определяется в первом параметре, принимающем идентификатор одного из ENUM_POSITION_PROPERTY-перечислений, рассмотренных в предыдущем разделе.
Для каждого типа свойств имеется краткая и полная форма функции: первая возвращает значение свойства напрямую, вторая — записывает его во второй параметр, передаваемый по ссылке.
Целочисленные свойства и свойства совместимых с ними типов (datetime, перечисления) можно получить функцией PositionGetInteger.
long PositionGetInteger(ENUM_POSITION_PROPERTY_INTEGER property)
bool PositionGetInteger(ENUM_POSITION_PROPERTY_INTEGER property, long &value)
В случае неудачного выполнения функция возвращает 0 или false.
Для получения вещественных свойств предназначена функция PositionGetDouble.
double PositionGetDouble(ENUM_POSITION_PROPERTY_DOUBLE property)
bool PositionGetDouble(ENUM_POSITION_PROPERTY_DOUBLE property, double &value)
Наконец, строковые свойства возвращает функция PositionGetString.
string PositionGetString(ENUM_POSITION_PROPERTY_STRING property)
bool PositionGetString(ENUM_POSITION_PROPERTY_STRING property, string &value)
В случае неудачного выполнения первая форма функции возвращает пустую строку.
Для чтения свойств позиций у нас уже готов абстрактный интерфейс MonitorInterface (TradeBaseMonitor.mqh) — мы его использовали для написания монитора ордеров. Теперь будет легко реализовать аналог и для позиций. Результат прилагается в файле PositionMonitor.mqh.
Класс PositionMonitorInterface наследуется от MonitorInterface с назначением шаблонным типам I, D, S рассмотренных ENUM_POSITION_PROPERTY-перечислений и переопределяет пару методов stringify с учетом специфики свойств позиций.
class PositionMonitorInterface:
|
Конкретный класс монитора, полностью готовый к просмотру позиций, является следующим в цепочке наследования и основан на PositionGet-функциях. Выделение позиции по тикету производится в конструкторе.
class PositionMonitor: public PositionMonitorInterface
|
Простой скрипт позволит вывести в журнал все характеристики первой позиции (если хотя бы одна имеется).
void OnStart()
|
В журнале мы должны получить что-то вроде этого.
MonitorInterface<ENUM_POSITION_PROPERTY_INTEGER, »
|
Если открытых позиций в данный момент нет, увидим сообщение об ошибке.
Error: PositionSelectByTicket(0) failed: TRADE_POSITION_NOT_FOUND |
Однако монитор полезен не только и не столько выводом свойств в журнал. На основе PositionMonitor создадим класс для выборки позиций по условиям, аналогичный тому, что мы сделали для ордеров (OrderFilter). Конечной целью является усовершенствование нашего эксперта-сеточника.
Благодаря ООП, создание класса нового фильтра практически не требует усилий. Ниже приведен исходный код целиком (файл PositionFilter.mqh).
class PositionFilter: public TradeFilter<PositionMonitor,
|
Теперь мы можем написать, например, такой скрипт для получения удельной прибыли по позициям с заданным магическим числом.
input ulong Magic;
|
В данном случае нам пришлось вызвать метод select дважды, потому что типы интересующих нас свойств отличаются: вещественные прибыль и лот, но строковое название инструмента. В одном из разделов в начале главы, когда мы разрабатывали класс-фильтр для символов, была описана концепция кортежей. В MQL5 мы можем реализовать её в виде шаблонов структур с полями произвольных типов. Подобные кортежи пришлись бы очень кстати для доработки иерархии классов-фильтров, так как тогда можно было бы описать метод select, заполняющий массив кортежей с полями любых типов.
Сами кортежи описаны в файле Tuples.mqh. Все структуры в нем имеют название TupleN<T1,...>, где N — число от 2 до 8, и оно соответствует количеству параметров шаблона (типов Ti). Например, Tuple2:
template<typename T1,typename T2>
|
В классе TradeFilter (TradeFilter.mqh) добавим вариант функции select с кортежами.
template<typename T,typename I,typename D,typename S>
|
Массив кортежей можно опционально сортировать по первому полю _1, но вспомогательный метод sortTuple оставлен для самостоятельного изучения.
Благодаря кортежам можно запросить у объекта-фильтра свойства трех разных типов за один вызов select.
Ниже позиции с некоторым Magic-номером выводятся упорядоченными по прибыли, для каждой дополнительно получается символ и тикет.
input ulong Magic;
|
Разумеется, типы-параметры в описании массива кортежей (в данном случае, Tuple3<double,string,ulong>) должны соответствовать типам перечислений запрашиваемых свойств (POSITION_PROFIT, POSITION_SYMBOL, POSITION_TICKET).
Теперь мы можем слегка упростить сеточный эксперт (имеется в виду не просто более короткий, но и более понятный код). Новая версия имеет название PendingOrderGrid2.mq5. Изменения коснутся всех функций, связанных с управлением позициями.
Функция GetMyPositions заполняет переданный по ссылке массив кортежей types4tickets. В каждом кортеже Tuple2 предполагается хранить тип и тикет позиции. В принципе, в данном конкретном случае мы могли бы обойтись и двумерным массивом ulong вместо кортежей, потому что оба свойства — одного базового типа. Однако мы используем кортежи для демонстрации работы с ними в вызывающем коде.
#include <MQL5Book/Tuples.mqh>
|
Обратите внимание, что последний, третий параметр метода select равен true, что предписывает отсортировать массив по первому полю, то есть типу позиций. Таким образом, покупки у нас будут в начале, а продажи — в конце. Это потребуется для встречного закрытия.
Реинкарнация метода CompactPositions выглядит следующим образом.
uint CompactPositions(const bool cleanup = false)
|
Функция CloseAllPositions почти не изменилась.
uint CloseAllPositions(const Tuple2<ulong,ulong> &types4tickets[],
|
Вы можете сравнить работу экспертов PendingOrderGrid1.mq5 и PendingOrderGrid2.mq5 в тестере.
Отчеты будут слегка отличаться, потому что при наличии нескольких позиций они встречно закрываются в других сочетаниях, из-за чего закрытие прочих, непарных позиций происходит с учетом их индивидуальных спредов.