Оглавление
Кроссплатформенный торговый советник: Мани-менеджмент
Оглавление
- Введение
- Цели
- Базовый класс
- Классы и типы мани-менеджмента
- Контейнер объектов мани-менеджмента
- Пример
- Заключение
Введение
Мани-менеджмент (управление капиталом) — распространенная функция в торговых советниках. Она позволяет эксперту динамически определять размер лота для следующей сделки, в которую он войдет. В этой статье представлены несколько классов мани-менеджмента, которые позволят нам автоматизировать весь процесс расчета торгового объема в советнике.
- Понимать и применять наиболее распространенные методы управления капиталом, используемые в трейдинге
- Разрешить эксперту выбирать из списка доступных методов мани-менеджмента
- Обеспечить совместимость с MQL4 и MQL5
Базовый класс
Базовый родительский класс для всех классов мани-менеджмента, описанных в этой статье — СMoney, производный от CMoneyBase. Класс CMoneyBase определен в нижеследующем фрагменте кода:
Большинство методов класса отвечают либо за получение, либо за установку различных членов класса, и поэтому не требуют подробных пояснений. В практическом применении реальное значение имеют три метода: UpdateLotSize, OnLotSizeUpdated и Volume.
В методе UpdateLotSize происходит фактический расчет торгового объема. Это тоже основной метод, расширенный из базового класса, и следовательно, большая часть различий между классами мани-менеджмента находится именно в нем. Для базового класса CMoneyBase метод можно считать виртуальным, потому что единственное его назначение здесь — возвращать значение true:
Иногда после расчета торгового объема нужно обновить определенные значения, которые будут использоваться для последующих вычислений. В таких случаях используется метод OnLotSizeUpdated. Он автоматически вызывается внутри метода UpdateLotSize:
Чтобы получить текущее значение торгового объема, уже рассчитанное посредством мани-менеджмента, советнику не надо вызывать ни UpdateLotSize, ни OnLotSizeUpdated. Вместо этого вызывается метод Volume класса. Этот метод автоматически вызовет внутри себя остальные два.
Методы мани-менеджмента
Фиксированный лот
Это самый общий и наиболее известный большинству трейдеров метод определения объема лота. Здесь все сделки имеют постоянный торговый объем, вне зависимости от того, растет или снижается с течением времени баланс или эквити.
В этом типе мани-менеджмента нам нужен только фиксированный объем. Таким образом, его основное отличие от CMoney/CMoneyBase — в конструкторе, где мы определяем фиксированный размер лота:
Если нам нужно динамически изменить результат работы этого метода управления капиталом, мы просто изменяем его член класса m_volume вызовом метода Volume.
Фиксированно-фракционный метод
Фиксированно-фракционный метод (или метод фиксированного риска) подразумевает выделение определенного процента от баланса или эквити в качестве риска на каждую сделку. Этот метод реализован в стандартной библиотеке: CmoneyFixedRisk. Если сделка закрывается в убытке, этот убыток не превышает установленного процента от баланса счета ко времени входа в сделку. Убыток здесь определяется как максимальная потеря, которую может понести трейдер в конкретной сделке — когда условия сделки доходят до стоп-лосса. Применение метода требует, чтобы стоп-лосс не был равен нулю.
Вычисление процента риска выражается в следующей формуле:
Volume = (balance * account_percentage / ticks) / tick_value
- balance — баланс или эквити счета
- account_percentage — процент максимального риска (диапазон: 0.0-1.0)
- ticks — значение стоп-лосса, выраженное в тиках
- tick_value — стоимость тика в валюте депозита (на 1 полный лот)
Тик определяется как самое маленькое возможное движение цены для данного инструмента или валютной пары. К примеру, EURUSD у брокера, использующего пятизначные котировки, будет иметь стоимость тика 0,00001. Это наименьшее возможное движение по этой валютной паре. Если значение стоп-лосса выражено в пунктах или пипсах, результатом будет разница между входной ценой сделки и стоп-лоссом в пунктах или пипсах.
По той же валютной паре размер тика для брокера с четырехзначной котировкой будет отличаться от пятизначной. Причина в том, что при 4 знаках 1 тик эквивалентен 1 пункту (или пипсу), а при использовании пятизначной котировки пипс равен 10 пунктам.
В качестве примера мани-менеджмента с фиксированным риском предположим, что мы работаем с брокером, использующим пятизначные котировки, у нас на балансе есть $ 1 000, а заданный предел риска составляет 5% на одну сделку. Предположим, что стоимость тика 0,1, а стоп-лосс — 200 пунктов (20 пипсов):
Volume = (1000 * 0.05 / 200) / 0.1 = 2.5 лота
Вычисленный объем лота увеличивается в зависимости от процента риска и доступного баланса, а уменьшается на основании размера стоп-лосса и тикового значения. Баланс счета, риск и стоимость тика, как правило, постоянны, а вот стоп-лосс нередко бывает переменным и вычисляется динамически. Поэтому фиксированный риск не подходит для стратегий, где нет верхнего лимита на разницу между входной ценой и стоп-лоссом. Рассчитанный размер лота может оказаться слишком маленьким, и брокер может его отклонить. С другой стороны, слишком маленький стоп-лосс приведет к очень большому размеру лота, и это тоже может повлечь за собой проблемы: некоторые брокеры устанавливают настройку, ограничивающую максимальный лот. Эта проблема практически решена в MetaTrader 5, где ордера разбиваются на несколько сделок, если объем лота слишком велик. Однако в MetaTrader 4 такой функции нет — объем сделки должен быть подготовлен заранее (при необходимости разбит на несколько мелких сделок), чтобы она смогла состояться, даже если ее размер превышает максимально допустимый уровень.
Формула, которая используется в расчетах, находится внутри метода UpdateLotSize:
Сначала мы получаем значение стоп-лосса. Затем используем текущую формулу для обновления члена класса m_volume, который впоследствии будет использован в качестве финального результата.
Фиксированно-пропорциональный метод
Фиксированно-пропорциональный метод управления капиталом — вычисление объема лота в пропорции к текущему балансу счета. Его можно рассматривать как частный случай фиксированного лота, за исключением того, что здесь размер лота настраивается автоматически, а не вручную самим трейдером. Если счет растет, размер лота тоже будет увеличиваться после прохождения определенного порога. Если баланс уменьшается, соответственно будет уменьшаться и размер лота.
В отличие от мани-менеджмента с фиксированным риском, фиксированно-пропорциональный метод не требует ненулевого стоп-лосса. Это делает его идеальным для использования в сделках, для которых не требуется стоп-лосс и выход из которых осуществляется по-другому (закрытие по прибыли/убытку в валюте депозита и т.д.).
Объем сделки для этого метода мани-менеджмента рассчитывается по формуле:
Volume = base_volume + (balance / balance_increase) * volume_increment
- base_volume — базовый объем лота, который будет в любом случае добавлен к общему объему, вне зависимости от характеристик счета
- balance — текущий баланс на счете
- balance_increase — порог увеличения баланса на счете, после которого будет происходить шаг приращения размера лота
- volume_increment — шаговый объем, который будет добавлен к лоту после достижения порога (или, соответственно, вычтен из него).
К примеру, возьмем за базовый объем нулевой лот. Он будет увеличиваться на 0,1 на каждые 1000 долларов на счёте. В данный момент на нашем счете $2,500. Общий объем будет рассчитан следующим образом:
Volume = 0 + (2500 / 1000) * 0.1 = 0.25 лота
У этого метода есть множество вариаций. Одна из них — метод, где размер лота обновляется только на определенных уровнях, пошагово. В вышеприведенном примере рассчитанный объем лота равен 0,25. В ином случае он может определенное время оставаться на уровне 0,2 лота, а потом сразу вырасти до 0,3 (как только баланс достигнет $3,000).
Для этого случая метод UpdateLotSize будет реализован так:
Фиксированный риск на один пункт
Фиксированный риск на один пункт работает так, что каждый пункт стоп-лосса стоит определенную сумму в валюте депозита. Алгоритм вычисления размера лота основывается на том, какая стоимость тика нужна трейдеру. К примеру, если зафиксировать на долларовом счёте риск на пункт 2.0, каждый пункт стоп-лосса будет стоить $2. Если стоп-лосс на сделку составляет 200 пунктов, максимальный риск для такой сделки составит $400 (то есть, $400 будет потеряно, если рынок достигнет уровня стоп-лосса сделки).
Для обычного трейдера использование этого типа мани-менеджмента — очень просто для понимания, потому что риск выражается в денежном значении, в валюте депозита. Трейдеру просто нужно установить требуемую стоимость тика, и торговый объем будет рассчитан автоматически. Стоимость тика, или изменение в прибыли/убытке на минимальное движение цены, будет оставаться одинаковым, но общий риск будет зависеть от размера стоп-лосса сделки.
С использованием формулы для этого типа мани-менеджмента метод UpdateLotSize будет реализован так:
Фиксированный риск (Фиксированная маржа)
Фиксированный риск по марже — аналог класса CMoneyFixedMargin из Стандартной библиотеки MQL5. Фактически, это частный случай описанного выше способа мани-менеджмента — фиксированного риска на пункт. Однако, в отличие от фиксированного риска на пункт, этот метод учитывает при расчете объема сделки всю величину стоп-лосса, поэтому вне зависимости от размера стоп-лосса, риск остается таким же. В предыдущем примере у нас был установлен стоп-лосс в 200 пунктов, и $400 — максимальный риск. Если уменьшить стоп-лосс до 100 пунктов, максимальный риск на сделку при использовании фискированного риска на пункт тоже уменьшится вдвое, а при использовании просто фиксированного риска (фиксированной маржи) максимальный риск останется все тем же — $400.
Используя эту формулу, мы можем реализовать метод UpdateLotSize следующим образом:
Формула, которая здесь используется, практически аналогична фиксированному риску на пункт, за исключением того, что нам надо получить тиковое значение стоп-лосса, и потом определять результат по предыдущей формуле с этим значением.
Контейнер объектов мани-менеджмента
Как и классы сигналов, рассмотренные в предыдущей статье, наши объекты мани-менеджмента тоже будут иметь контейнеры. Это позволит советнику динамически выбирать из списка доступных объектов мани-менеджмента, загруженных в платформу. В идеале этот контейнер будет выступать как посредник между классами мани-менеджмента и остальным кодом советника. Базовый класс для этого объекта — CMoneysBase, его определение продемонстрировано ниже:
Поскольку этот объект разработан, чтобы содержать многочисленные объекты мани-менеджмента, требуются как минимум два метода, чтобы сделать объект доступным к использованию в разрабатываемом советнике:
- Выбор, или способность динамически переключаться между методами мани-менеджмента
- Использование выбранного объекта мани-менеджмента и получение рассчитанного для него объема сделки
Выбор можно реализовать двумя путями: через присвоение индекса объекту мани-менеджмента в массиве объектов (CMoneysBase расширяет CArrayObj), или через нахождение выбранного объекта по имени (метод Name, принадлежащий классу CMoneyBase/CMoney). Ниже показана перегрузка метода Selected, который принимает целочисленный аргумент (или индекс):
А вот как выглядит перегруженный метод Selected, который принимает строковый аргумент (имя объекта мани-менеджмента). Обратите внимние, что он принимает не пустое имя объекта мани-менеджмента, которое присваивается методом Name.
Третья перегрузка метода вообще не содержит аргументов. Она просто возвращает индекс выбранного объекта мани-менеджмента, когда нужно выяснить, какой метод выбран на данный момент.
Текущий объем рассчитывается через этот объект его методом Volume. Метод сначала получает указатель на выбранный объект мани-менеджмента, а потом вызывает его собственный метод Volume. Код метода Volume для класса CMoneysBase продемонстрирован ниже:
Здесь метод обращается к объекту через массив объектов и сохраняет его в указателе. Чтобы избежать ошибок, нужно убедиться, что текущий элемент, на который ссылается индекс, действительно существует внутри массива объектов.
Пример
В качестве примера мы будем использовать последний пример из предыдущей статьи. Модифицируем его: включим в него классы мани-менеджмента, описанные в этой статье, поместим их в отдельный контейнер, и потом добавим в менеджер ордеров. Большинство дополнений будут иметь дело только с функцией советника OnInit, которая продемонстрирована ниже:
Сюда включены строки кода, отвечающие за использование фиксированно-фракционного типа мани-менеджмента, фиксированного риска и фиксированного риска на пункт. Однако на данный момент наш советник входит только в сделки с нулевыми стоп-лоссами, а все эти методы требуют ненулевого. Поэтому воздержимся от их применения. Будем использовать только методы, основанные на фиксированном лоте и фиксированно-пропорциональном управлении капиталом. Если эти объекты возвращают невалидный стоп-лосс (меньше нуля), менеджер ордеров будет использовать объем лота по умолчанию (0.1, он доступен в члене m_lotsize класса CorderManager/COrderManagerBase).
У COrderManager есть свой собственный член класса, который является указателем на контейнер мани-менеджмента (CMoney). Таким образом, использование COrderManager тоже приведет к тому, что заголовочные файлы мани-менеджмента будут включены в исходный код. Если в советнике не используется COrderManager, тогда директива #include для классов мани-менеджмента должна быть указана в исходном коде.
Для функции OnTick мы изменяем советник следующим образом: для длинных позиций советник будет использовать фиксированный размер лота, а для коротких — рассчитывать размер лота с использованием фиксированного соотношения. Этого можно добиться, изменив выбранный тип мани-менеджмента методом Selected (класс CMoneys) перед тем, как менеджер ордеров вызовет метод TradeOpen:
Поскольку мани-менеджмент, по сути своей, — просто чистые расчеты, мы ожидаем, что вычисленный размер лота будет одинаковым в обеих версиях терминала. Ниже показан результат тестов советника в MetaTrader 4 (первые 10 сделок):
# | Время | Тип | Ордер | Объем | Цена | S / L | T / P | Прибыль | Баланс |
1. | 2017.01.02 00:00 | продажа | 1. | 1.00 | 1.05100 | 0.00000 | 0.00000 | ||
2 | 2017.01.03 03:00 | Закрытие | 1. | 1.00 | 1.04679 | 0.00000 | 0.00000 | 419.96 | 10419.96 |
3 | 2017.01.03 03:00 | Покупка | 2 | 0.05 | 1.04679 | 0.00000 | 0.00000 | ||
4 | 2017.01.03 10:00 | Закрытие | 2 | 0.05 | 1.04597 | 0.00000 | 0.00000 | -4.10 | 10415.86 |
5 | 2017.01.03 10:00 | продажа | 3 | 1.00 | 1.04597 | 0.00000 | 0.00000 | ||
6 | 2017.01.03 20:00 | Закрытие | 3 | 1.00 | 1.04285 | 0.00000 | 0.00000 | 312.00 | 10727.86 |
7 | 2017.01.03 20:00 | Покупка | 4 | 0.05 | 1.04285 | 0.00000 | 0.00000 | ||
8 | 2017.01.03 22:00 | Закрытие | 4 | 0.05 | 1.04102 | 0.00000 | 0.00000 | -9.15 | 10718.71 |
9 | 2017.01.03 22:00 | продажа | 5 | 1.00 | 1.04102 | 0.00000 | 0.00000 | ||
10 | 2017.01.04 02:00 | Закрытие | 5 | 1.00 | 1.04190 | 0.00000 | 0.00000 | -89.04 | 10629.67 |
11 | 2017.01.04 02:00 | Покупка | 6 | 0.05 | 1.04190 | 0.00000 | 0.00000 | ||
12 | 2017.01.04 03:00 | Закрытие | 6 | 0.05 | 1.03942 | 0.00000 | 0.00000 | -12.40 | 10617.27 |
13 | 2017.01.04 03:00 | продажа | 7 | 1.00 | 1.03942 | 0.00000 | 0.00000 | ||
14 | 2017.01.04 06:00 | Закрытие | 7 | 1.00 | 1.04069 | 0.00000 | 0.00000 | -127.00 | 10490.27 |
15 | 2017.01.04 06:00 | Покупка | 8 | 0.05 | 1.04069 | 0.00000 | 0.00000 | ||
16 | 2017.01.05 11:00 | Закрытие | 8 | 0.05 | 1.05149 | 0.00000 | 0.00000 | 54.05 | 10544.32 |
17 | 2017.01.05 11:00 | продажа | 9 | 1.00 | 1.05149 | 0.00000 | 0.00000 | ||
18 | 2017.01.05 16:00 | Закрытие | 9 | 1.00 | 1.05319 | 0.00000 | 0.00000 | -170.00 | 10374.32 |
19 | 2017.01.05 16:00 | Покупка | 10 | 0.05 | 1.05319 | 0.00000 | 0.00000 | ||
20 | 2017.01.06 05:00 | Закрытие | 10 | 0.05 | 1.05869 | 0.00000 | 0.00000 | 27.52 | 10401.84 |
В MetaTrader 5 мы можем видеть следующие результаты (режим хеджирования, первые 10 сделок):
Поскольку менеджер ордеров уже позаботился о разнице между двумя платформами (и языками), метод и результат расчета размера лота будет одинаковым.
Заключение
В статье показано, как в кроссплатформенном торговом советнике можно применять мани-менеджмент. Представлены 5 различных типов управления капиталом. Также представлен пользовательский объект-контейнер для указателей на объекты, который используется для динамического выбора метода мани-менеджмента.
https://www.mql5.com/ru/articles/3280