Пт. Июн 25th, 2021

Кроссплатформенный торговый советник: Мани-менеджмент

Enrico Lambino

Оглавление

  1. Введение
  2. Цели
  3. Базовый класс
  4. Классы и типы мани-менеджмента
  5. Контейнер объектов мани-менеджмента
  6. Пример
  7. Заключение

Введение

Мани-менеджмент (управление капиталом) — распространенная функция в торговых советниках. Она позволяет эксперту динамически определять размер лота для следующей сделки, в которую он войдет. В этой статье представлены несколько классов мани-менеджмента, которые позволят нам автоматизировать весь процесс расчета торгового объема в советнике.

  • Понимать и применять наиболее распространенные методы управления капиталом, используемые в трейдинге
  • Разрешить эксперту выбирать из списка доступных методов мани-менеджмента
  • Обеспечить совместимость с 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, его определение продемонстрировано ниже:

Поскольку этот объект разработан, чтобы содержать многочисленные объекты мани-менеджмента, требуются как минимум два метода, чтобы сделать объект доступным к использованию в разрабатываемом советнике:

  1. Выбор, или способность динамически переключаться между методами мани-менеджмента
  2. Использование выбранного объекта мани-менеджмента и получение рассчитанного для него объема сделки

Выбор можно реализовать двумя путями: через присвоение индекса объекту мани-менеджмента в массиве объектов (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 / LT / PПрибыльБаланс
1.2017.01.02 00:00продажа1.1.001.051000.000000.00000
22017.01.03 03:00Закрытие1.1.001.046790.000000.00000419.9610419.96
32017.01.03 03:00Покупка20.051.046790.000000.00000
42017.01.03 10:00Закрытие20.051.045970.000000.00000-4.1010415.86
52017.01.03 10:00продажа31.001.045970.000000.00000
62017.01.03 20:00Закрытие31.001.042850.000000.00000312.0010727.86
72017.01.03 20:00Покупка40.051.042850.000000.00000
82017.01.03 22:00Закрытие40.051.041020.000000.00000-9.1510718.71
92017.01.03 22:00продажа51.001.041020.000000.00000
102017.01.04 02:00Закрытие51.001.041900.000000.00000-89.0410629.67
112017.01.04 02:00Покупка60.051.041900.000000.00000
122017.01.04 03:00Закрытие60.051.039420.000000.00000-12.4010617.27
132017.01.04 03:00продажа71.001.039420.000000.00000
142017.01.04 06:00Закрытие71.001.040690.000000.00000-127.0010490.27
152017.01.04 06:00Покупка80.051.040690.000000.00000
162017.01.05 11:00Закрытие80.051.051490.000000.0000054.0510544.32
172017.01.05 11:00продажа91.001.051490.000000.00000
182017.01.05 16:00Закрытие91.001.053190.000000.00000-170.0010374.32
192017.01.05 16:00Покупка100.051.053190.000000.00000
202017.01.06 05:00Закрытие100.051.058690.000000.0000027.5210401.84

В MetaTrader 5 мы можем видеть следующие результаты (режим хеджирования, первые 10 сделок):

Поскольку менеджер ордеров уже позаботился о разнице между двумя платформами (и языками), метод и результат расчета размера лота будет одинаковым.

Заключение

В статье показано, как в кроссплатформенном торговом советнике можно применять мани-менеджмент. Представлены 5 различных типов управления капиталом. Также представлен пользовательский объект-контейнер для указателей на объекты, который используется для динамического выбора метода мани-менеджмента.

https://www.mql5.com/ru/articles/3280

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *