English 中文 Español Deutsch 日本語 Português
Как снизить риски трейдера

Как снизить риски трейдера

MetaTrader 5Трейдинг | 21 декабря 2017, 12:01
19 850 17
Aleksandr Masterskikh
Aleksandr Masterskikh

Оглавление


Введение

В первую очередь, эта статья пригодится начинающим трейдерам и аналитикам, которые работают над созданием собственной торговой системы. Надеюсь, что многие вопросы будут интересны и опытным участникам рынка. Это, например, классификация видов риска, использование свечного анализа для определения зон перекупленности/перепроданности, взаимосвязь фундаментального и технического анализа, выбор периодов расчёта скользящих средних, минимизация рисков, связанных с возможным обвалом цен.

В статье рассматриваются следующие вопросы:

  • с каким процессом, с точки зрения динамики, мы имеем дело на финансовых и фондовых рынках;
  • какова вероятность получения прибыли при трейдинге;
  • как можно снизить риски трейдера ещё на стадии разработки торговой системы.

Я не претендую на всеобъемлющий анализ и полную классификацию рисков при торговле на финансовых рынках. Речь пойдёт об основных рыночных рисках, связанных с динамикой движения цен финансовых инструментов. Также поговорим и о рисках, не связанных непосредственно с рыночной динамикой, но тоже важных с точки зрения эффективности торговли. При написании статьи я использовал свой опыт, накопленный в аналитике и разработке торговых систем.

MQL5-версия советника из данной статьи доступна на странице Reduce_risks.


Что такое финансовые рынки с точки зрения динамики процесса?

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

Проявляется эта нестационарность в поведении участников рынка. Их реакции разнонаправленные, и в итоге изменение амплитуды и частоты на рынке невозможно определить законами детерминированного поведения. Поэтому такой процесс в общем виде можно считать случайным.

Однако в то же время процесс движения рыночных цен нельзя назвать абсолютно случайным. Всё же в нем есть зоны, в которых возможно корректно спрогнозировать движение. Перечислим факторы, благодаря которым появляются эти зоны.

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

Какова вероятность получения прибыли при торговле на финансовых рынках?

Это основной вопрос, ведь любой трейдер — по сути, инвестор. Вероятность получить прибыль при трейдинге на финансовых рынках напрямую связана с тем, насколько верным будет прогноз о продолжении тренда, ведь основная амплитуда движения находится именно на трендовых участках.

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

Поэтому, чтобы оценить возможность получения прибыли, мы пойдём другим путём и используем не расчётные, а фактические данные. Для этого обратимся к статистике результативности трейдинга на рынке Форекс и фондовом рынке. Ее предоставляют инвестиционные и брокерские компании.

Так, по данным, указанным в статье «Результативность частного трейдинга на Форекс в России и США», на начало 2015 года доля прибыльных счетов частных трейдеров в России составляла 28%, в США — 33%. Конечно, эти данные нельзя считать исчерпывающими, ведь в исследование было включено ограниченное количество компаний, а исследуемый период составил всего полгода. Однако порядок цифр вероятности получения прибыли понятен. Какой же вывод мы можем из этого сделать?

Традиционные методы анализа, которые использует большинство участников рынка, не позволяют эффективно прогнозировать процесс движения цен на финансовых рынках. Малоэффективны и дополнительные меры, в том числе, методы управления капиталом. Причина этого — изначальная неэффективность базового прогноза динамики рынка с помощью технического и фундаментального анализа. В итоге прибыль на финансовых рынках получают не более трети участников торгов.

Что касается фондового рынка, то статистика здесь неоднородна. Приведу относительно «умеренные» данные. По исследованиям французского агентства по финансовым рынкам, восемь из десяти индивидуальных трейдеров в итоге теряет свои средства. То есть, результативность торговли на фондовом рынке составляет 20%. Это даже хуже, чем на рынке Форекс, но порядок цифр примерно одинаков.

Итак, мы видим, что комплексный учёт рисков при трейдинге — суровая необходимость для любого инвестора.

Выделим две основные группы рисков:

  • риски, связанные с динамикой движения цен;
  • риски, не связанные с рыночной динамикой.

Рассмотрим подробнее эти риски и возможности их минимизации.

Начнём с первой группы рисков. Их перечень определяется, исходя из анализа графиков финансовых инструментов. Нужно проанализировать элементы графика и их параметры, включая характеристики как отдельных свечей, так и их групп, а также параметры скользящих средних. Другие традиционные индикаторы мы использовать не будем: их математические модели не соответствуют характеру процесса движения цен, и поэтому они неэффективны при анализе.


Рыночные риски, связанные с динамикой движения цен

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

Что такое тренд, каждый трейдер определяет для себя сам. Ведь, как ни парадоксально, "официального" определения этого понятия в техническом анализе не существует. А значит, субъективна и оценка вероятности разворота тренда. При этом величина критической амплитуды (при развороте тренда), которую определяет для себя трейдер, зависит от величины приемлемого риска (лимита риска). Он, в свою очередь, определяется количеством средств на балансе конкретного трейдера. Всё упирается в максимально допустимую просадку. Иными словами, что банку «хорошо», то рядовому трейдеру — «смерть».

Далее рассмотрим виды рисков и, по возможности, поищем решения по их минимизации.

Классификация рисков, связанных с рыночной динамикой

Традиционный анализ выделяет три вида трендов по длительности: краткосрочные, среднесрочные и долгосрочные.

Часто упоминаются также локальные и глобальные тренды. Обычно под локальными трендами подразумеваются тренды, формируемые в краткосрочной или среднесрочной перспективе. Глобальные тренды формируются в долгосрочной перспективе. При этом нет однозначных цифр, определяющих временные и амплитудные границы этих понятий. Всё опять же относительно. Поэтому упростим анализ: за критерий риска, связанного с разворотом тренда, возьмем величину амплитуды обратного движения. Будем оценивать ее относительно важных технических уровней, либо в зависимости от величины депозита инвестора, с учётом заданного лимита риска.

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

  • Риски, связанные с высокой волатильностью к моменту входа в рынок.
  • Риски, связанные с уровнями сопротивления при входе в рынок.
  • Риски попадания в зону перекупленности/перепроданности при входе в рынок.
  • Риски, связанные с отсутствием выраженного тренда при входе в рынок.
  • Риски, связанные с некорректным выбором периода расчёта индикаторов.
  • Риски, связанные с использованием отложенных ордеров при входе в рынок.
  • Риски, связанные с неопределённостью амплитуды движения цен после входа в рынок.
  • Риски, связанные с обвалами цен после входа в рынок.
  • Риски, связанные с использованием только одного таймфрейма.
  • Риски, связанные с использованием только одного типа анализа (технического или фундаментального).

Риски, связанные с высокой волатильностью к моменту входа в рынок

Многие трейдеры вообще не учитывают этот вид риска. Но это большая ошибка, ведь при высокой волатильности растет амплитуда движения, в том числе и против господствующего тренда. Это и есть фактор риска.

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

Чтобы минимизировать риск этого вида, можно задать в алгоритме входа условие: лимит предельной амплитуды в ближайшей истории котировок. Такой коридор цен может быть задан:

  • амплитудой между двумя противоположными фракталами
  • или амплитудой группы свечей.

Ограничение амплитуд свечей — самый простой способ. Рассмотрим фрагмент кода, в котором он реализован:

 //---АЛГОРИТМ ВХОДА В РЫНОК - ПОКУПКА (BUY)-------------------------------------------------------------------------------------------
      
  if( 
   //----МИНИМИЗИРУЕМ РИСКИ,СВЯЗАННЫЕ С ВЫСОКОЙ ВОЛАТИЛЬНОСТЬЮ К МОМЕНТУ ВХОДА В РЫНОК ----
  
     //Моделируем отсутствие высокой волатильности в ближайшей истории:
     ( High[1] - Low[1]) <= 200*Point &&                       //ограничение амплитуды свечей младшего таймфрейма (тфМ1)
     ( High[2] - Low[2]) <= 200*Point &&
     ( High[3] - Low[3]) <= 200*Point && 
     (H_prev_m15 - L_prev_m15) <= 300*Point &&                 //ограничение амплитуды свечей старшего таймфрейма (тфМ15)
     (H_2p_m15 - L_2p_m15) <= 300*Point && 
     (H_3p_m15 - L_3p_m15) <= 300*Point && 
     (H_prev_m15 - L_3p_m15) <= 300*Point &&                   //ограничение амплитуды канала из свечей старшего масштаба (тфМ15)
     (High[1] - Low[1]) >= (1.1*(High[2] - Low[2])) &&         //ограничение активности на предыдущем баре относительно 2-го бара в истории котировок 
     (High[1] - Low[1]) < (3.0*(High[2] - Low[2])) &&          //то же

Рис. 1. Модуль в алгоритме входа: минимизация рисков, связанных с высокой волатильностью к моменту входа в рынок.

На рисунке 1 показан модуль в алгоритме входа (Buy).

Обозначения:

  • High{1], High[2], High[3] — уровни Highна трёх предыдущих барах по таймфрейму М1,
  • H_prev_m15, H_2p_m15, H_3p_m15 — уровни High на трёх предыдущих барах по таймфрейму М15,
  • Low[1], Low[2], Low[3] — уровни Low на трёх предыдущих барах по таймфрейму М1,
  • L_prev_m15, L_2p_m15, L_3p_m15 — уровни Low на трёх предыдущих барах по таймфрейму М15.

Модуль позволяет минимизировать риски, возникающие, если точка входа находится в зоне значительной волатильности. Это достигается за счёт моделирования горизонтального ценового канала, а также моделирования активности (умеренной волатильности) в окончании канала.

Ценовые каналы на таймфреймах М1 и М15 моделируются за счёт ограничения амплитуды свечей, находящихся на трёх предыдущих барах в истории котировок. При этом ограничения амплитуды задаются как для отдельных свечей, так и для всей группы свечей. Амплитуда канала определяется как разница между экстремумами его первой и последней свечей.

Умеренная волатильность в окончании канала моделируется путём ограничения соотношения амплитуд двух соседних свечей таймфрейма М1 (в данном случае используется соотношение от 1.1 до 3.0). Разумеется, вы можете использовать другие соотношения амплитуд.

Возникает вопрос: зачем задавать амплитуду всего канала? Разве не достаточно задать амплитуду каждой свечи? Нет, не достаточно. Если не задать амплитуду всего канала, то может сформироваться волнообразный, а не горизонтальный канал, амплитуда которого может вдвое превышать амплитуду одной свечи.

Данный пример приведён для входа Buy. Для входа Sell код будет тот же, поскольку амплитуда канала и отдельных свечей определяется как разница High и Low, а направление будет задано не в этом, а в других модулях алгоритма входа.

Риски, связанные с наличием уровней сопротивления при входе в рынок

Участники рынка по-разному реагируют на уровни сопротивления, присутствующие на графике. Для одних это цели профита, для других — ограничители убытка, а для третьих — начальная цель для пробоя уровня. Поэтому вокруг фрактальных уровней часто формируются зоны, где цена двигается разнонаправленно с небольшой амплитудой. Риски открытия позиции в этих зонах повышены, а прогнозирование в них, по результатам тестирования различных торговых систем, неэффективно. Поэтому логичным видится решение, когда точка входа в рынок находится за пределами уровней сопротивления в направлении тренда.

Как же учитывать этот вид риска в торговле?

Если уже открыта позиция в направлении уровня сопротивления и цена приближается к нему, то эту позицию лучше закрыть заранее, потому что возможен сильный отскок, который ухудшит результат.

Если же вы планируете открыть позицию по своему алгоритму после того, как цена пройдет уровень сопротивления, то нужно дождаться его надёжного пробоя в выбранном направлении.

По сути, вопрос упирается в проблему ложного и истинного пробоя. Решить ее можно, например, так. Дождитесь, когда дальше фрактального уровня сформируется новый уровень сопротивления. Затем ждите, когда цена пробьёт этот новый фрактальный уровень. При этом желательно использовать один из младших таймфреймов. Но и этого недостаточно: в текущей динамике должны быть явные признаки активности в направлении пробоя и за пределами нового фрактального уровня.

Недостаток такого подхода — неопределенность таймфрейма. Он выбирается субъективно, потому что невозможно заранее спрогнозировать амплитуду пробоя уровня. Поэтому упростим задачу, задав условие, что на момент входа уровень уже должен быть пройден.

На этапе создания торговой системы можно воспользоваться несколькими вариантами в алгоритме входа для минимизации риска, связанного с наличием уровней сопротивления.

  • Вариант 1.Поиск ближайшего фрактала сопротивления (в коде это будет реализовано с использованием цикла). Преимущество такого подхода: мы найдем реальный уровень сопротивления на данном таймфрейме. Недостатков два. Во-первых, программирование циклов может оказаться сложным для начинающих кодеров. Во-вторых, фрактал может оказаться слишком далеко в истории, а значит, он будет неактуальным в качестве уровня сопротивления.
  • Вариант 2. Использовать High (для Buy) и Low (для Sell) предыдущей свечи. Преимуществ такого подхода два. Во-первых, это несложно запрограммировать. Во-вторых, можно задать одновременно несколько таймфреймов, что эквивалентно поиску старших фракталов. Недостаток: некоторые фракталы могут быть не обнаружены, так как экстремумы свечи являются фракталами только при наличии так называемых теней.

Для начинающих программистов, а также при разработке ручных стратегий, рекомендуется вариант 2: он прост и эффективен, даже несмотря на некоторое снижение точности из-за потери некоторых фракталов. Вот фрагмент кода:

 //----МИНИМИЗИРУЕМ РИСКИ,СВЯЗАННЫЕ С НАЛИЧИЕМ УРОВНЕЙ СОПРОТИВЛЕНИЯ ПРИ ВХОДЕ В РЫНОК-----
  
     //Моделируем ситуацию, при которой локальные уровни сопротивления преодолены текущей ценой:
       Bid > High[1] &&           //на М1 (младший таймфрейм)
       Bid > H_prev_m15 &&        //на М15 (старший таймфрейм)

Рис. 2. Модуль в алгоритме входа: минимизация рисков, связанных с наличием уровней сопротивления при входе.

На рисунке 2 представлен модуль в алгоритме входа для минимизации рисков, связанных с наличием уровней сопротивления для восходящего движения, входа Buy. Это достигается за счёт заданного условия о том, что текущая цена уже преодолела уровень сопротивления в виде High предыдущей свечи (отдельно на двух таймфреймах).

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

Для входа Sell в качестве уровней сопротивления нужно использовать уровни Low предыдущей свечи (на таймфреймах М1 и М15), с учётом нисходящего тренда.

Риски попадания в зону перекупленности/перепроданности при входе в рынок

Под этими рисками подразумевается вероятность входа в «хвосте» активного волнообразного движения, когда остаток амплитуды в направлении входа мал и резко повышается вероятность разворота. Такие области — не что иное, как зоны перекупленности/перепроданности. Использование традиционных индикаторов (RSI и т.д.) для их определения часто неэффективно, во многих случаях их сигналы ложные. Причина всё та же: в традиционных индикаторах нет адекватных математических алгоритмов определения этих зон. Для более точного поиска зон перекупленности/перепроданности нужно выявить признаки торможения тренда (в том числе, на М1, так как на нем сразу видна  динамика разворотов на всех остальных таймфреймах).

Итак, признаки торможения тренда будем выявлять сочетанием фрактального и свечного анализа по следующим критериям:

  • уменьшение дистанции (величины амплитуды) между соседними фрактальными уровнями сопротивления. Чтобы сравнить амплитуды двух соседних участков, нужны три фрактала;
  • увеличение глубины коррекции внутри свечи, уменьшение «тела» свечи (внутрисвечной анализ);
  • изменение направления смещения пивота свечи относительно пивота предыдущей свечи (для этого понадобятся три свечи).

Если используется этот способ, в алгоритм входа нужно вписать условие отсутствия перечисленных факторов. Например, это можно сделать с помощью false и true, где true говорит о том, что указанные факторы торможения на рынке есть.

Есть и другой, более простой вариант. Он не связан напрямую с поиском зоны перекупленности\перепроданности. Здесь используется косвенный признак: если обеспечить вход в рынок в начале волнообразного движения, то вероятность попадания в зону перекупленности\перепроданности при этом резко сокращается. По сути, мы моделируем начальную стадию локального тренда.

  • Сначала надо выявить пересечение одной или нескольких скользящих средних (МА) внутри одной и той же свечи — это возможное начало волнообразного движения. Для подтверждения начала волны нужны дополнительные условия (см. ниже).
  • Затем смоделируем начальную фазу развития волнообразного движения. Она и будет началом нового тренда. Для этого зададим: направление следующей после пересечения свечи; ее активность; направление быстрых МА, участвующих в пересечении на предыдущем баре; положение текущей цены относительно этих МА.

Обратите внимание: при моделировании начальной стадии локального тренда целесообразно задавать направление только быстрых МА. Направление медленных МА задавать не надо.

Причина такого разного подхода к скользящим средним следующая: старшие МА, в силу большего запаздывания, не успевают вовремя развернуться в направлении нового тренда. Поэтому, если задать их направление, то моделируемая точка входа в рынок может оказаться далеко от начала тренда и попасть в опасную зону перекупленности/перепроданности.

Второй вариант (моделирование начальной стадии локального тренда) проще и поэтому рекомендуется начинающим разработчикам. Рассмотрим фрагмент кода:

//---МИНИМИЗИРУЕМ РИСКИ,СВЯЗАННЫЕ СО ВХОДОМ В РЫНОК В ЗОНЕ ПЕРЕКУПЛЕННОСТИ-----
  
    //Моделируем привязку к началу волны, чтобы уменьшить вероятность входа в зоне перекупленности:
     ((MA8_prev > Low[1] && MA8_prev < High[1]) || (MA8_2p > Low[2] && MA8_2p < High[2]) || //начало волны - не далее трёх баров в истории данных (М1)
     (MA8_3p > Low[3] && MA8_3p < High[3])) &&                                              //то же
      MA5_prev_m15 > L_prev_m15 && MA5_prev_m15 < H_prev_m15 &&                             //начало волны - на предыдущем баре старшего таймфрейма (М15)
    

Рис. 3. Модуль в алгоритме входа: минимизация рисков попадания в зону перекупленности при входе в рынок.

Обозначения:

  • МА8_prev, МА8_2p, МА8_3p — МА с периодом 8, рассчитанная на предыдущем, 2-м и 3-м барах (соответственно) в истории котировок (М1),
  • МА5_prev_m15, МА5_2p_m15, МА5_3p_m15 — МА с периодом 5, рассчитанная на предыдущем, 2-м и 3-м барах (соответственно) в истории котировок (М15),
  • обозначения экстремумов свечей указаны ранее (см. рис.2).

Риск угодить в зону перекупленности минимизируется за счёт привязки точки входа к началу прогнозируемой волны. Признаком начала волны считаем факт пересечения МА свечой: на М1 это будет МА с периодом 8, на М15 — МА с периодом 5. Величина периодов скользящих средних выбрана из ряда Фибоначчи. Более подробно на выборе этого параметра мы остановимся позже, в разделе «Риски, связанные с некорректным выбором величины периода расчёта индикаторов».

В этом модуле не задаются параметры, характеризующие активность и направленность свечей и МА, а также положение текущей цены относительно МА. Это сделано, чтобы не дублировать переменные: зададим эти параметры в модуле из раздела «Риски, связанные с отсутствием выраженного тренда при входе в рынок».

Обратите внимание, что пересечение свечи и МА на таймфрейме М1 не ограничивается одним баром в истории. Оно задаётся логическим ИЛИ — либо на предыдущем, либо на 2-м, либо на 3-м баре в истории (на М1). На М15 в данном случае предусмотрен один вариант пересечения — на предыдущем баре в истории котировок. Этот набор возможных вариантов дает возможность учитывать многовариантность реальных рыночных ситуаций, связанных с развитием локального тренда относительно такого пересечения.

Вышеприведенный пример написан для входа Buy (избегаем зону перекупленности). Для входа Sell (избегаем зону перепроданности) модуль точно такой же, так как алгоритм пересечения МА со свечой не зависит от направления движения.

Итак, мы рассмотрели два способа войти в рынок и не попасть при этом в зоны перекупленности\перепроданности, а также найти эти зоны. С этими способами вы можете сами поэкспериментировать при создании вашей торговой системы или в разработке торговых индикаторов.

Риски, связанные с отсутствием выраженного тренда при входе в рынок

Еще один фактор неопределённости динамики и связанного с этим риска — отсутствие выраженного тренда. Речь идет о ситуациях, когда на рынке царит либо боковой тренд малой амплитуды, либо и вовсе флэт.

Определить господствующее направление цены при этом затруднительно, ведь оно постоянно меняется, а амплитуда изменений очень мала. Поэтому растет риск ошибки при прогнозе направления для открытия позиции.

Беда в том, что в рамках традиционных методов анализа нет однозначного определения флэта (как и в случае с трендом). Поэтому нет и определения границы между флэтом и началом тренда. Имеющиеся методы идентификации этих состояний рынка очень субъективны: это касается и метода квадратичных отклонений (например, в индикаторе “StdDev” ), и более «продвинутых» адаптивных функций (например, FRAMA). И уж совсем отдельная история — графические методы определения тренда в теханализе. Здесь сколько трейдеров, столько и трендов. По разным интерпретациям, к флэту относятся участки с разной, порой довольно значительной амплитудой. Это приводит к потерям прибыли.

Мой личный опыт показывает (и это подтверждается результатами ТС), что границу флэта эффективнее определять, задав абсолютную величину амплитуды внутри бокового тренда.

Но нужно помнить: если амплитуда больше выбранного порогового значения, то это еще не значит, что мы наблюдаем новый тренд! Поэтому не торопитесь немедленно открывать позицию. Нужно подтвердить эти данные текущей динамикой.

Подход с использованием абсолютных пороговых величин представляется мне более перспективным, чем оценка относительных величин амплитуд, которые очень сложно установить в условиях случайного нестационарного процесса. Конечно, это серьёзное упрощение, но на практике оно даёт неплохие результаты. Без него вы столкнётесь с серьезной проблемой и сложными теоретическими выкладками, ведь границы флэта и тренда — это предмет нечёткой логики.

Рассмотрим фрагмент кода (для входа Buy):

 //---МИНИМИЗИРУЕМ РИСКИ,СВЯЗАННЫЕ С ОТСУТСТВИЕМ ВЫРАЖЕННОГО ТРЕНДА ПРИ ВХОДЕ В РЫНОК-------
  
      //Моделируем направление свечей на младшем таймфрейме:
      Close[2] > Open[2] &&      //восходящее направление свечи на 2-м баре в истории (М1)
      Close[1] > Open[1] &&      //восходящее направление предыдущей свечи (М1)
      
      //Моделируем направление скользящих средних на младшем таймфрейме:
      MA5_cur > MA5_2p &&  MA60_cur > MA60_2p &&     //восходяшие МА: используем скользящие средние с периодом 5 и 60 (М1)
      
      //Моделируем иерархию скользящих средних на младшем таймфрейме:
      MA5_cur > MA8_cur && MA8_cur > MA13_cur &&     //сформирована "иерархия" трёх МА на М1 (периоды Фибоначчи:5,8,13), это косвенный признак восходящего движения
      
      //Моделируем положение текущей цены относительно скользящих средних младшего масштаба:
      Bid > MA5_cur && Bid > MA8_cur && Bid > MA13_cur && Bid > MA60_cur && //текущая цена выше МА (5,8,13,60) на М1, это косвенный признак восходящего движения 
      
      //Моделируем направление свечей на старшем таймфрейме:
      C_prev_m15 > O_prev_m15 &&       //восходящее направление предыдущей свечи (М15)
      
      //Моделируем направление скользящей средней на старшем таймфрейме: 
      MA4_cur_m15 > MA4_2p_m15 &&     //восходяшая МА с периодом 4 (М15)
      
      //Моделируем иерархию скользящих средних на старшем таймфрейме: 
      MA4_prev_m15 > MA8_prev_m15 &&  //сформирована "иерархия" двух МА на М15 (периоды 4 и 8), это косвенный признак восходящего движения
      
      //Моделируем положение текущей цены относительно скользящих средних старших таймфреймов:
      Bid > MA4_cur_m15 &&            //текущая цена выше МА4 (М15), это косвенный признак восходящего движения 
      Bid > MA24_cur_h1 &&            //текущая цена выше МА24 (МН1), это косвенный признак восходящего движения
      
      //Моделирование микротренда внутри текущей свечи младшего таймфрейма, а также точки входа:
      Bid > Open[0] &&               //наличие восходящего движения внутри текущей свечи (М1)
       
     //Моделирование достаточной активности предыдущего процесса в старшем таймфрейме:
     (C_prev_m15 - O_prev_m15) > (0.5*(H_prev_m15 - L_prev_m15)) &&  //доля "тела" свечи более 50% от величины амплитуды свечи (предыдущая свеча М15)
     (H_prev_m15 - C_prev_m15) < (0.25*(H_prev_m15 - L_prev_m15)) && //ограничение глубины коррекции-менее 25% амплитуды свечи (предыдущая свеча М15)
      H_prev_m15 > H_2p_m15 &&                                       //восходящая тенденция по локальным уровням сопротивления (две свечи М15) 
      O_prev_m15 < H_prev_m15 && O_prev_m15 > L_prev_m15 &&          //наличие тени (предыдущая свеча М15)относительно цены открытия данной свечи
      
     //Моделирование достаточной активности предыдущего процесса в младшем таймфрейме: 
     (Close[1] - Open[1]) > (0.5*(High[1] - Low[1])) &&              //доля "тела" свечи более 50% от величины амплитуды свечи (предыдущая свеча М1)
     (High[1] - Low[1]) > 70*Point &&                                //предыдущая свеча имеет амплитуду больше пороговой (исключаем явный флэт)
     (High[2] - Close[2]) < (0.25*(High[2] - Low[2])) &&             //ограничение глубины коррекции-менее 20% амплитуды свечи (2-я свеча в истории данных М1)
      High[1] > High[2] &&                                           //восходящая тенденция по локальным уровням сопротивления (две свечи М1)
      Open[1] < High[1] && Open[1] > Low[1] )                        //наличие тени (предыдущая свеча тфМ1)относительно цены открытия данной свечи
      

Рис. 4. Модуль в алгоритме входа: минимизация рисков, связанных с отсутствием выраженного тренда при входе в рынок.

Обозначения:

  • Open[1], Close[1] — цены открытия и закрытия соответственно на предыдущем баре (М1);
  • МА5_cur, MA8_cur, MA13_cur, MA60_cur — значения МА на текущем баре с периодами 5,8, 13, 60 соответственно (М1);
  • MA4_cur_m15, MA4_prev_m15, MA4_2p_m15 — значения МА с периодом 4 на текущем, предыдущем и 2-м баре в истории котировок, соответственно (М15);
  • MA8_prev_m15 —  значение МА с периодом 8 на предыдущем баре в истории котировок (М15).

Этот вид риска мы снижаем за счет того, что моделируется выраженный тренд, причём одновременно на двух таймфреймах — М1 и М15, а именно:

  • направление предыдущих свечей в направлении открытия позиции (две свечи на М1 и одна — на М15);
  • направление скользящих средних (две МА на М1, одна — на М15);
  • иерархия скользящих средних (три МА на М1 и две — на М15);
  • положение текущей цены относительно скользящих средних — трёх МА на М1.

Такой «комплекс мер» существенно увеличивает вероятность того, что точка входа в позицию будет находиться внутри выраженного тренда, причём на двух таймфреймах одновременно. Соответственно, снизится вероятность попасть в зону флэта, случайных флуктуаций и других областей невыраженного тренда. А значит и снизится риск, связанный с этим неблагоприятным фактором.

В нашем примере рассмотрен вариант для входа Buy. Для входа Sell алгоритм будет зеркальным — вместо восходящего направления свечей и МА задается нисходящее, и точка входа будет не выше, а ниже, чем указанные МА.

Риски, связанные с некорректным выбором величины периода расчёта индикаторов

Каждый трейдер настраивает период индикатора, в том числе скользящей средней, произвольно, исходя из личного опыта. Кто-то предпочитает МА с периодом 200, кто-то любит период 50, а кому-то милее периоды по ряду Фибоначчи. То есть, мы выбираем конкретные настройки индикаторов (и в первую очередь — период, который нас интересует больше всего) интуитивно.

Причина такой вынужденной интуитивности в том, что в традиционных методах анализа нет механизмов идентификации частотно изменяемых колебаний в конкретный момент времени. Это и приводит к неопределённости при настройке периода индикаторов. Конечно, есть методы построения адаптивных функций (Кауфмана, FRAMA и т.д.), но их алгоритмы тоже не учитывают постоянно изменяющейся частоты рыночных колебаний.

Рассмотрим частичное решение проблемы: используем традиционные методы анализа, но внесем некоторую логику в определение периодов скользящих средних. Используем при этом некоторые неизменные факторы, связанные со временем. В пользу такого принципа говорит тот факт, что границы свечей крупных таймфреймов являются фрактальными уровнями для внутрисвечных движений — но только если у этих свечей есть тени. Если тени нет, то движение может продолжиться на следующую свечу без образования фрактала.

Соотносим стандартные таймфреймы и числа ряда Фибоначчи (близкие по величине). Получаем следующие пары примерного соответствия таймфреймов и периодов расчёта МА:

  • 1 минута — ближайшее число Фибоначчи 1 (минута, это пивот);
  • 5 минут — ближайшее число Фибоначчи 5 (минут);
  • 15 минут – ближайшее число Фибоначчи 13 (минут);
  • 1 час (60 минут) — ближайшее число Фибоначчи 55 (минут);
  • 4 часа (240 минут) — ближайшие числа Фибоначчи 3 (часа), 5 (часов), 233 (минуты);
  • 1 день (24 часа) — ближайшее число Фибоначчи 21 (час);
  • 5 дней (торговая неделя, 120 часов для рынка Форекс) — ближайшие числа Фибоначчи 89 (часов) и 144 (часа).

В дополнение к этому можно рекомендовать вариант, минимизирующий запаздывание МА:

  • на каждом таймфрейме использовать только первые числа ряда: 1 (пивот), 3, 5, 8, 13;
  • использовать их комплексно: переводить в младший таймфрейм с помощью коэффициента, равного отношению таймфреймов. Использование МА с минимальными периодами позволит минимизировать запаздывание этих функций.

В итоге получаем набор скользящих средних для разных масштабов (пример использования четырёх таймфреймов):

  • для М1:МА с периодами 5, 8, 13, 55 (или 60 =1 час), 233 (или 240 = 4 часа);
  • для М15: МА с периодами 5, 8, 13, 55 (или 60=4 часа?);
  • для Н1: МА с периодами 5, 8, 13, 21 (или 24 = 1 день), 89, 144 (или 120 = 5 дней);
  • для D1: МА с периодами 5, 8, 13, 21 (или 24 = 1 торговый месяц).

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

Эти рекомендации по выбору скользящих средних мы будем использовать и при разработке других описываемых модулей.

Риски, связанные с использованием отложенных ордеров для входа в рынок

Здесь имеются в виду стратегии получения прибыли, где целевой уровень задается не рыночным, а отложенным ордером. Чаще всего отложенные ордера используются в стратегиях, связанных с выходом цены из зон консолидации.

При всём многообразии подобных стратегий, поговорим об использовании пары отложенных ордеров, выставляемых по обеим сторонам зоны консолидации в надежде на то, что один ордер сработает верно, а второй будет удален за ненужностью сразу после срабатывания первого. При этом нужно учитывать, что использование отложенных ордеров для определения точки входа связано с риском. Ведь уровень, на который выставляется отложенный ордер, всегда определяется раньше, чем происходит событие достижения желаемой цены. Уровень отложенного ордера определяется например, в процентах от амплитуды зоны консолидации, или вообще интуитивно,и это никак не связано с реальной динамикой цены.

В этом, собственно, и заключается главный недостаток отложенных ордеров по сравнению с рыночными – невозможность избежать открытия позиции при наличии негативных факторов в момент входа. Ведь сразу же после момента достижения желаемой цены динамика рынка может оказаться неблагоприятной для данного типа отложенного ордера, но, несмотря на это, вход в рынок всё равно состоится. В результате трейдер потеряет деньги.

Поэтому, если вы всё-таки хотите торговать от конкретных фиксированных уровней, то целесообразнее вместо стандартных отложенных ордеров задавать их внутри алгоритма входа виртуально. Входить по ним в рынок нужно, только если при их пересечении действительно зафиксирована нужная динамика. Это, конечно, сложнее, чем классические отложенные ордера, так как требуется дополнительный алгоритм контроля динамики в момент пересечения ценой виртуального уровня (понадобятся знания по программированию такого алгоритма). Зато вы избавитесь от рисков торговли «вслепую», неизбежных при использовании традиционных отложенных ордеров.

Есть у этого способа и недостатки. Когда цена достигает нужного уровня, мы входим рыночным, а не отложенным ордером, который будет отражаться в платформе брокера позже, чем уже выставленные отложенные ордера. И если количество ордеров велико, то высока вероятность задержки исполнения, связанной с очерёдностью ордеров. При резком скачке цены в момент входа возможно и проскальзывание.

Перед вами встает проблема выбора между риском «слепого» входа отложенными ордерами и риском запаздывания исполнения рыночных ордеров. При этом преимущество использования виртуального уровня в том, что система может вообще отменить вход в автоматическом режиме, если при достижении заданного уровня на рынке не будет дополнительных благоприятных условий для входа в рынок.

Моё личное мнение: поскольку использование отложенных ордеров повышает риск, то надо минимизировать этот риск, отказавшись от них. Такой отказ оправдан в том числе и тем, что амплитуду движений цены определяет только рынок. А наша задача — лишь фиксировать такие движения на определённой стадии развития, а затем сопровождать их при помощи аналитических функций.

Риски, связанные с неопределённостью амплитуды движения цен после входа в рынок

Типичная ошибка многих трейдеров состоит в том, что они чрезмерно увлекаются определением конкретных целевых уровней. Между тем, в условиях случайного нестационарного процесса движения цены окончательная амплитуда трендов – это вероятностная величина. А значит, как и в ранее рассмотренном примере с отложенными ордерами, установка конкретных фиксированных целевых уровней для фиксации прибыли (то есть, для определения точки выхода из рынка) имеет интуитивный характер. Поэтому часто такой подход приводит к убыткам.

Алгоритм выхода из рынка должен иметь либо функцию контроля признаков торможения (то есть, адаптивную функцию), либо функцию контроля фиксированной величины амплитуды относительно неких уровней (уровень входа, текущий максимум или минимум внутри открытой позиции). Добавим во второй вариант также и контроль лимита риска — как на позицию, так и в целом по депозиту. Остановимся на последнем, более простом варианте. Рассмотрим фрагмент кода:

 //МИНИМИЗИРУЕМ РИСКИ, СВЯЗАННЫЕ С НЕОПРЕДЕЛЁННОСТЬЮ АМПЛИТУДЫ ДВИЖЕНИЯ ЦЕН ПОСЛЕ ВХОДА В РЫНОК-- 
             
              //Контроль величины фиксированной прибыли (на позицию):
              (Bid > OrderOpenPrice() && (Bid - OrderOpenPrice()) >= 100*Point)                       //условия выхода в зоне профита (теневой тейк-профит)
                     ||
                     
             //Контроль величины максимально-допустимого отклонения цены 
             //от текущего максимума после входа в рынок:    
             (shift_buy >= 1 &&                                                                          //сдвиг не менее 1 бара от точки входа
             Time_cur > OrderOpenTime() && Max_pos > 0 && OrderOpenTime() > 0 && OrderOpenPrice() > 0 && //есть текущий максимум после входа
             Max_pos > OrderOpenPrice() &&                                                               //текущий максимум находится в зоне профита
             Bid < Max_pos &&                                                                            //есть обратное движение цены
             (Max_pos - Bid) >= 200*Point)                                                               //величина обратного отклонения от текущего максимума для выхода из рынка
                    ||
                      
             //Контроль заранее установленного лимита риска (на позицию):     
              (Bid < OrderOpenPrice() && (OrderOpenPrice() - Bid) >= 200*Point)                          //условия выхода в зоне убытка (теневой стоп-лосс)
                    ||
                    
             //Контроль заранее установленного лимита риска (в целом по депозиту):
              (AccountBalance() <=  NormalizeDouble( (Depo_first*((100 - Percent_risk_depo)/100)), 0)) )  //если при текущей торговле превышен лимит риска в целом по депозиту 

Рис.5. Модуль в алгоритме выхода: минимизация рисков, связанных с неопределённостью амплитуды движения цен после входа в рынок.

Обозначения:

  • OrderOpenPrice() — цена при входе в рынок;
  • Shift_buy —  сдвиг (в барах на М1) относительно точки входа (необходим для определения максимума внутри открытой позиции);
  • Max_pos  — уровень максимума внутри открытой позиции;
  • AccountBalance()текущее значение баланса депозита в денежном выражении;
  • Depo_first — начальный депозит в денежном выражении;
  • Percent_risk_depo — процент максимально допустимых потерь в целом по депозиту.

Минимизация этого вида риска достигается за счёт использования следующих функций:

  • Контроль фиксированной прибыли на позицию — это, по сути, «теневой» тейк-профит.
  • Контроль максимально допустимого отклонения цены от текущего максимума (для Buy) или текущего минимума (для Sell) после входа в рынок.
  • Контроль заранее установленного лимита риска на позицию — это «теневой» стоп-лосс.
  • Контроль заранее установленного лимита риска в целом по депозиту.

Во всех этих случаях мы контролируем определённое значение амплитуды относительно уровней, которые могут изменять своё значение. Это и уровень входа, и максимум внутри открытой позиции, и величина начального значения депозита. Поэтому, в отличие от жёстких целевых уровней, в данном случае эти цели не являются фиксированными уровнями.

Мы рассмотрели пример модуля в алгоритме закрытия позиции Buy. Для модуля Sell изменения будут лишь в части направления движения. Вместо текущего максимума внутри позиции (Max_pos) будет использоваться текущий минимум (Min_pos).

В следующем разделе мы рассмотрим риски, учитывающие не только амплитуду, но и скорость, что особенно важно при обвалах рыночных цен.

Риски, связанные с обвалами цен после входа в рынок

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

Суть проблемы

  • Скорости обвалов цен лежат за пределами адекватного реагирования участников рынка.
  • В современной аналитике нет механизма идентификации динамических структур, присущих быстрым обвалам цен.
  • При наличии открытой позиции участники рынка совершенно беззащитны при обвалах цен. На ранней стадии обнаружить обвал проблематично, а вовремя отреагировать на него невозможно, поскольку основной максимум движения уже пройден, либо рынок заблокирован из-за паники в цепочке брокеров и банков.

Результат — огромные убытки участников торговли. Например, 6 мая 2010 года индекс Dow Jones обвалился за 6 минут на 1000 пунктов, при этом, по экспертным оценкам, рынок потерял около триллиона долларов.

Более свежий пример (на рис. 6) — выход Великобритании из ЕС, который спровоцировал обвал GBPUSD 24 июня 2016 года сразу на 560 пунктов. 473 пункта из них были потеряны за одну минуту:

GBPUSD 24/06/2014

Рис. 6. Обвал цены GBPUSD 24 июня 2016 года.

Глобальных причин обвалов цен три.

  1. Природа самого рынка. Обвал — это не что-то чужеродное, а естественное проявление рыночной динамики. В числе прочего, к нему может приводить резкий скачок скорости изменения цен (в том числе из-за роста количества участников рынка, включая торговых роботов). Например, по данным СМИ, на фондовом рынке США регистрируются тысячи сверхбыстрых флуктуаций длительностью менее 1 секунды.
  2. Уровень развития аналитики. Методы идентификации подобных проявлений рынка несовершенны. Для реагирования на обвалы нужен анализ на уровне долей минуты, а секундные таймфреймы — редкость для рыночных платформ.
  3. Недостатки в законодательстве, регулирующем деятельность на финансовых рынках. К примеру, нет никаких правовых механизмов борьбы с искусственными манипуляциями ценой, которые осуществляют маркетмейкеры.

Вот пример того, как эксперт на основе MACD не успевает отреагировать на резкий обвал цен пары USDCHF:


USDCHF- MACD

Рис. 7. Эксперт на основе индикатора MACD не успевает реагировать на обвал цен USDCHF 2 октября 2015 года.

На рисунке 7 видно, что эксперт открыл две позиции — одну до обвала цен (стрелка 1), другую — после (стрелка 2). А на сам импульс при обвале он вообще не отреагировал, поскольку попросту «не заметил» его.

Таким образом, если у вас открыта позиция, то при обвале или резком ралли возникает риск потери значительной части депозита. Поэтому в алгоритме закрытия позиции должен быть модуль защиты от таких ситуаций.

Рассмотрим фрагмент кода:

 if( 
            //МИНИМИЗИРУЕМ РИСКИ, СВЯЗАННЫЕ С ОБВАЛАМИ ЦЕН ПОСЛЕ ВХОДА В РЫНОК----------------------
            
              (Bid < Open[0] && (Open[0] - Bid) >= 100*Point && (Time_cur - Time[0]) <= 20)           //условия выхода (в любой зоне) при обвале цен (контрольная точка - цена открытия текущей свечи М1)
                     ||
              (Bid < O_cur_m15 && (O_cur_m15 - Bid) >= 200*Point && (Time_cur - Time_cur_m15) <= 120) //условия выхода (в любой зоне) при обвале цен (контрольная точка - цена открытия текущей свечи М15)
                     ||
              ((Time_cur - OrderOpenTime()) > 60 && Close[1] < Open[1] && 
              (Open[1] - Close[1]) >= 200*Point)                                                      //условия выхода в любой зоне при обвале цен (контрольный параметр - амплитуда предыдущей свечи М1)
                     ||

Рис. 8. Модуль в алгоритме выхода - минимизация рисков, связанных с обвалами цен после входа в рынок.

Риски обвала цен после открытия позиции минимизируются следующим образом.

  • Задаются предельные значения обратного отклонения (обвала) цены относительно уровня открытия текущей свечи отдельно на разных таймфреймах (в данном случае это М1 и М15), а также максимально допустимая длительность такого обвала.
  • Задаётся амплитуда максимально допустимого обвала в виде завершённой предыдущей свечи на М1 (так как это минутная свеча, то косвенно задаётся и время обвала).

Таким образом, обвал контролируется и в начале текущей свечи (по обвалу на предыдущей свече), и в процессе развития текущей свечи. Если любое из указанных условий появляется (по логике ИЛИ), позиция закрывается — риск минимизируется.

В данном примере показан модуль для закрытия позиции Buy. Для закрытия позиции Sell нужно зеркально учесть направление движения цены.

Риски, связанные с использованием только одного таймфрейма при анализе

Изменения цены по-разному отражаются на графиках разного таймфрейма. Явный тренд на младшем таймфрейме может оказаться лишь незначительной коррекцией, если рассматривать его на старшем периоде графика.

Поэтому для полного анализа динамики цен ее нужно рассматривать на нескольких таймфреймах — одного недостаточно.

Сколько таймфреймов использовать при анализе? На личное усмотрение каждого. Лично я использую одновременно четыре таймфрейма (на четырех экранах), и вот почему:

  • М1: на этом таймфрейме хорошо видны и развороты трендов (в том числе глобальных), и быстрые обвалы рынка;
  • М15: свечи на этом периоде графика часто отражают законченные динамические структуры быстрых обвалов рынка, формируемые на младших таймфреймах (М1, М5);
  • Н1: свечи на этом таймфрейме — естественные временные ограничители (в том числе, в распорядке торговых сессий, публикации макроэкономических показателей, новостной информации и т.д.);
  • D1: свечи на этом таймфрейме — естественные ограничители (в том числе, при учете торговых дней внутри недели).

Такой набор таймфреймов я вижу оптимальным, так как он позволяет точно анализировать динамику рынка. Конечно, нужен некоторый опыт «объёмного» восприятия движения цен, но это просто необходимо при работе с финансовыми рынками.

Поскольку использование одного таймфрейма неизбежно увеличивает риски трейдинга, то в коде алгоритма входа должен присутствовать анализ свечей, МА и других индикаторов применительно к нескольким таймфреймам.

Риски, связанные с использованием только одного вида анализа (технического или фундаментального)

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

Целесообразнее использовать оба вида анализа в комплексе, поскольку они логически дополняют друг друга. Фундаментальные факторы в целом (но не абсолютно) предопределяют направление движения цены, а технические факторы это подтверждают. Но первичность фундаментальных факторов относительно технических не абсолютна.

В некоторых ситуациях рынок в большей степени реагирует именно на технические факторы, а не на фундаментальные — так бывает в моменты достижения исторических максимумов. Яркий пример тому — периодические обвалы биткоина (иногда на 20% в день) сразу после достижения исторического максимума. Впрочем, пример с биткоином не совсем показателен, так как фундаментальный анализ криптовалют в принципе проблематичен из-за специфики рынка.

Но в случае торговли на рынке Форекс и особенно — на фондовом рынке, роль фундаментального анализа очевидна. Например, обвал цены пары USDCHF (в октябре 2015 года) безусловно был спровоцирован тем, что банк Швейцарии «отвязал» курс франка от курса евро.

Поэтому, на мой взгляд, целесообразно отказаться от поиска строго приоритета ТА или ФА, а использовать их в комплексе. При этом сразу возникает вопрос: как использовать фундаментальный анализ при автоматической торговле, ведь алгоритм торговой системы анализирует лишь технические параметры рынка?

Можно предложить два варианта встраивания фундаментального анализа в ТС.

  • Вариант 1. Попытаться внести фундаментальные параметры в алгоритм торговой системы, преобразовав их в технические (например, заводить данные экономического календаря, определив логику действия этих показателей).
  • Вариант 2. Вручную ограничить направления входа в рынок внутри торгового эксперта (только в том направлении, которое соответствует фундаментальным показателям).

Как видим, использовать фундаментальный анализ в алготорговле неудобно, однако это правильный путь. Комплексное использование ТА и ФА в ручной торговле проще, к этому и нужно стремиться начинающим аналитикам и трейдерам.


Риски, не связанные с рыночной динамикой

Внешние факторы — эксплуатационные, финансовые и юридические — тоже часть торгового процесса. Они играют не менее важную роль в возникновении рисков. Поэтому, по возможности, их стоит учесть при разработке торговой системы.

Определим их перечень.

Классификация рисков, не связанных с рыночной динамикой

Вот самые распространенные из возможных рисков, не связанных с динамикой цены.

  • Риски, связанные со структурой торговой системы.
  • Риски, связанные с превышением лимита потерь по депозиту (контроль лимита риска инвестора по депозиту).
  • Риски, связанные с негативными изменениями торговых условий.
  • Риски, определяемые качеством связи с торговым сервером брокера.
  • Риски, связанные с разрешением на автоматическую торговлю на стороне брокера или клиента.
  • Риски, связанные с изменением законодательства в области финансовых рынков.

Рассмотрим эти риски и наметим меры по их минимизации.

Риски, связанные со структурой торговой системы

Главное правило: структура торговой системы должна учитывать структуру рисков. В нее нужно включить защиту от максимально возможного количества рисков, рассмотренных ранее. Это позволит повысить результативность торговли.

Но увеличивая количество блоков минимизации рисков, мы неизбежно увеличиваем количество фильтров, ведь любой способ избегания рисков — это, по сути, фильтр. В итоге мы сталкиваемся с «зафильтрованностью» алгоритмов входа торгового робота. При этом большинство трейдеров считают, что робот должен достаточно активно торговать, открывая позиции как минимум ежедневно. В этом смысле трейдер — заказчик робота, и с его стороны такое требование вроде бы вполне логично. Однако с точки зрения понимания природы процесса, это, на мой взгляд, неверно, и вот почему.

Алгоритм любого робота — всегда моделирование сложнейших динамических процессов, причём неизбежно упрощённое. Ошибки связаны с неполным соответствием модели отдельного робота динамике рынка.

Каждый разработчик знает, что есть зависимость между количеством входов торговой системы и объёмом фильтрации в алгоритме входа. Чем больше объём фильтрации — тем меньше количество входов, и наоборот. Причем в общем случае с увеличением фильтрации улучшается финансовый результат. Но, разумеется, всё зависит от содержания фильтров. Понятно, что для каждой торговой системы нужно находить компромисс между количеством входов и финансовым результатом, а точнее — максимальным риском (просадкой депозита). Это и называется традиционной оптимизацией.

А что, собственно, подразумевается под фильтрацией?

Если это выделение полезного сигнала из всего спектра, то нужны чёткие критерии этой полезности. Но их нет в традиционном анализе — вряд ли срабатывание традиционных индикаторов можно назвать «правильной» фильтрацией столь сложного процесса, как движение цен. Если, к примеру, для поиска полезного сигнала использовать волновые структуры Эллиотта или фигуры ТА, то все они ненадёжны для анализа, ведь каждый трейдер определяет их по-разному на одном и том же графике.

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

Отсюда следует вывод:

Количество открываемых позиций — второстепенный фактор оценки качества робота. Главное — его относительная стабильность при получении прибыли.

Оценивать эффективность торговой системы нужно тестированием на нескольких финансовых инструментах. Это повышает качество моделирования и улучшает результат:

  • ТС тестируется на разнообразных проявлениях рыночной динамики;
  • При положительном результате тестирования на нескольких инструментах суммарная прибыль по депозиту вырастает. За счет этого удовлетворяется требование инвестора о величине прибыли.

Значит, и оптимизация ТС должна сводиться к выбору таких настроек, которые показывают успешность при тестировании на нескольких финансовых инструментах.

Риски, связанные с превышением лимита потерь по депозиту

Ещё до начала торговли необходимо установить лимит риска по торговому депозиту. Это будет фиксированная величина, абсолютная (в денежном выражении), или относительная (в процентах от начальной суммы депозита). По ее достижении торговля прекращается.

Если вы передаёте торговый счёт в доверительное управление более опытному трейдеру, то величину лимита риска нужно указать в договоре.

Если вы торгуете сами, то необходимо добавить код как в алгоритм входа (запрет входа при превышении лимита риска), так и в алгоритм закрытия позиции (это мы уже рассмотрели ранее в разделе «Риски, связанные с неопределённостью амплитуды движения цен после входа в рынок"). Двойной контроль депозита нужен потому, что сначала лимит риска по депозиту достигается при наличии открытой позиции (это фиксируется в алгоритме выхода из рынка). Затем нужно блокировать следующие входы, так как лимит риска по депозиту уже достигнут (это фиксируется в модуле перед алгоритмом входа в рынок).

Рассмотрим фрагмент кода:

 //КОНТРОЛЬ ФИНАНСОВЫХ ПАРАМЕТРОВ,СВЯЗАННЫХ С ЛИМИТОМ РИСКА В ЦЕЛОМ ПО ДЕПОЗИТУ КЛИЕНТА-------------------------------
  
  if(kol < 1) //нет ордеров
  {
   if(AccountBalance() <=  NormalizeDouble( (Depo_first*((100 - Percent_risk_depo)/100)), 0))//если ранее превышен лимит риска в целом по депозиту 
    {
     Print("Вх запрещён-ранее достигнут лимит риска=",Percent_risk_depo, " % в целом по депозиту=", Depo_first);
     Alert("Вх запрещён-ранее достигнут лимит риска=",Percent_risk_depo, " % в целом по депозиту=", Depo_first); 
     return;
    }
    
    
   if(AccountFreeMargin() < (1000*Lots)) //если недостаточно залоговых средств, разрешённых для открытия ордеров на текущем счёте
    {
     Print("Недостаточно залоговых средств.Свободная маржа счёта = ",AccountFreeMargin());
     Alert("Недостаточно залоговых средств.Свободная маржа счёта = ",AccountFreeMargin());
     return; //...то выходим
    } 
  }     
        
 //-------------- 

Рис. 9. Модуль до алгоритма входа: минимизация рисков, связанных с превышением лимита потерь по депозиту.

В первом блоке контролируется состояние депозита клиента (переменная AccountBalance()). Настраиваемые переменные:

  • Depo_first — начальная величина депозита в денежном выражении;
  • Percent_risk_depo — лимит потерь по депозиту (в % от его начальной величины).

Алгоритм срабатывает, если потери по депозиту достигнут значения, заданной переменной Percent_risk_depo. При этом вход в рынок запрещается, и мы выходим из программы.

Во втором блоке контролируется величина залоговых средств на счете, при которой разрешен вход в рынок. Алгоритм срабатывает, когда объем залоговых средств становится ниже определённого количества лотов. Вход в рынок запрещается, выходим из программы.

Риски, связанные с наступлением неблагоприятных условий для торговли

Такими факторами могут быть: качество котировок, предоставляемых брокером; расширение спреда на момент открытия и закрытия позиции; проскальзывание цены при исполнении ордеров; задержки исполнения ордеров.

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

Вы можете самостоятельно разработать такой модуль в своей торговой системе.


Риски, определяемые качеством связи с торговым сервером брокера

Качество связи с торговым сервером зависит от двух факторов:

  • включен ли торговый сервер на стороне брокера;
  • работает ли интернет на стороне клиента.

Второй фактор можно исключить за счёт размещения клиентского терминала на внешнем сервере. Первый фактор проверяется программно, с помощью добавления кода в алгоритм ТС.

Рассмотрим фрагмент кода:

 if(IsConnected() == false) //проверка состояния главного соединения клиентского терминала с сервером брокера
    {
     Print("Вх запрещён-откл сервер брокера"); 
     Alert("Вх запрещён-откл сервер брокера");
     return;
    } 

Рис. 10. Модуль минимизации рисков, связанных с качеством связи с торговым сервером брокера.

На рисунке 10 показан фрагмент кода, позволяющий контролировать связь с сервером брокера. Его нужно встроить в советник до алгоритма входа. При наступлении указанных условий открытие позиции блокируется.

Риски, связанные с наличием разрешений на автоматическую торговлю на стороне брокера и на стороне клиента

Иногда ТС отсылает ордер в клиентском терминале, но он не исполняется. При этом запрета на вход со стороны самой ТС нет. Возможные причины этого:

  • в клиентском терминале не поставлены галочки для разрешения автоматической торговли на стороне клиента;
  • нет разрешения для торговли на текущем торговом счете на стороне брокера.

Чтобы устранить эти риски, надо контролировать, разрешена ли автоматическая торговля в программе торговой системы.

Рассмотрим фрагмент кода:

 if(IsTradeAllowed() == false) //проверка возможности торговать при помощи экспертов (поток брокера, разрешение торговать)
    {
     
     Print("Вх запрещён-несвободен торг поток у брокера,и/или у робота нет разрешения торговать :", IsTradeAllowed()); 
     Alert("Вх запрещён-несвободен торг поток у брокера,и/или у робота нет разрешения торговать :", IsTradeAllowed());
     return;
    } 
    
    
    if( !AccountInfoInteger(ACCOUNT_TRADE_EXPERT) ) //проверка свойств торгового счёта
    {
     Print("Авт торг запрещена для счёта :", AccountInfoInteger(ACCOUNT_LOGIN), "на стороне торг сервера"); 
     Alert("Авт торг запрещена для счёта :", AccountInfoInteger(ACCOUNT_LOGIN), "на стороне торг сервера"); 
     return;
    }
    
    
    if(IsExpertEnabled() == false) //проверка разрешения запуска экспертов в клиентском терминале
    {
     
     Print("Вх запрещён- в терминале клиента у робота нет разрешения торговать :", IsExpertEnabled()); 
     Alert("Вх запрещён- в терминале клиента у робота нет разрешения торговать :", IsExpertEnabled());
     return;
    } 
    
    
   if(IsStopped() == true) //проверка поступления команды завершить выполнение mql4-программы
    {
     Print("Вх запрещён-поступила команда на завершение работы mql4-программы"); 
     Alert("Вх запрещён-поступила команда на завершение работы mql4-программы");
     return;
    } 

Рис. 11. Модуль минимизации рисков, связанных с наличием разрешений на автоматическую торговлю на стороне брокера и стороне клиента.

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

Риски, связанные с изменением законодательства в области финансовых рынков

Это правила взаимоотношений в индустрии финансовых рынков, которые напрямую или косвенно влияют на риски клиента. В различных странах разрабатываются законодательные акты, регулирующие взаимоотношения на фондовых и финансовых рынках. В перспективе многие риски, связанные с различными нарушениями, должны уменьшиться.

Пример простого эксперта, учитывающего некоторые из указанных рисков

Итак, мы выявили и рассмотрели риски — как связанные, так и не связанные с рыночной динамикой, а также определили конкретные решения по их снижению.

Риски минимизируются с помощью встраивания в советник особых модулей (до алгоритма входа, в алгоритме входа в рынок, в алгоритме выхода из рынка). Каждый модуль контролирует свой вид риска.

Основные элементы анализа — свечи разных таймфреймов. Анализируется динамика, как внутри свечей (анализ единичной структуры), так и между ними (анализ группы структур).

Ниже представлен код простого эксперта, в котором я реализовал решения по минимизации некоторых рисков, которые мы рассмотрели. Обратите внимание, что из традиционных индикаторов используются лишь скользящие средние (да и то с учётом ограничений, о которых мы говорили ранее).

Код эксперта для котировок с 5 знаками (или 3 знаками для USDJPY):

//+------------------------------------------------------------------+
//|                                                 Reduce_risks.mq4 |
//|                            Copyright 2017, Alexander Masterskikh |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright   "2017, Alexander Masterskikh"
#property link        "https://www.mql5.com/ru/users/a.masterskikh"

input double TakeProfit     = 600;   //тейк-профит                                    
input double StopLoss       = 300;   //стоп-лосс                                 
input double Lots           = 1;     //количество лотов
input int Depo_first        = 10000; //начальная величина депозита клиента в денежном выражении
input int Percent_risk_depo = 5;     //максимально допустимый риск в целом по депозиту (в % к начальной сумме депозита клиента)
input bool test             = false; //установить: для тестирования true (по умолчанию - для торговли false)

//-------------------------------------------------------------------------------------------------

void OnTick(void)
  {
   //---определение переменных---
   int f,numb,kol;
   double sl_buy, tp_buy, sl_sell, tp_sell;
   double L_prev_m15, L_2p_m15, L_3p_m15; 
   double H_prev_m15, H_2p_m15, H_3p_m15;
   double O_cur_m15, O_prev_m15, O_2p_m15, C_prev_m15, C_2p_m15;
   double MA4_cur_m15, MA4_prev_m15, MA4_2p_m15, MA5_prev_m15, MA8_cur_m15, MA8_prev_m15, MA8_2p_m15;
   double MA8_cur, MA8_prev, MA8_2p, MA8_3p, MA5_cur, MA5_prev, MA5_2p, MA13_cur, MA13_prev, MA13_2p,  
       MA60_cur, MA60_prev, MA60_2p, MA24_cur_h1;
   double C_prev_h1, O_prev_h1, H_prev_h1, L_prev_h1, H_2p_h1, L_2p_h1;    
   datetime Time_cur, Time_cur_m15; 
   double shift_buy, shift_sell;
   double Max_pos, Min_pos;    
  //--------

   //КОНТРОЛЬ ТЕХНИЧЕСКИХ ПАРАМЕТРОВ (СОСТОЯНИЙ И РАЗРЕШЕНИЙ)- НА СТОРОНЕ БРОКЕРА И СТОРОНЕ КЛИЕНТСКОГО ТЕРМИНАЛА-------------------------------
   
 if(test==false) //проверка:тест или торговля (тест -true, торговля -false)
 {//начало параметров, которые не проверяются при тестировании на исторических данных---
     
    if(IsConnected() == false) //проверка состояния главного соединения клиентского терминала с сервером брокера
    {
     Print("Вх запрещён-откл сервер брокера"); 
     Alert("Вх запрещён-откл сервер брокера");
     return;
    } 
    
    
    if(IsTradeAllowed() == false) //проверка возможности торговать при помощи экспертов (поток брокера, разрешение торговать)
    {
     
     Print("Вх запрещён-несвободен торг поток у брокера,и/или у робота нет разрешения торговать :", IsTradeAllowed()); 
     Alert("Вх запрещён-несвободен торг поток у брокера,и/или у робота нет разрешения торговать :", IsTradeAllowed());
     return;
    } 
    
    
    if( !AccountInfoInteger(ACCOUNT_TRADE_EXPERT) ) //проверка свойств торгового счёта
    {
     Print("Авт торг запрещена для счёта :", AccountInfoInteger(ACCOUNT_LOGIN), "на стороне торг сервера"); 
     Alert("Авт торг запрещена для счёта :", AccountInfoInteger(ACCOUNT_LOGIN), "на стороне торг сервера"); 
     return;
    }
    
    
    if(IsExpertEnabled() == false) //проверка разрешения запуска экспертов в клиентском терминале
    {
     
     Print("Вх запрещён- в терминале клиента у робота нет разрешения торговать :", IsExpertEnabled()); 
     Alert("Вх запрещён- в терминале клиента у робота нет разрешения торговать :", IsExpertEnabled());
     return;
    } 
    
    
   if(IsStopped() == true) //проверка поступления команды завершить выполнение mql4-программы
    {
     Print("Вх запрещён-поступила команда на завершение работы mql4-программы"); 
     Alert("Вх запрещён-поступила команда на завершение работы mql4-программы");
     return;
    } 
    
 } //здесь окончание параметров, которые не проверяются при тестировании на исторических данных
 
 
  //Контроль наличия достаточного количества котировок в терминале по используемому символу---
      
     if(Bars<100)
     {
      Print("недостаточное количество баров на текущем графике");
      return; 
     }
     
  //Контроль установки эксперта на необходимый таймфрейм----
  
    if(Period() != PERIOD_M1)
    {
     Print("эксперт установлен неверно, установите эксперт на тф :", PERIOD_M1);
     Alert("эксперт установлен неверно, установите эксперт на тф :", PERIOD_M1);
     return;
    }
 
  //Контроль установки эксперта на графики нужных финансовых инструментов----
  
   if(Symbol() != "EURUSD" && Symbol() != "USDCHF" && Symbol() != "USDJPY") 
     {
     Print("эксперт уствновлен неверно-несанкционированный фин инструмент"); 
     Alert("эксперт установлен неверно-несанкционированный фин инструмент");
     return;
    } 
    
    //----------
    
    
  //КОНТРОЛЬ ФИНАНСОВЫХ ПАРАМЕТРОВ,СВЯЗАННЫХ С ЛИМИТОМ РИСКА В ЦЕЛОМ ПО ДЕПОЗИТУ КЛИЕНТА-------------------------------
  
  if(kol < 1) //нет ордеров
  {
   if(AccountBalance() <=  NormalizeDouble( (Depo_first*((100 - Percent_risk_depo)/100)), 0))//если ранее превышен лимит риска в целом по депозиту 
    {
     Print("Вх запрещён-ранее достигнут лимит риска=",Percent_risk_depo, " % в целом по депозиту=", Depo_first);
     Alert("Вх запрещён-ранее достигнут лимит риска=",Percent_risk_depo, " % в целом по депозиту=", Depo_first); 
     return;
    }
    
    
   if(AccountFreeMargin() < (1000*Lots)) //если недостаточно залоговых средств,разрешённых для открытия ордеров на текущем счёте
    {
     Print("Недостаточно залоговых средств.Свободная маржа счёта = ",AccountFreeMargin());
     Alert("Недостаточно залоговых средств.Свободная маржа счёта = ",AccountFreeMargin());
     return; //...то выходим
    } 
  }     
        
 //-------------- 
        
         
  //Значения переменных:
 
    L_prev_m15 = iLow(NULL,PERIOD_M15,1);
    L_2p_m15 = iLow(NULL,PERIOD_M15,2);
    L_3p_m15 = iLow(NULL,PERIOD_M15,3);
    H_prev_m15 = iHigh(NULL,PERIOD_M15,1);
    H_2p_m15 = iHigh(NULL,PERIOD_M15,2);
    H_3p_m15 = iHigh(NULL,PERIOD_M15,3);
    
    O_cur_m15 = iOpen(NULL,PERIOD_M15,0);
    O_prev_m15 = iOpen(NULL,PERIOD_M15,1);
    O_2p_m15 = iOpen(NULL,PERIOD_M15,2);
    C_prev_m15 = iClose(NULL,PERIOD_M15,1);
    C_2p_m15 = iClose(NULL,PERIOD_M15,2);
    Time_cur_m15 = iTime(NULL,PERIOD_M15,0);
    
    C_prev_h1 = iClose(NULL,PERIOD_H1,1);
    O_prev_h1 = iOpen(NULL,PERIOD_H1,1);
    H_prev_h1 = iHigh(NULL,PERIOD_H1,1);
    L_prev_h1 = iLow(NULL,PERIOD_H1,1);
    H_2p_h1 = iHigh(NULL,PERIOD_H1,2);
    L_2p_h1 = iLow(NULL,PERIOD_H1,2);
    
    MA4_cur_m15 = iMA(NULL,PERIOD_M15,4,0,MODE_SMA,PRICE_TYPICAL,0);
    MA4_prev_m15 = iMA(NULL,PERIOD_M15,4,0,MODE_SMA,PRICE_TYPICAL,1);
    MA4_2p_m15 = iMA(NULL,PERIOD_M15,4,0,MODE_SMA,PRICE_TYPICAL,2);
    MA5_prev_m15 = iMA(NULL,PERIOD_M15,5,0,MODE_SMA,PRICE_TYPICAL,1);
    MA8_cur_m15 = iMA(NULL,PERIOD_M15,8,0,MODE_SMA,PRICE_TYPICAL,0);
    MA8_prev_m15 = iMA(NULL,PERIOD_M15,8,0,MODE_SMA,PRICE_TYPICAL,1);
    MA8_2p_m15 = iMA(NULL,PERIOD_M15,8,0,MODE_SMA,PRICE_TYPICAL,2);

    MA8_cur = iMA(NULL,PERIOD_M1,8,0,MODE_SMA,PRICE_TYPICAL,0);
    MA8_prev = iMA(NULL,PERIOD_M1,8,0,MODE_SMA,PRICE_TYPICAL,1);
    MA8_2p = iMA(NULL,PERIOD_M1,8,0,MODE_SMA,PRICE_TYPICAL,2);
    MA8_3p = iMA(NULL,PERIOD_M1,8,0,MODE_SMA,PRICE_TYPICAL,3);
    MA5_cur = iMA(NULL,PERIOD_M1,5,0,MODE_SMA,PRICE_TYPICAL,0);
    MA5_prev = iMA(NULL,PERIOD_M1,5,0,MODE_SMA,PRICE_TYPICAL,1);
    MA5_2p = iMA(NULL,PERIOD_M1,5,0,MODE_SMA,PRICE_TYPICAL,2);
    MA13_cur = iMA(NULL,PERIOD_M1,13,0,MODE_SMA,PRICE_TYPICAL,0);
    MA13_prev = iMA(NULL,PERIOD_M1,13,0,MODE_SMA,PRICE_TYPICAL,1);
    MA13_2p = iMA(NULL,PERIOD_M1,13,0,MODE_SMA,PRICE_TYPICAL,2);  
    MA60_cur = iMA(NULL,PERIOD_M1,60,0,MODE_SMA,PRICE_TYPICAL,0);
    MA60_prev = iMA(NULL,PERIOD_M1,60,0,MODE_SMA,PRICE_TYPICAL,1);
    MA60_2p = iMA(NULL,PERIOD_M1,60,0,MODE_SMA,PRICE_TYPICAL,2);
    MA24_cur_h1 = iMA(NULL,PERIOD_H1,24,0,MODE_SMA,PRICE_TYPICAL,0);
    
    kol = OrdersTotal();
    Time_cur = TimeCurrent();
   
 if(kol < 1) //если нет открытых ордеров, то продолжаем
     {
      
 //---АЛГОРИТМ ВХОДВ В РЫНОК - ПОКУПКА (BUY)-------------------------------------------------------------------------------------------
      
  if( 
   //----МИНИМИЗИРУЕМ РИСКИ,СВЯЗАННЫЕ С НАЛИЧИЕМ ЗНАЧИТЕЛЬНОЙ ВЕЛИЧИНЫ ВОЛАТИЛЬНОСТИ К МОМЕНТУ ВХОДА В РЫНОК ----
  
     //Моделируем отсутствие значительной волатильности в ближайшей истории:
     ( High[1] - Low[1]) <= 200*Point &&                       //ограничение амплитуды свечей младшего масштаба (М1)
     ( High[2] - Low[2]) <= 200*Point &&
     ( High[3] - Low[3]) <= 200*Point && 
     (H_prev_m15 - L_prev_m15) <= 300*Point &&                 //ограничение амплитуды свечей старшего масштаба (М15)
     (H_2p_m15 - L_2p_m15) <= 300*Point && 
     (H_3p_m15 - L_3p_m15) <= 300*Point && 
     (H_prev_m15 - L_3p_m15) <= 300*Point &&                   //ограничение амплитуды канала из свечей старшего масштаба (М15)
     (High[1] - Low[1]) >= (1.1*(High[2] - Low[2])) &&         //ограничение активности на предыдущем баре относительно 2-го бара в истории котировок 
     (High[1] - Low[1]) < (3.0*(High[2] - Low[2])) &&          //то же
  
    
   //----МИНИМИЗИРУЕМ РИСКИ,СВЯЗАННЫЕ С НАЛИЧИЕМ УРОВНЕЙ СОПРОТИВЛЕНИЯ ПРИ ВХОДЕ В РЫНОК-----
  
     //Моделируем ситуацию, при которой локальные уровни сопротивления преодолены текущей ценой:
       Bid > High[1] &&           //на М1 
       Bid > H_prev_m15 &&        //на М15 
           
    
   //---МИНИМИЗИРУЕМ РИСКИ,СВЯЗАННЫЕ СО ВХОДОМ В ЗОНЕ ПЕРЕКУПЛЕННОСТИ ПРИ ВХОДЕ В РЫНОК-----
  
    //Моделируем привязку к началу волны, чтобы уменьшить вероятность входа в зоне перекупленности:
     ((MA8_prev > Low[1] && MA8_prev < High[1]) || (MA8_2p > Low[2] && MA8_2p < High[2]) || //начало волны - не далее трёх баров в истории данных (М1)
     (MA8_3p > Low[3] && MA8_3p < High[3])) &&                                              //то же
      MA5_prev_m15 > L_prev_m15 && MA5_prev_m15 < H_prev_m15 &&                             //начало волны - на предыдущем баре старшего таймфрейма (М15)
      
  
  //---МИНИМИЗИРУЕМ РИСКИ,СВЯЗАННЫЕ С ОТСУТСТВИЕМ ВЫРАЖЕННОГО ТРЕНДА ПРИ ВХОДЕ В РЫНОК-------
  
      //Моделируем направление свечей на младшем таймфрейме:
      Close[2] > Open[2] &&      //восходящее направление свечи на 2-м баре в истории данных (М1)
      Close[1] > Open[1] &&      //восходящее направление предыдущей свечи (М1)
      
      //Моделируем направление скользящих средних на младшем таймфрейме:
      MA5_cur > MA5_2p &&  MA60_cur > MA60_2p &&     //восходяшие МА: используем скользящие средние с периодом 5 и 60 (М1)
      
      //Моделируем иерархию скользящих средних на младшем таймфрейме:
      MA5_cur > MA8_cur && MA8_cur > MA13_cur &&     //сформирована "иерархия" трёх МА (периоды Фибоначчи:5,8,13) (косвенный признак восходящего движения) М1
      
      //Моделируем положение текущей цены относительно скользящих средних младшего масштаба:
      Bid > MA5_cur && Bid > MA8_cur && Bid > MA13_cur && Bid > MA60_cur && //текущая цена выше МА (5,8,13,60) (косвенный признак восходящего движения) М1 
      
      //Моделируем направление свечей на старшем таймфрейме:
      C_prev_m15 > O_prev_m15 &&       //восходящее направление предыдущей свечи (М15)
      
      //Моделируем направление скользящей средней на старшем таймфрейме: 
      MA4_cur_m15 > MA4_2p_m15 &&     //восходящая МА с периодом 4 (М15)
      
      //Моделируем иерархию скользящих средних на старшем таймфрейме: 
      MA4_prev_m15 > MA8_prev_m15 &&  //сформирована "иерархия" двух МА (периоды 4 и 8) (косвенный признак восходящего движения) М15
      
      //Моделируем положение текущей цены относительно скользящих средних старших масштабов:
      Bid > MA4_cur_m15 &&            //текущая цена выше МА4 (М15) (косвенный признак восходящего движения) 
      Bid > MA24_cur_h1 &&            //текущая цена выше МА24 (Н1) (косвенный признак восходящего движения)
      
      //Моделирование микротренда внутри текущей свечи младшего таймфрейма, а также точки входа:
      Bid > Open[0] &&               //наличие восходящего движения внутри текущей свечи (М1)
       
     //Моделирование достаточной активности предыдущего процесса в старшем масштабе:
     (C_prev_m15 - O_prev_m15) > (0.5*(H_prev_m15 - L_prev_m15)) &&  //доля "тела" свечи более 50% от величины амплитуды свечи (предыдущая свеча М15)
     (H_prev_m15 - C_prev_m15) < (0.25*(H_prev_m15 - L_prev_m15)) && //ограничение глубины коррекции - менее 25% амплитуды свечи (предыдущая свеча М15)
      H_prev_m15 > H_2p_m15 &&                                       //восходящая тенденция по локальным уровням сопротивления (две свечи М15) 
      O_prev_m15 < H_prev_m15 && O_prev_m15 > L_prev_m15 &&          //наличие тени (предыдущая свеча М15)относительно цены открытия данной свечи
      
     //Моделирование достаточной активности предыдущего процесса в младшем масштабе: 
     (Close[1] - Open[1]) > (0.5*(High[1] - Low[1])) &&              //доля "тела" свечи более 50% от величины амплитуды свечи (предыдущая свеча М1)
     (High[1] - Low[1]) > 70*Point &&                                //предыдущая свеча имеет амплитуду больше пороговой (исключаем явный флэт)
     (High[2] - Close[2]) < (0.25*(High[2] - Low[2])) &&             //ограничение глубины коррекции-менее 20% амплитуды свечи (2-я свеча в истории данных М1)
      High[1] > High[2] &&                                           //восходящая тенденция по локальным уровням сопротивления (две свечи М1)
      Open[1] < High[1] && Open[1] > Low[1] )                        //наличие тени (предыдущая свеча М1)относительно цены открытия данной свечи
      
        {
        //если вышеуказанные условия алгоритма входа Buy выполнены, то формируем ордер на вход Buy:
        sl_buy = NormalizeDouble((Bid-StopLoss*Point),Digits);
        tp_buy = NormalizeDouble((Ask+TakeProfit*Point),Digits);
        
         numb = OrderSend(Symbol(),OP_BUY,Lots,Ask,3,sl_buy,tp_buy,"Reduce_risks",16384,0,Green); 
         
         if(numb > 0)

           {
            if(OrderSelect(numb,SELECT_BY_TICKET,MODE_TRADES))
            {
               Print("Вход Buy : ",OrderOpenPrice());   
            }
           }
         else
            Print("Ошибка при открытии ордера Buy : ",GetLastError());
         return;
        }
        
 //--- АЛГОРИТМ ВХОДА В РЫНОК - ПРОДАЖА (SELL)--------------------------------------------------------------------------------------------------
    
  if( 
     //----МИНИМИЗИРУЕМ РИСКИ, СВЯЗАННЫЕ С НАЛИЧИЕМ ЗНАЧИТЕЛЬНОЙ ВЕЛИЧИНЫ ВОЛАТИЛЬНОСТИ К МОМЕНТУ ВХОДА В РЫНОК ----
  
     //Моделируем отсутствие значительной волатильности в ближайшей истории:
     ( High[1] - Low[1]) <= 200*Point &&                       //ограничение амплитуды свечей младшего масштаба (М1)
     ( High[2] - Low[2]) <= 200*Point &&
     ( High[3] - Low[3]) <= 200*Point && 
     (H_prev_m15 - L_prev_m15) <= 300*Point &&                 //ограничение амплитуды свечей старшего масштаба (М15)
     (H_2p_m15 - L_2p_m15) <= 300*Point && 
     (H_3p_m15 - L_3p_m15) <= 300*Point && 
     (H_prev_m15 - L_3p_m15) <= 300*Point &&                   //ограничение амплитуды канала из свечей старшего масштаба (М15)
     (High[1] - Low[1]) >= (1.1*(High[2] - Low[2])) &&         //ограничение активности на предыдущем баре относительно 2-го бара в истории котировок 
     (High[1] - Low[1]) < (3.0*(High[2] - Low[2])) &&          //то же
  
    
  //----МИНИМИЗИРУЕМ РИСКИ,СВЯЗАННЫЕ С НАЛИЧИЕМ УРОВНЕЙ СОПРОТИВЛЕНИЯ ПРИ ВХОДЕ В РЫНОК-----
  
     //Моделируем ситуацию, при которой локальные уровни сопротивления преодолены текущей ценой:
       Bid < Low[1] &&           //на М1 
       Bid < L_prev_m15 &&       //на М15 
           
    
  //---МИНИМИЗИРУЕМ РИСКИ,СВЯЗАННЫЕ СО ВХОДОМ В ЗОНЕ ПЕРЕПРОДАННОСТИ ПРИ ВХОДЕ В РЫНОК-----
  
    //Моделируем привязку к началу волны, чтобы уменьшить вероятность входа в зоне перепроданности:
     ((MA8_prev > Low[1] && MA8_prev < High[1]) || (MA8_2p > Low[2] && MA8_2p < High[2]) || //начало волны - не далее трёх баров в истории данных (М1)
     (MA8_3p > Low[3] && MA8_3p < High[3])) &&                                              //то же
      MA5_prev_m15 > L_prev_m15 && MA5_prev_m15 < H_prev_m15 &&                             //начало волны - на предыдущем баре старшего таймфрейма (М15)
      
  
  //---МИНИМИЗИРУЕМ РИСКИ,СВЯЗАННЫЕ С ОТСУТСТВИЕМ ВЫРАЖЕННОГО ТРЕНДА ПРИ ВХОДЕ В РЫНОК-------
  
      //Моделируем направление свечей на младшем таймфрейме:
      Close[2] < Open[2] &&      //нисходящее направление свечи на 2-м баре в истории данных (М1)
      Close[1] < Open[1] &&      //нисходящее направление предыдущей свечи (М1)
      
      //Моделируем направление скользящих средних на младшем таймфрейме:
      MA5_cur < MA5_2p &&  MA60_cur < MA60_2p &&     //нисходяшие МА: используем скользящие средние с периодом расчёта 5 и 60 (М1)
      
      //Моделируем иерархию скользящих средних на младшем таймфрейме:
      MA5_cur < MA8_cur && MA8_cur < MA13_cur &&    //сформирована "иерархия" трёх МА (периоды Фибоначчи:5,8,13) (косвенный признак нисходящего движения)М1
      
      //Моделируем положение текущей цены относительно скользящих средних младшего масштаба:
      Bid < MA5_cur && Bid < MA8_cur && Bid < MA13_cur && Bid < MA60_cur && //текущая цена ниже МА (5,8,13,60) (косвенный признак нисходящего движения)М1
      
      //Моделируем направление свечей на старшем таймфрейме:
      C_prev_m15 < O_prev_m15 &&      //нисходящее направление предыдущей свечи (М15)
      
      //Моделируем направление скользящей средней на старшем таймфрейме: 
      MA4_cur_m15 < MA4_2p_m15 &&     //нисходяшая МА с периодом расчёта 4 (М15)
      
      //Моделируем иерархию скользящих средних на старшем таймфрейме: 
      MA4_prev_m15 < MA8_prev_m15 &&  //сформирована "иерархия" двух МА (периоды расчёта 4 и 8) (косвенный признак нисходящего движения)М1
      
      //Моделируем положение текущей цены относительно скользящих средних старших масштабов:
      Bid < MA4_cur_m15 &&            //текущая цена ниже,чем МА4 (М15) (косвенный признак нисходящего движения) 
      Bid < MA24_cur_h1 &&            //текущая цена ниже, чем МА24 (МН1) (косвенный признак нисходящего движения)
      
      //Моделирование микротренда снутри текущей свечи младшего таймфрейма, а также точки входа:
      Bid < Open[0] &&                //наличие нисходящего движения внутри текущей свечи (М1)
       
     //Моделирование достаточной активности предыдущего процесса на старшем таймфрейме:
     (O_prev_m15 - C_prev_m15) > (0.5*(H_prev_m15 - L_prev_m15)) &&  //доля "тела" свечи более 50% от величины амплитуды свечи (предыдущая свеча М15)
     (C_prev_m15 - L_prev_m15) < (0.25*(H_prev_m15 - L_prev_m15)) && //ограничение глубины коррекции-менее 25% амплитуды свечи (предыдущая свеча М15)
      L_prev_m15 < L_2p_m15 &&                                       //нисходящая тенденция по локальным уровням сопротивления (две свечи М15) 
      O_prev_m15 < H_prev_m15 && O_prev_m15 > L_prev_m15 &&          //наличие тени (предыдущая свеча М15)относительно цены открытия данной свечи
      
     //Моделирование достаточной активности предыдущего процесса на младшем таймфрейме: 
     (Open[1] - Close[1]) > (0.5*(High[1] - Low[1])) &&              //доля "тела" свечи более 50% от величины амплитуды свечи (предыдущая свеча М1)
     (High[1] - Low[1]) > 70*Point &&                                //предыдущая свеча имеет амплитуду больше пороговой (исключаем явный флэт)
     (Close[2] - Low[2]) < (0.25*(High[2] - Low[2])) &&              //ограничение глубины коррекции-менее 20% амплитуды свечи (2-я свеча в истории данных М1)
      Low[1] < Low[2] &&                                             //нисходящая тенденция по локальным уровням сопротивления (две свечи М1)
      Open[1] < High[1] && Open[1] > Low[1] )                        //наличие тени (предыдущая свеча М1)относительно цены открытия данной свечи
               
        {
         //если вышеуказанные условия алгоритма входа Buy выполнены, то формируем ордер на вход Sell:
         
         sl_sell = NormalizeDouble((Ask+StopLoss*Point),Digits);
         tp_sell = NormalizeDouble((Bid-TakeProfit*Point),Digits);
         
         numb = OrderSend(Symbol(),OP_SELL,Lots,Bid,3,sl_sell,tp_sell,"Reduce_risks",16384,0,Red);
          
         if(numb > 0)
           {
            
            if(OrderSelect(numb,SELECT_BY_TICKET,MODE_TRADES))
              {
               Print("Вход Sell : ",OrderOpenPrice());
              }
           }
         else
            Print("Ошибка при открытии ордера Sell : ",GetLastError());
        }
      //--- здесь окончание алгоритма входа в рынок (Buy,Sell)
      return;
     }
//--- Проверка открытых ордеров и символа финансового инструмента для подготовки закрытия позиции:  

   for(f=0; f < kol; f++)
     {
      if(!OrderSelect(f,SELECT_BY_POS,MODE_TRADES))
         continue;
      if(OrderType()<=OP_SELL &&   //для проверки типа ордера 
         OrderSymbol()==Symbol())  //проверка символа 
        {
         
         if(OrderType()==OP_BUY) //если тип ордера "Buy", то переходим к закрытию позиции Buy:
           {
            
   //------АЛГОРИТМ ЗАКРЫТИЯ ПОЗИЦИИ BUY------------------------------------------------------------------------------------------------- 
          
         
     //Модуль поиска имещегося максимума цены внутри открытой позиции--------------
         
          //сначала определим дистанцию от текущей точки внутри открытой позиции до точки входа в рынок:
             
             shift_buy = 0; 
      
           if(Time_cur > OrderOpenTime() && OrderOpenTime() > 0)                          //если текущее время далее, чем момент входа...
            { shift_buy = NormalizeDouble( ((Time_cur - OrderOpenTime() ) /60), 0 ); }    //то определяем дистанцию в барах тфМ1 до точки входа
            
          //теперь определим максимум цены после входа в рынок:
          
            Max_pos = 0; 
     
           if(Time_cur > OrderOpenTime() && shift_buy > 0) 
            { Max_pos = NormalizeDouble((High[iHighest(NULL,PERIOD_M1, MODE_HIGH ,(shift_buy + 1), 0)]), Digits);}
           
          //здесь окончание модуля поиска максимума цены внутри открытой позиции--  
          
          //Переходим к закрытию открытой позиции Buy (варианты по логике ИЛИ): 
       
            if( 
            //МИНИМИЗИРУЕМ РИСКИ, СВЯЗАННЫЕ С ОБВАЛАМИ ЦЕН ПОСЛЕ ВХОДА В РЫНОК----------------------
            
              (Bid < Open[0] && (Open[0] - Bid) >= 100*Point && (Time_cur - Time[0]) <= 20)           //условия выхода (в любой зоне) при обвале цен (контрольная точка - цена открытия текущей свечи М1)
                     ||
              (Bid < O_cur_m15 && (O_cur_m15 - Bid) >= 200*Point && (Time_cur - Time_cur_m15) <= 120) //условия выхода (в любой зоне) при обвале цен (контрольная точка - цена открытия текущей свечи М15)
                     ||
              ((Time_cur - OrderOpenTime()) > 60 && Close[1] < Open[1] && 
              (Open[1] - Close[1]) >= 200*Point)                                                      //условия выхода в любой зоне при обвале цен (контрольный параметр - амплитуда предыдущей свечи М1)
                     ||
                     
            //МИНИМИЗИРУЕМ РИСКИ, СВЯЗАННЫЕ С НЕОПРЕДЕЛЁННОСТЬЮ АМПЛИТУДЫ ДВИЖЕНИЯ ЦЕН ПОСЛЕ ВХОДА В РЫНОК-- 
             
              //Контроль величины фиксированной прибыли (на позицию):
              (Bid > OrderOpenPrice() && (Bid - OrderOpenPrice()) >= 100*Point)                       //условия выхода в зоне профита (теневой тейк-профит)
                     ||
                     
             //Контроль величины максимально допустимого отклонения цены 
             //от текущего максимума после входа в рынок:    
             (shift_buy >= 1 &&                                                                          //сдвиг не менее 1 бара от точки входа
             Time_cur > OrderOpenTime() && Max_pos > 0 && OrderOpenTime() > 0 && OrderOpenPrice() > 0 && //есть текущий максимум после входа
             Max_pos > OrderOpenPrice() &&                                                               //текущий максимум находится в зоне профита
             Bid < Max_pos &&                                                                            //есть обратное движениеие цены
             (Max_pos - Bid) >= 200*Point)                                                               //величина обратного отклонения от текущего максимума для выхода из рынка
                    ||
                      
             //Контроль заранее установленного лимита риска (на позицию):     
              (Bid < OrderOpenPrice() && (OrderOpenPrice() - Bid) >= 200*Point)                          //условия выхода в зоне убытка (теневой стоп-лосс)
                    ||
                    
             //Контроль заранее установленного лимита риска (в целом по депозиту):
              (AccountBalance() <=  NormalizeDouble( (Depo_first*((100 - Percent_risk_depo)/100)), 0)) )  //если при текущей торговле превышен лимит риска в целом по депозиту 
   
          
              {
               
               if(!OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet))     //если алгоритм закрытия выполнен, то формируем ордер на закрытие позиции Buy
                  Print("Ошибка закрытия позиции Buy ",GetLastError());    //иначе печатаем ошибку закрытия позиции Buy
               return;
              }
        
           }
           else //иначе переходим к закрытию позиции Sell:
           {
            
           //------АЛГОРИТМ ЗАКРЫТИЯ ПОЗИЦИИ SELL------------------------------------------------------------------------------------
           
           
            //Модуль поиска имещегося максимума цены внутри открытой позиции--------------
         
          //сначала определим дистанцию от текущей точки внутри открытой позиции до точки входа в рынок:
             
             shift_sell = 0; 
      
           if(Time_cur > OrderOpenTime() && OrderOpenTime() > 0)                          //если текущее время далее, чем момент входа...
            { shift_sell = NormalizeDouble( ((Time_cur - OrderOpenTime() ) /60), 0 ); }   //то определяем расст в барах М1 до точки входа
            
          //теперь определим минимум цены после входа в рынок:
          
            Min_pos = 0; 
     
           if(Time_cur > OrderOpenTime() && shift_sell > 0)  
           { Min_pos = NormalizeDouble( (Low[iLowest(NULL,PERIOD_M1, MODE_LOW ,(shift_sell + 1), 0)]), Digits); }
           
          //здесь окончание модуля поиска максимума цены внутри открытой позиции--  
          
          
          //Переходим к закрытию открытой позиции Sell (варианты по логике ИЛИ): 
           
           if( 
            //МИНИМИЗИРУЕМ РИСКИ, СВЯЗАННЫЕ С ОБВАЛАМИ ЦЕН ПОСЛЕ ВХОДА В РЫНОК-----------------
            
              (Bid > Open[0] && (Bid - Open[0]) >= 100*Point && (Time_cur - Time[0]) <= 20)          //условия выхода (в любой зоне) при обвале цен (контрольная точка - цена открытия текущей свечи М1)
                     ||
              (Bid > O_cur_m15 && (Bid - O_cur_m15) >= 200*Point && (Time_cur - Time_cur_m15) <= 120) //условия выхода (в любой зоне) при обвале цен (контрольная точка - цена открытия текущей свечи М15)
                     ||
              ((Time_cur - OrderOpenTime()) > 60 && Close[1] > Open[1] && 
              (Close[1] - Open[1]) >= 200*Point)                                                      //условия выхода в любой зоне при обвале цен (контрольный параметр - амплитуда предыдущей свечи М1)
                     ||
                       
           //МИНИМИЗИРУЕМ РИСКИ, СВЯЗАННЫЕ С НЕОПРЕДЕЛЁННОСТЬЮ АМПЛИТУДЫ ДВИЖЕНИЯ ЦЕН ПОСЛЕ ВХОДА В РЫНОК-- 
             
              //Контроль величины фиксированной прибыли (на позицию):
              (Bid < OrderOpenPrice() && (OrderOpenPrice()- Bid) >= 100*Point)                         //условия выхода в зоне профита (теневой тейк-профит)
                     ||
                     
             //Контроль величины максимально допустимого отклонения цены 
             //от текущего минимума после входа в рынок:      
             (shift_sell >= 1 &&                                                                         //сдвиг не менее 1 бара от точки входа
             Time_cur > OrderOpenTime() && Min_pos > 0 && OrderOpenTime() > 0 && OrderOpenPrice() > 0 && //есть текущий минимум после входа
             Min_pos < OrderOpenPrice() &&                                                               //текущий минимум находится в зоне профита
             Bid > Min_pos &&                                                                            //есть обратное движение цены
             (Bid - Min_pos) >= 200*Point)                                                               //величина обратного отклонения от текущего минимума для выхода из рынка
                    || 
                      
             //Контроль заранее установленного лимита риска (на позицию):     
             (Bid > OrderOpenPrice() && (Bid - OrderOpenPrice()) >= 200*Point)                            //условия выхода в зоне убытка (теневой стоп-лосс)
                    ||
                    
             //Контроль заранее установленного лимита риска (в цело по депозиту):
             (AccountBalance() <=  NormalizeDouble( (Depo_first*((100 - Percent_risk_depo)/100)), 0)) )   //если при текущей торговле превышен лимит риска в целом по депозиту 
   
              {
        
               if(!OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet))     //если алгоритм закрытия выполнен, то формируем ордер на закрытие позиции Sell
                  Print("Ошибка закрытия позиции Sell ",GetLastError());   //иначе печатаем ошибку закрытия позиции Sell
               return;
              }  
          
           }
        }
     }
//---
  }
