Скачать MetaTrader 5

Торговый эксперт по книге Б. Вильямса "Новые измерения в биржевой торговле"

8 февраля 2011, 15:05
Alexey Klenov
32
9 129


Введение

В данной статье я расскажу о создании торгового эксперта по книге Б. Вильямса "Новые измерения в биржевой торговле" для платформы MetaTrader 5 на языке MQL5.  Сама стратегия хорошо известна и до сих пор вызывает споры среди трейдеров о ее работоспособности. 

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

Задачи статьи:
  • С использованием принципов ООП (объектно-ориентированного программирования) разработать класс советника, реализующий торговлю по стратегии Б. Вильямса, назовем его C_TS_BW;
  • В классе C_TS_BW по возможности использовать готовые коды из Стандартной библиотеки.
  • Написать советник, использующий класс C_TS_BW;
  • Проверить разработанного эксперта в Тестере стратегий на нескольких инструментах Forex и CFD;
  • Как итог, подтвердить или опровергнуть профпригодность данной стратегии в текущих условиях рынка.


1. Индикаторы

В основе торговой системы лежат сигналы от 4 индикаторов:

  1. Аллигатор;
  2. Фракталы;
  3. Удивительный Осциллятор;
  4. Ускорение/Замедление.

1.1. Аллигатор
Технический индикатор Alligator — это комбинация Линий Баланса (Скользящих Средних, Moving Averages), использующих фрактальную геометрию и нелинейную динамику.

  • Синяя линия (Челюсть Аллигатора) — это Линия Баланса для временного периода, который использовался для построения графика (13-периодное сглаженное скользящее среднее, сдвинутое на 8 баров в будущее);
  • Красная линия (Зубы Аллигатора) — это Линия Баланса для значимого временного периода на порядок ниже (8-периодное сглаженное скользящее среднее, сдвинутое на 5 баров в будущее);
  • Зеленая линия (Губы Аллигатора) — это Линия Баланса для значимого временного периода, который ниже еще на один порядок (5-периодное сглаженное скользящее среднее, сдвинутое на 3 бара в будущее).

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

Когда Челюсть, Зубы и Губы закрыты или переплетены, Аллигатор собирается спать или уже спит. Когда он спит, его голод увеличивается — чем дольше он спит, тем более голодным он будет, когда проснется. Когда он просыпается, первое, что он делает, — это открывает свою Пасть и начинает зевать. Затем он начинает чуять запах пищи: мясо быка или мясо медведя, и начинает за ним охотиться. Когда Аллигатор основательно наестся, он начинает терять интерес к пище-цене (Линии Баланса сходятся) — это время для фиксирования прибыли.

1.2. Фракталы
Все рынки характеризуются тем, что в течение большей части времени цены на них сильно не меняются и лишь в течение небольшого времени (15-30 процентов) наблюдаются трендовые изменения. Наиболее благоприятны для извлечения прибыли периоды, когда цены на рынках изменяются в соответствии с определенным трендом.

Фракталы (Fractals) — это один из 4 индикаторов торговой системы Билла Вильямса, позволяющий обнаруживать дно или вершину. Техническое определение фрактала вверх — это серия из минимум пяти последовательных баров, в которой перед самым высоким максимумом и за ним находятся по два бара с более низкими максимумами. Противоположная конфигурация (серия из пяти баров, в которой перед самым низким минимумом и за ним находятся по два бара с более высокими минимумами) соответствует фракталу вниз. На графике фракталы имеют значения High и Low и отмечены стрелками вверх или вниз.

Сигналы технического индикатора Fractals необходимо отфильтровывать с помощью технического индикатора Аллигатор. Другими словами, не следует заключать сделку на покупку, если фрактал находится ниже Зубов Аллигатора, и не следует заключать сделку на продажу, если фрактал находится выше Зубов Аллигатора. После того, как сигнал фрактала сформирован и имеет силу, что определяется его позицией вне Пасти Аллигатора, он остается сигналом до тех пор, пока не поражается, либо до той поры, пока не возникает более свежий сигнал фрактала.

1.3. AO (Awesome Oscillator)
Технический индикатор Чудесный Осциллятор Билла Вильямса (Awesome Oscillator, AO) — это 34-периодное простое скользящее среднее, построенное по средним точкам баров (H+L)/2, которое вычтено из 5-периодного простого скользящего среднего, построенного по центральным точкам баров (H+L)/2. Он точно говорит нам, что происходит в текущий момент времени с движущей силой рынка.

1.4. AC (Accelerator Oscillator)
Цена — это последний элемент, который изменяется. Прежде чем изменится цена, изменяется движущая сила рынка, а перед тем, как движущая сила изменяет свое направление, ускорение движущей силы должно замедлиться и дойти до нуля. Затем она начинает ускоряться в противоположном направлении до тех пор, пока цена не начнет изменять свое направление.

Технический индикатор Ускорения/Замедления (Accelerator/Decelerator Oscillator, AC) измеряет ускорение и замедление текущей движущей силы. Этот индикатор будет изменять направление перед изменением движущей силы, а она в свою очередь будет изменять свое направление перед изменением цены. Понимание того, что АС является более ранним предупреждающим сигналом, дает очевидные преимущества.


2. Сигналы

В торговой системе, описанной в книге Б. Вильямса "Новые измерения в биржевой торговле", используются сигналы от пяти торговых измерений.

  • Первое измерение: преодоление фрактала за пределами пасти Аллигатора;
  • Второе измерение: сигналы от индикатора AO (Awesome Oscillator);
  • Третье измерение: сигналы от индикатора AC (Accelerator Oscillator);
  • Четвертое измерение: торговля в зонах;
  • Пятое измерение: торговля линией баланса.

Более подробно о сигналах от каждого измерения.


2.1. Описание торговли сигналами первого измерения

Фрактал "А" на покупку не торгуется, т.к. пробитие его ценой происходит ниже линии зубов Аллигатора. Фрактал "В" исполняется и у нас есть открытая позиция на продажу. При исполнении фрактала "С" мы закрываем короткую позицию и уже имеем чистую позицию на покупку. При пробитии фрактала "D" снова переворачиваем позицию с покупки на продажу. Преодоление фрактала "E" на покупку рынок вновь сообщает, что необходим переворот позиции с продажи на покупку. При исполнении сигналов от  фракталов "G" и "J" мы добавляем к открытой позиции на покупку еще по одному контракту.

Торговля сигналами первого измерения

Рисунок 1. Пример торговли сигналами первого измерения

2.2. Описание торговли сигналами второго измерения

От второго измерения реализовано два типа сигналов. Это пересечение нулевой линии индикатора AO (Awesome Oscillator) и сигнал "блюдце". Нумерацию баров примем как в MetaTrader 5, то есть от текущего (нулевого) бара в историю. Проверку сигнала будем производить на нулевом баре.

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

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

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

Торговля сигналов второго измерения

Рисунок 2. Пример торговли сигналами второго измерения


2.3. Описание торговли сигналами третьего измерения

От третьего измерения (индикатор AC, Accelerator Oscillator) есть сигналы на покупку "выше нулевой линии" и "ниже нулевой линии". Для начала ищем паттерн, указанный на рисунке 3. Проверку производим на нулевом баре. Если первый столбец выше нулевой линии, то нам необходим вариант "А", который состоит из двух зеленых и одного красного столбцов гистограммы. Причем неважно положение относительно нулевой линии второго и третьего столбцов.

Если же первый столбец ниже нулевой линии (вариант "В"), то для формирования сигнала на покупку необходимо три зеленых и один красный бар. Здесь также не учитывается положение остальных столбцов относительно нулевой линии. Сигналы на продажу от третьего измерения зеркально аналогичные. За более подробным описанием и примерами лучше обратиться к первоисточнику.

Описание сигналов третьего измерения

Рисунок 3. Пример торговли сигналами третьего измерения.


2.4. Описание торговли сигналами четвертого измерения ("Зональная торговля")

Зеленой зоной называется такой паттерн, когда одному бару на двух индикаторах AO и АС соответствуют зеленые столбцы. Для формирования торгового сигнала необходимо две подряд зеленых зоны и чтобы цена закрытия первого бара была выше цены закрытия второго. Исполнение сразу при открытии нового бара. В оригинале исполнение должно быть ордером по закрытию бара, но такого в MetaTrader 5 не предусмотрено. Бывает ситуация, когда последний тик закрывающегося бара может изменить цвет столбца на АО или АС, и тогда получается, что вход на покупку по сигналу от зеленой зоны был ложным. По этим причинам я использую именно открытие нового бара для покупки.

Также от четвертого измерения есть сигнал переноса стоп приказа на закрытие для позиции Buy. Для этого необходимо пять подряд зеленых зон. Минимальное значение цены первой из зон будет использовано в качестве установки Stop Loss. Если на следующем баре стоп приказ не сработает (после его закрытия), то при открытии нового переносим Stop Loss на минимальную цену предыдущего закрытого бара (по идее должна быть выше, чем стоп приказ), причем не учитываем какого цвета зона на предыдущем баре.

Также используется ограничение на доливку в открытую позицию на покупку по количеству подряд зеленых зон: Б. Вильямс рекомендует 6 или 8. После чего необходимо подождать появление серой (это когда цвета столбцов на АО и АС разные) или красной зон, которые вновь разрешают производить доливки на покупку от зеленой зоны.

Сигнал на продажу формирует "красная зона" - зеркальное отражение зеленой зоны.

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

Описание сигналов четвертого измерения

Рисунок 4. Пример торговли сигналами четвертого измерения


2.5. Описание торговли сигналами пятого измерения

Паттерн "покупка выше линии баланса" при условии, что сейчас находимся в зеленой зоне, формируется двумя барами. Если цена открытия нулевого бара (она же и максимальная цена этого бара в этот момент) ниже, чем первая предыдущая максимальная цена бара (может быть найдена несколько баров назад), то найденная максимальная цена будет ценой на открытие позиции в направлении покупки для зеленой зоны. Для красной или серой зон необходим еще один максимум выше цены для входа в зеленой зоне. Как только его находим (обычно не дальше 10 баров назад и выше зубов Аллигатора [мое дополнение, у автора не нашел сколько нужно баров назад для такого паттерна]), то запоминаем ее как цену для входа в красной или серой зоне в направлении покупки.

Далее уже на каждом новом делаем проверку на предмет превышения текущей ценой найденных цен для открытия по сигналу "покупка выше линии баланса" в условиях зеленой или других (красной и серой) зон.

Описание сигналов пятого измерения

Рисунок 5. Пример торговли сигналами пятого измерения


3. Класс C_TS_BW

3.1. Задачи класса
  • По возможности использовать классы и методы из Стандартной библиотеки;
  • Большие объемы собственных "похожих данных" хранить в структурах;
  • Принимать пользовательские настройки;
  • Получать для анализа необходимое количество рассчитанных данных от индикаторов;
  • При открытии нового бара произвести поиск сигналов от пяти торговых измерений;
  • При поступлении нового тика проверять возможность срабатывания сигнала для открытия позиции;
  • Производить расчет лота; либо фиксированный, либо "пирамидинг" (будет рассказано об этом алгоритме в методе CalcLot данного класса);
  • Разрешать изменять лот из эксперта непосредственно на каждый тип сигнала. Таким способом реализовать пользовательские потребности в алгоритмах управления капиталом;
  • Производить сопровождение стоп приказа у открытой позиции. При необходимости изменять цену Stop Loss, рассчитанной пользователем из советника;
  • Контролировать отправку приказа открытия сделки на сервер и при неудачной попытке производить повторный запрос;
  • Запретить дублирование торговых сигналов (по одному сигналу входить только один раз);
  • Минимизировать количество методов класса, доступных для обращения из советника;
3.2. Реализация класса C_TS_BW
  • ...По возможности использовать классы и методы из Стандартной библиотеки;

Для выполнения этой задачи нужно предварительно подключить необходимые заголовочные файлы из Стандартной библиотеки. Реализует это ниже приведенный код.

#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\HistoryOrderInfo.mqh>

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

CTrade            exp_trade;    // торговые методы из стандартной библиотеки
CSymbolInfo       s_info;       // методы доступа к информации по символу
CPositionInfo     pos_info;     // методы получения информации по торговой позиции
CHistoryOrderInfo h_info;       // методы доступа к истории ордеров 
  • …Большие объемы собственных "похожих данных" хранить в структурах.

В данном классе используется четыре структуры, две из них в закрытой секции private. Это структуры

struct l_signals            // структура сигналов и времени бара, на котором они появились
struct l_trade              // структура времен последних сработанных сигналов 

И две структуры в открытой секции public.

struct  s_input_parametrs   // структура настроечных параметров
struct  s_actual_action     // структура актуальных торговых приказов

Объекты данных типов структур:

l_signals         last_signals;     // сигналы
l_trade           last_trade;       // отработанные сигналы
s_input_parametrs inp_param;        // внутренняя структура принятых настроек
s_input_parametrs inp_param_tmp;    // приемная структура настроек (получает по ссылке при инициализации класса)
s_actual_action   actual_action;    // приказы на сервер

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

  • … принимать пользовательские настройки;

Данная задача реализуется с помощью метода Init из секции public. Параметры для вызова из эксперта:

string Symbol_for_trade             // символ, на котором будет торговать класс
ENUM_TIMEFRAMES Period_for_trade     // период графика символа, на котором будет происходить поиск сигналов и их отработка
s_input_parametrs &inp_param_tmp   // приемная структура настроек класса 

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

  • …получать для анализа необходимое количество рассчитанных данных от индикаторов;

Это под силу методу CopyIndValue из секции private, параметры

int type       // что требуем  (0- Аллигатор, 2 - АО, 3 - АС  )
int countValue // количество данных

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

  • …при открытии нового бара…

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

  • …произвести поиск сигналов от пяти торговых измерений;

На каждое из торговых измерений я завел отдельный метод. Сигналы первого измерения ищет FindSignal_1_dimension.

Параметры вызова:

int type               // направление фрактала для поиска (0- на покупку, 1 на продажу)
double &price_out[]   // в этом массиве после успешного поиска будет цена фрактала 
datetime &time_out[]  // в этом массиве после успешного поиска будет время бара, на котором найден  фрактал.

Анализ второго измерения выполняет метод FindSignal_2_dimension. Параметры вызова:

int type               // направление поиска (0-в направлении покупки, 1-в направлении продажи)
int sub_type         // подтип поиска (0-  сигнал пересечения нулевой линии, 1- сигнал "блюдце")
double &price_out[]   // в этом массиве после успешного поиска будет сигнальная цена 
datetime &time_out[]  // в этом массиве после успешного поиска будет время бара сигнала.

От третьего измерения данные получаем с помощью метода FindSignal_3_dimension с входными/выходными параметрами:

int type              // направление поиска (0-в направлении покупки, 1-в направлении продажи)
int sub_type           // подтип поиска (0-  сигнал по двум одинаковым барам, 1- сигнал "по трем одинаковым барам)
double &price_out[]    // в этом массиве после успешного поиска будет сигнальная цена
datetime &time_out[]   // в этом массиве после успешного поиска будет время бара сигнала.

Обработку четвертого измерения поручено методу FindSignal_4_dimension с входными/выходными параметрами:

int type               // направление поиска (0-в направлении покупки, 1-в направлении продажи)
int sub_type          // что ищем (0- сигналы от зон, 1- тейлинг стоп по пяти подряд зонам одного цвета)
double &price_out[]   // в этом массиве после успешного поиска будет сигнальная цена
datetime &time_out[]  // в этом массиве после успешного поиска будет время бара сигнала.

За пятым измерением наблюдает FindSignal_5_dimension. Параметры у этого метода:

int type               // направление поиска (0-в направлении покупки, 1-в направлении продажи)
int sub_type          // подтип поиска (0-  сигнал по двум барам, 1- сигнал по трем барам)
double &price_out[]   // в этом массиве после успешного поиска будет сигнальная цена
datetime &time_out[]  // в этом массиве после успешного поиска будет время бара сигнала.

Весь поиск сигналов объединяет метод CheckSignal, он не имеет входных параметров и содержит в себе:

  • Копирование данных от индикаторов;
  • Проверку на закрытие позиции (если используется) за какой либо из линий Аллигатора;
  • Сброс актуальных сигналов предыдущего бара;
  • Поиск активных фракталов в обоих направлениях;
  • В зависимости от наличия позиции ищет сигналы от второго по пятое измерение в направлении открытой позиции.

Данный метод объявлен в секции public, его необходимо вызывать из советника.

  • …при поступлении нового тика проверять на возможность срабатывания сигнала для открытия позиции;

В классе реализован метод CheckForTradeSignal, который выполняет поиск возможности входа в позицию по текущей цене. Параметры вызова:

int dimension        // номер измерения (от первого до пятого включительно)
int type            // направление торговли (0- покупка, 1- продажа)
int sub_type         // подтип сигнала из торгового измерения (описано в поиске сигналов)
double &price_out[]  // цена сигнала
datetime &time_out[] // время бара сигнала

Если соблюдены все условия для активации сигнала, то возвращаем true, иначе false.

Проверку возможности отработки всех сигналов объединяет метод CheckActionOnTick, объявленный в секции public, его необходимо вызывать из советника. Параметры на вызов отсутствуют. Каждый успешный сигнал сохраняется в объекте actual_action, впоследствии они будут обрабатываться в методе TradeActualSignals.

  • …производить расчет лота; либо фиксированный, либо "пирамидинг"

Метод CalcLot объявлен в секции public и может вызываться из советника. Он предназначен для расчета лота и последующей модификации переменной Lot, объявленной в секции private данного класса. Параметры вызова:

bool external // для установки внешнего рассчитанного лота необходимо в эту переменную передавать true, 
              // тогда лот будет установлен значением ext_lot. 
              // Внутри класса (расчет лота своими силами) метод вызывается с параметром false.
double ext_lot // внешний размер лота
int type // тип расчета лота 
         //(0- стартовый лот (используем то значение, что было передано при инициализации класса, 
         //-1 переворотный лот (то есть сумма лота текущей позиции и стартового лота), 
         // значения с 5 по 2 используются, если включен режим агрессивной торговли (подразумевается "пирамидинг").
         // В этом режиме: 5 – стартовый,  умноженный на 5, 
         // 4 – стартовый,  умноженный на 4,
         // 3 – стартовый,  умноженный на 3, 
         // 2 – стартовый,  умноженный на 2,
         // 1 - доливочный лот равен стартовому лоту. 

Если с фиксированным лотом более-менее понятно, то о "пирамидинге" расскажу более подробно.

Пусть стартовый лот будет 0.1, тогда, к примеру, открываемся стартовым лотом по сигналу от фрактала за пределами пасти Аллигатора, суммарная позиция 0.1 лота. После чего начинаем анализировать поступающие сигналы от второго по пятое измерения. Как только срабатывает сигнал, доливаемся в открытую позицию 0.5 лотами (стартовый, умноженный на 5), итого имеем общий объем позиции 0.6 лота. При следующем сигнале в направлении открытой позиции доливаемся 0.4 лота, и суммарная позиция будет равна 1.0 лоту.

Следующий сигнал в направлении позиции добавит нам 0.3 лота, и ее объем будет 1.3 лота. Пятая по счету доливка будет производиться 0.2 лотами, и суммарный объем позиции станет 1.5 лота. Последующие доливки в направлении позиции будут происходить только 0.1 лотом.

Данный алгоритм управления капиталом (манименеджмент, ММ) был описан Б. Вильямсом в "Торговом Хаосе". Возможность устанавливать пользовательский лот позволяет реализовать практически любое управление капиталом.

Для правильного определения последовательности ордеров в сделке, я использую разные Magic номера.

Номер

Описание ордера

999

Переворотный ордер.

1000

Стартовый ордер

1001

Доливочный ордер (стартовый Х 1)

1002

Доливочный ордер (стартовый Х 2)

1003

Доливочный ордер (стартовый Х 3)

1004

Доливочный ордер (стартовый Х 4)

1005

Доливочный ордер (стартовый Х 5)


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

  • …Разрешать изменять лот из эксперта непосредственно на каждый тип сигнала.

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

Установка пользовательского лота возможна в советнике после вызова метода CheckActionOnTick и перед вызовом TradeActualSignals. Так как на текущем тике может быть несколько сигналов, ожидающих исполнения, будет отработан только один.

Порядок выполнения сигналов:

  • Закрытие позиции;
  • Исполнение одного из сигналов от фрактала (открытие, доливка, переворот позиции);
  • Сигнал "блюдце";
  • Сигнал "Пересечение нулевой линии";
  • АC "два одинаково - цветных бара";
  • АC "три одинаково - цветных бара";
  • Торговля в зонах;
  • Линия баланса (2-х баровый сигнал);
  • Линия баланса (3-х баровый сигнал);

Поэтому необходимо учитывать данную последовательность при установке "пользовательского" размера лота.

  •  …Производить сопровождение стоп приказа у открытой позиции. При необходимости изменять цену Stop Loss, рассчитанной пользователем из советника.

В описываемом классе реализовано сопровождение стоп цены у позиции методом Trailing Stop, то есть подтягивание Stop Loss только в направлении увеличения прибыли у позиции при срабатывании по этой цене. Имеется пять моделей сопровождения:

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

Пятый вариант установки Stop Loss реализует метод SetStopLoss с единственным параметром double & stoploss. Вызов необходимо производить из советника и перед исполняющим методом TrailingStop, который производит проверку цены для модификации позиции и отправляет запрос на сервер. После успешного выполнения данной процедуры значение внутренней переменной StopLoss сбрасывается в значение -1.

  • ...Контролировать отправку приказа открытия сделки на сервер и при неудачной попытке производить повторный запрос.

Отправку торгового приказа для открытия, закрытия или переворота позиции используется метод bool SendOrder.  Параметры вызова:

ENUM_ORDER_TYPE type   // направление торговой операции
double &price_out[]   // указатель на цену сигнала, после успешного выполнения операции устанавливаем в -1;
datetime &time_out[]  // указатель на время сигнала, после успешного выполнения операции устанавливаем в -1;
string comment         // комментарий для ордера.

Объединяет отработку всех торговых сигналов метод TradeActualSignals. В структуре actual_action хранятся торговые приказы. После успешной отправки на сервер приказа (SendOrder возвращает true) сбрасываем торговый сигнал в структуре actual_action. Торговый сигнал будет активен до тех пор, пока не получим положительный ответ об отправке.

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

  • ...Запретить дублирование торговых сигналов (по одному сигналу входить только один раз);

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

  • Минимизировать количество методов класса, доступных для обращения из советника.

Вот список методов класса, доступных из вызова из советника:

void C_TS_BW();                                      // Конструктор
bool Init(string Symbol_for_trade,
           ENUM_TIMEFRAMES Period_for_trade,
          s_input_parametrs  &inp_param_tmp);       // Инициализация класса
bool NewBar();                                           // Проверка на новый бар на текущем символе\таймфрейме
void CheckSignal();                                 // Поиск сигналов
void CheckActionOnTick();                              // Сбор желаемых действий на текущей тик
void TrailingStop();                                // Подтягивание стопа
void TradeActualSignals();                             // Торговля по актуальным сигналам
void SetStopLoss(double  &stoploss);                  // Прием внешнего стопа
void CalcLot(bool external,double ext_lot,int type); // Расчет лота

Также доступны структуры:

actual_action    // Актуальные торговые приказы для исполнения
inp_param_tmp;   // Приемная структура настроек
                   // (получает данные по ссылке при инициализации класса)


4. Реализация советника с использованием класса C_TS_BW

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

#include <h_TS_BW.mqh>

После чего объявить объект класса C_TS_BW. Пусть будет это expert_TS_BW.

Также потребуется структура настраиваемых параметров вида s_input_parametrs, к примеру, input_parametrs.

Вот описание параметров, объединенных в эту структуру:

input_parametrs.alligator_jaw_period        // Аллигатор: период линии челюстей
input_parametrs.alligator_jaw_shift         // Аллигатор: сдвиг линии челюстей
input_parametrs.alligator_teeth_period      // Аллигатор: период линии зубов
input_parametrs.alligator_teeth_shift       // Аллигатор: сдвиг линии зубов
input_parametrs.alligator_lips_period       // Аллигатор: период линии губ
input_parametrs.alligator_lips_shift        // Аллигатор: сдвиг линии губ
input_parametrs.add_1_dimension              // Разрешить доливку по фракталам
input_parametrs.add_2_dimension_bludce     // Разрешить доливку по сигналу "блюдце (АО)"
input_parametrs.add_2_dimension_cross_zero // Разрешить доливку по сигналу "пересечение нулевой линии (АО)"
input_parametrs.add_3_dimension_use_2_bars // Разрешить доливку по сигналу "покупка выше 0, продажа ниже 0" (АС 2 бара)
input_parametrs.add_3_dimension_use_3_bars // Разрешить доливку по сигналу "покупка ниже 0, продажа выше 0" (АС 3 бара)
input_parametrs.add_4_dimension_zone       // Разрешить доливку по сигналам от красной или зеленой зон
input_parametrs.add_5_dimension             // Разрешить доливку по сигналам от линии баланса
input_parametrs.max_4_dimension_zone       // Максимальное количество подряд баров зон одного цвета 
input_parametrs.trall_4_dimension           // Разрешить тралл по 5 подряд барам зон одного цвета
input_parametrs.agress_trade_mm            // Агрессивный стиль доливания в открытую позицию
input_parametrs.support_position           // Тип сопровождение стопа у позиции
input_parametrs.lot                           // Лот для торговли

В секции OnInit() советника необходимо:

  • Заполнить все необходимые значения структуры input_parametrs данными, которые впоследствии будут переданы в класс.
  • С помощью метода класса Init произвести его инициализацию. Пример:
expert_TS_BW.Init(Symbol(),PERIOD_CURRENT,input_parametrs)

В данном случае советник будет работать на текущем символе/периоде где установлен.

Пример секции советника OnTick():

//   double Sl[1];  
   if(expert_TS_BW.NewBar()) // на графике новый бар 
     {
      expert_TS_BW.CheckSignal();       // поиск сигналов
     }
   expert_TS_BW.CheckActionOnTick();    // проверка необходимых действий на текущем тике
//---******************* начало места внешнего управления лотом, стопом 
//--- пример установки лота для торговли по сигналам от зон

//   if(expert_TS_BW.actual_action.zone_buy || expert_TS_BW.actual_action.zone_sell)
//     {expert_TS_BW.CalcLot(true,0.11,0);}
//--- установка стопа по параболику

//   CopyBuffer(h_parabolic,0,0,1,Sl);
//   if (Sl[0]>0){expert_TS_BW.SetStopLoss(Sl[0]);}
//---*******************конец места внешнего управления лотом, стопом 

   expert_TS_BW.TrailingStop();           // подтягивание стопа (при необходимости)  
   expert_TS_BW.TradeActualSignals();     // торговля актуальных сигналов    

В данном случае примеры внешнего управления стоповой ценой и торговым лотом для исполнения классом закомментированы.


5. Некоторые тесты на истории

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

Для начала проверим эксперт на CFD. Пусть в качестве полигона для тестирования будет часть истории IBM. Система ориентирована на трендовые участки котировок. Я взял первый попавшийся отрезок, где на глаз виден уверенный тренд.

Трендовый участок IBM

Рисунок 6. График IBM

Запустил на этом участке написанного эксперта и вот что получил в виде ордеров.

Результат в виде ордеров

Рисунок 7. Торговые сигналы Билла Вильямса (IBM)

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

Отчет тестера на трендовом участке

Рисунок 8. Результаты тестирования

В целом получили прибыль.

Теперь возьмем затяжной тренд не такого сильного наклона.

Затяжной тренд несильного наклона

Рисунок 9. График котировок IBM (фрагмент 2)

Пусть это будет тот же инструмент и период 13 месяцев (с 2008.12) по (2010.01)

Вот график из тестера:


Отчет тестера за 2009 год

Рисунок 10. Результаты тестирования системы на истории (фрагмент 2)


Скажем так, "не удовлетворительно" или "не оправдал надежды".

Далее хотелось бы проверить работу и на валютных парах.

Пусть будет всем известная пара EURUSD и период графика Н1. Глубина истории 2010 год.

Тест на EURUSD н1 за 2010 год

Рисунок 11. Результаты тестирования системы на истории, EURUSD, H1,  2010

Попробуем на дневных свечках EURUSD за тот же 2010 год.

Отчет тестера выглядит вот так:

Тест  EURUSD агрессивный ММ + закрытие за челюстью D1 2010 год

Рисунок 12. Результаты тестирования системы на истории, EURUSD, D1, 2010


Заключение

Целью данной статьи было рассмотрение тестирование работоспособности одной из общедоступных стратегий Билла Вильямса не только на рынках акций и товарно-сырьевых биржах, но и на рынке Forex. Система "более-менее" работает на дневных графиках EURUSD за последний год, но не приносит прибыли на меньших таймфреймах без попыток оптимизации.

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

Полный код класса можно посмотреть в прикрепленном файле.

Прикрепленные файлы |
h_ts_bw.mqh (65.12 KB)
Последние комментарии | Перейти к обсуждению на форуме трейдеров (32)
Vladimir Karputov
Vladimir Karputov | 13 авг 2017 в 10:51

Ждём автора - пусть внесёт исправления.

Alexey Klenov
Alexey Klenov | 13 авг 2017 в 22:22

Эксперт разрабатывался и соответсвенно была оформлена статья когда про хеджсчета для мт5 даже не смели заикаться.

По этому выбор позиции был реализован по символу.

Vladimir Karputov
Vladimir Karputov | 14 авг 2017 в 07:15
Alexey Klenov:

Эксперт разрабатывался и соответсвенно была оформлена статья когда про хеджсчета для мт5 даже не смели заикаться.

По этому выбор позиции был реализован по символу.


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

Alexey Klenov
Alexey Klenov | 14 авг 2017 в 15:31

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

По мере возможности сделаю это.

natyog
natyog | 23 авг 2017 в 05:42

На счетах netting mode у 2-х брокеров (БКС-Форекс и Робофорекс) при тестировании (настройки и параметры тестирования приложены)

трейлинг стоп по красной линии (история и операции - в приложении) осуществляется по teeth[5] вопреки заявленному в коде эксперта тралу по

teeth[0].

Однако при торговле на демо счете Робофорекса и БКС-Форекс тралится все же по teeth текущего бара.

А вот при реальной торговле у БКС-Форекс  стопы опять "уходят" на teeth[5].

Так не должно быть. 

Универсальная регрессионная модель для прогнозирования рыночной цены Универсальная регрессионная модель для прогнозирования рыночной цены

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

Реализация индикаторов в виде классов на примере Zigzag и ATR Реализация индикаторов в виде классов на примере Zigzag и ATR

Споры о том, какой способ расчета индикаторов является оптимальным, идут постоянно. Где лучше вычислять значения индикатора - в самом индикаторе или встроить всю логику в код самого эксперта, который его использует? В статье рассматривается один из вариантов переноса кода пользовательского индикатора iCustom непосредственно в код эксперта или скрипта с оптимизацией расчетов и моделированием значения prev_calculated.

Как открыть мир C# из MQL5 путем экспорта неуправляемого кода Как открыть мир C# из MQL5 путем экспорта неуправляемого кода

В данной статье я представил различные методы взаимодействия между кодом, написанным на MQL5, и управляемым кодом на C#. Также я подготовил несколько примеров маршалинга структур MQL5 для C# и примеров вызова экспортированных функций DLL в скриптах на MQL5. Приведенные примеры могут служить основой для дальнейших исследований аспектов написания DLL в управляемом коде. Эта статья также открывает двери для использования в MetaTrader 5 множества библиотек, уже реализованных на C#.

Применение псевдошаблонов как альтернатива шаблонов С++ Применение псевдошаблонов как альтернатива шаблонов С++

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