//-----------------------------------------------------------------------------------------------------------

Рис.12. Пример эксперта, учитывающего некоторые из перечисленных рисков

В структуре представленного кода простого советника учтены некоторые из рассмотренных выше рисков, в нее включены соответствующие модули их минимизации.

Эксперт устанавливается на тфМ1 и был протестирован на исторических данных по следующим инструментам: EURUSD, USDCHF, USDJPY.

Результат тестирования по EURUSD:

test_EURUSD

Рис.13. Результаты теста по EURUSD.

Получен положительный результат — тестирование на исторических данных за полтора года.

Результат теста по USDCHF:

test_USDCHF

Рис.14. Результаты теста по USDCHF.

Получен положительный результат на исторических данных за полтора года. Однако количество входов в рынок недостаточно.

Результат теста по USDJPY:


test_USDJPY

Рис.15. Результаты теста по USDJPY.

Получен положительный результат при тестировании за полтора года.

Теперь оценим значимость каждого вида рисков. Для этого используем следующую методику:

  • за основной параметр возьмем величину чистой прибыли, полученной экспертом;
  • значимость конкретного вида риска будем определять, отключая (отдельно) соответствующий модуль в алгоритме эксперта;
  • чем хуже будет финансовый результат, тем значимее этот вид риска.

В качестве уровня, относительно которого будем определять влияние каждого модуля, используем данные тестирования по паре EURUSD. Рассмотрим график:

segnificance_types_risks

Рис.16.График значимости видов риска на примере рассмотренного ранее эксперта

Обозначения на рис. 16:

  • NetProfit — ось, где показана чистая прибыль торгового эксперта;
  • А - величина чистой прибыли «в собранном виде» (все модули минимизации рисков включены);
  • 1 - отключён модуль по минимизации рисков, связанных с высокой волатильностью к моменту входа в рынок;
  • 2 - отключён модуль по минимизации рисков, связанных с наличием уровней сопротивления при входе в рынок;
  • 3 - отключён модуль по минимизации рисков, связанных с попаданием в зону перекупленности/перепроданности при входе в рынок;
  • 4 - отключён модуль по минимизации рисков, связанных с отсутствием выраженного тренда при входе в рынок (блок моделирования достаточной активности предыдущего процесса);
  • 5 - отключён модуль по минимизации рисков, связанных с отсутствием выраженного тренда при входе в рынок (блоки направления свечей и скользящих средних).

На рисунке видно, что максимальный убыток соответствует точке 4. Результат здесь в несколько раз хуже, чем в других точках графика. Значит, важнейший компонент ТС — модуль, где задаётся активность процесса.

Значит, самый серьезный риск (по крайней мере, применительно к данному торговому эксперту) — риск, связанный с отсутствием выраженного тренда (с отсутствием достаточной активности процесса).

Заключение

Мы классифицировали основные виды рисков — как связанных, так и не связанных с рыночной динамикой. Определили варианты минимизации этих рисков. Показали алгоритмы реализации некоторых из них. Далее рассмотрели программу простого эксперта, которая содержит некоторые из этих алгоритмов. Также протестировали эксперта на трёх финансовых инструментах — EURUSD, USDCHF, USDJPY. Обращаю ваше внимание, что результаты получены без какой-либо оптимизации эксперта. При этом пороговые уровни цен, использованные в программных модулях, я установил исходя из личного опыта.

Кроме того, для использования предложен набор скользящих средних, а также метод определения их набора, основанного на календарной цикличности. Этот метод я применил при разработке модулей минимизации рисков, а также эксперта в целом. Предложен метод, позволяющий в какой-то мере уменьшить вероятность попадания точки входа в зону перекупленности/перепроданности (на основе моделирования начала волнообразного движения).

Получен положительный результат на трёх финансовых инструментах, что в целом подтверждает правильность описанных подходов, как в классификации рисков и способов их минимизации, так и в определении структуры торговой системы, учитывающей эти риски.

Проведённый анализ показал, что наибольшим рискам подвержены те трендовые торговые системы, в которых не моделируется активность процесса. Именно этот фактор в большей степени, чем остальные, отражается на финансовых результатах.

Преимущество приведенного эксперта (и описанного подхода к построению ТС) — отсутствие традиционных индикаторов в алгоритме входа и выхода. Используется только свечной анализ и скользящие средние (причём с ограничениями). Это существенно уменьшает объёмы оптимизации. Здесь она сводится к выбору пороговых уровней, при которых срабатывают соответствующие модули, а также к выбору периодов скользящих средних из имеющегося перечня периодов расчёта (см. раздел «Риски, связанные с некорректным выбором величины периода расчёта индикаторов»).

Недостаток описанного подхода — «зафильтрованность» алгоритма входа, так как рисков (а соответственно, и входных фильтров) может быть достаточно много. Результат — ограниченное количетсво входов в рынок. Однако это частично компенсируется возможностью торговать одновременно на нескольких финансовых инструментах (разумеется, после предварительного тестирования).

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

На примере данного эксперта начинающим разработчикам предоставляется возможность поэкспериментировать, отключая отдельные модули, либо изменяя состав модулей в зависимости от ваших логических решений.

ВНИМАНИЕ! Обращаю ваше внимание на то, что этот эксперт — упрощённая демонстрационная версия, не предназначенная для реальной торговли.

Описанные подходы к минимизации рыночных рисков могут быть полезны при разработке вашей собственной торговой системы.

MQL5-версия советника из данной статьи доступна на странице Reduce_risks
Прикрепленные файлы |
Reduce_risks.mq4 (60.32 KB)
test_EURUSD.png (186.65 KB)
test_USDCHF.png (182.76 KB)
test_USDJPY.png (178.94 KB)
Последние комментарии | Перейти к обсуждению на форуме трейдеров (17)
Rashid Umarov
Rashid Umarov | 9 янв. 2018 в 14:09
Vladimir Karputov:

Код переписан на MQL5 и доступен в КодоБазе: Reduce_risks

Добавил ссылку в саму статью

Vasily Belozerov
Vasily Belozerov | 5 февр. 2018 в 22:39
Вот и я чуть со стула не упал, а мог же свою драгоценную голову повредить, после чтения таких тезисов: "эксперт на основе MACD не успевает отреагировать на резкий обвал цен пары USDCHF" !!! Ну ты брат даешь. Предлагаю в классификацию рисков добавить: - дружба с "горе-программистами". Почему у Вас нет такого раздела?
Aleksandr Masterskikh
Aleksandr Masterskikh | 10 февр. 2018 в 20:10
Vasily Belozerov:
Вот и я чуть со стула не упал, а мог же свою драгоценную голову повредить, после чтения таких тезисов: "эксперт на основе MACD не успевает отреагировать на резкий обвал цен пары USDCHF" !!! Ну ты брат даешь. Предлагаю в классификацию рисков добавить: - дружба с "горе-программистами". Почему у Вас нет такого раздела?

Такой  раздел лучше подойдёт для вашего сервиса, а чтобы не упасть со стула - изучайте индикаторы - MACD -это пример стандартного индикатора, и не более того. А прежде чем неумело иронизировать, вы бы лучше представили миру свои разработки - что-то их не видно. 

DmitryK.Dev
DmitryK.Dev | 9 апр. 2018 в 10:57

Александр, спасибо за статью !

Насколько применим/адаптируем Ваш советник к FORTS ?

Я погонял в режиме тестирования/оптимизации MQL5-версию советника на индексе РТС.

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

Правильно понимаю, что изначально советник "заточен" только под хеджинговую систему ?  

Vasily Belozerov
Vasily Belozerov | 23 мая 2018 в 21:10
Aleksandr Masterskikh:

Такой  раздел лучше подойдёт для вашего сервиса, а чтобы не упасть со стула - изучайте индикаторы - MACD -это пример стандартного индикатора, и не более того. А прежде чем неумело иронизировать, вы бы лучше представили миру свои разработки - что-то их не видно. 

1. Научный подход - это когда выдвигается гипотеза и ее пытаются разрушить. Если она выдерживает нападение, становится аксиомой. Вы выдвинули гипотезу, я пытаюсь ее разрушить. Что не так? Что не по научному?

2. Какие мои разработки? Все уже давным-давно придумано: амплитудно-фазовая демодуляция.

Пользовательский тестер стратегий на основе быстрых математических вычислений Пользовательский тестер стратегий на основе быстрых математических вычислений
Статья описывает создание пользовательского тестера стратегий и своего собственного анализатора прогонов оптимизации. Прочитав ее, вы поймете, как работает режим математических вычислений и механизм так называемых фреймов, как можно подготовить и загрузить свои собственные данные для расчетов и использовать эффективные алгоритмы их сжатия. Также эта статья будет интересна всем, кто интересуется способами хранения пользовательской информации внутри эксперта.
Создаем новую торговую стратегию с использованием технологии разложения входов на индикаторы Создаем новую торговую стратегию с использованием технологии разложения входов на индикаторы
В статье предложена технология, с помощью которой каждый желающий сможет создать свою уникальную торговую стратегию, собрав индивидуальный набор индикаторов, и разработать собственные сигналы для входа в рынок.
Паттерн прорыва канала Паттерн прорыва канала
Как известно, ценовые тренды образуют ценовые каналы. Один из сильных сигналов на изменение тренда — прорыв текущего канала. В этой статье я предлагаю попробовать автоматизировать процесс поиска таких сигналов и посмотреть, действительно ли можно на этом построить свою стратегию торговли.
Торговля по уровням ДиНаполи Торговля по уровням ДиНаполи
В статье рассматривается один из вариантов практической реализации советника для торговли по уровням ДиНаполи при помощи стандартных инструментов MQL5. Протестированы результаты его работы и сделаны выводы.