тел.: 8 800 200 86 47|+7 (812) 336 61 11Заказать звонок
Admiral Markets UK Admiral Markets UK Choose your country

MQLabs: Торговля и тестирование на нестандартных таймфреймах

Советник NonStandart_Timeframe

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

 

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

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

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

Засучим рукава, внутренне приготовившись к некоторым неудобствам в работе, и рассмотрим пути создания собственных периодов графиков в среде Meta Trader 4.

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

 

Создание графика нестандартного периода для режима онлайн торговли

Основой для создания графика любого периода является минутный таймфрейм. Отсюда следует, что все производные периоды будут кратны минуте. Создать график с периодом, к примеру, 1 минута 30 секунд, в среде Meta Trader 4 невозможно, т.к. нет данных, дающих большую, чем одна минута, детализацию. Поэтому, перед тем как приступить к созданию нестандартных таймфреймов, следует позаботиться о наличии достаточной минутной истории. О том, как это сделать, читайте в разделах "Тестирование советника" статей "Линии силы быков и медведей" и "Объем сделки и вероятность ее успешности".

Когда минутная история по необходимому финансовому инструменту готова, а ценовой график открыт и выбран период М1, необходимо прикрепить к графику стандартный скрипт period_converter ("Вид" - "Навигатор" или Ctrl+N, раскрыть список "Скрипты", из которого перетащить элемент "period_converter" на активный график). В результате этих действий появится следующее диалоговое окно (см. рис. 1).

Рис. 1. Входные параметры скрипта period_converter.

У скрипта имеется только один входной параметр ExtPeriodMultiplier, при помощи которого пользователь может указать размер желаемого таймфрейма в минутах. Для примера создадим ценовой график с периодом 52 минуты. Нажимаем кнопку "ОК", запуская скрипт. Чтобы определить, что скрипт завершил конвертацию, необходимо заглянуть в журнал экспертов, содержимое которого можно увидеть, открыв вкладку "Эксперты" окна "Терминал" ("Вид" - "Терминал" или Ctrl+T). О завершении конвертации имеющегося набора свечей из периода 1 минута в период 52 минуты будет свидетельствовать следующая запись в журнале (см. рис. 2).

Рис. 2. Завершение конвертации.

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

Для открытия созданного графика необходимо воспользоваться главным меню Meta Trader 4, нажав "Файл", а затем "Открыть автономно". В итоге появится окно со списком доступных ценовых графиков (см. рис. 3).

Рис. 3. Открытие автономного графика.

Далее достаточно выделить мышью строку с созданным ценовым графиком, а затем нажать кнопку "Открыть". Новый график будет отличаться от графиков, использующих стандартный таймфрейм, надписью "offline" (см. рис. 4). Это означает, что он не будет автоматически обновляться с приходом новой котировки. Но, немного понаблюдав за графиком, мы сможем увидеть, что это не так - график реагирует на каждый тик, хотя и с небольшим опозданием. Автоматическое обновление происходит благодаря тому, что мы не отсоединили скрипт period_converter от графика с периодом М1.

Рис. 4. График EURUSD с периодом 52 минуты.

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

Также следует помнить, что при выключении терминала скрипт period_converter автоматически и без уведомлений удаляется с графика М1. Поэтому при следующей загрузке МТ4 нужно позаботиться о повторном подсоединении скрипта, указав правильное значение входного параметра ExtPeriodMultiplier.

 

Тестирование экспертов на нестандартных таймфреймах.

Если верить официальной документации Meta Trader 4, то проверка экспертов в тестере стратегий на нестандартных таймфреймах невозможна. И действительно, выпадающий список "Период" окна "Тестер" ("Вид" - "Тестер стратегий" или Ctrl+R) позволяет выбрать только стандартный таймфрейм. Но это не означает, что тестируемый эксперт ограничен только тем таймфреймом, на котором его запустили. Как и при работе онлайн, советнику доступны другие таймфреймы. В данном случае необходимо просто позаботиться об их наличии. Ведь даже если использовать программное обращение к другому стандартному таймфрейму, по которому нет исторических данных, то эксперт будет получать в ответ только нули.

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

Чтобы продемонстрировать процесс тестирования советника на нестандартном таймфрейме, создадим эксперт, использующий сигналы индикатора CCIWithMA (см. "Как создать индикатор, не обладая навыками программирования"). Основой для создания эксперта послужит шаблон эксперта (см. "Как создать эксперт, не обладая навыками программирования"). Новый эксперт будет носить имя NonStandart_Timeframe.

Среди настроечных параметров эксперта появится пять новых переменных: четыре переменные, при помощи которых пользователь сможет изменять параметры индикатора CCIWithMA, и одна переменная, при помощи которой указывается рабочий таймфрейм эксперта:

 
extern string    A1 = "Объем сделки. Если Lots = 0, то считается в процентах";
extern double    Lots = 0.1;
extern double    PercentOfDepo = 5;
extern string    A2 = "Параметры индикатора";
extern int       CCIPeriod = 20;
extern int       CCIPrice  = 0;
extern int       MAPeriod  = 21;
extern int       MAMethod  = 1;
extern string    A3 = "== Настройка расчета стоп-приказа ===";
extern string    A4 = "True - стоп в пунктах, false - в волатильности";
extern bool      UseSLInPoints = false;
extern string    A5 = "Величина стопа (пункты или волатильности)";
extern double    StopLoss = 5;
extern string    A6 = "Период ATR, если стоп выражен в волатильностях";
extern int       SLATR = 24;
extern string    A7 = "== Настройка расчета профита ===";
extern string    A8 = "True - профит в пунктах, false - в волатильности";
extern bool      UseTPInPoints = false;
extern string    A9 = "Величина профита (пункты или волатильности)";
extern double    TakeProfit = 1;
extern string    A10 = "Период ATR, если профит выражен в волатильностях";
extern int       TPATR = 24;
extern string    A11 = "Таймфрейм в минутах, даже нестандартный";
extern int       WorkTF = 52;
extern string    A12 = "=== Прочие настройки ===";
extern string    OpenOrderSound = "ok.wav";
extern int       MagicNumber = 100352;

Речь выше шла о параметрах: CCIPeriod, CCIPrice, MAPeriod, MAMethod и WorkTF.

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

 
   if (iBars(NULL, WorkTF) <= 0)
   {
      Alert("График инструмента ", Symbol(), " с периодом ", WorkTF,
            " минут не обнаружен!");
      Alert("Откройте график и запустите эксперт заново.");
      return(0);
   }

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

Следующим изменением в коде эксперта будет содержимое функции генерации торгового сигнала GetSignal:

 
//+-------------------------------------------------------------------------------------+
//| Генерация сигналов покупки и продажи                                                |
//+-------------------------------------------------------------------------------------+
void GetSignal()
{
   Signal = 0;
// - 1 - == Получение показаний индикатора ==============================================
   double CCI1 = iCustom(NULL, WorkTF, "CCIWithMA", CCIPeriod, CCIPrice, MAPeriod, 
                         MAMethod, 0, 1);
   double CCI2 = iCustom(NULL, WorkTF, "CCIWithMA", CCIPeriod, CCIPrice, MAPeriod, 
                         MAMethod, 0, 2);
   double MAcci1 = iCustom(NULL, WorkTF, "CCIWithMA", CCIPeriod, CCIPrice, MAPeriod,
                           MAMethod, 1, 1);
   double MAcci2 = iCustom(NULL, WorkTF, "CCIWithMA", CCIPeriod, CCIPrice, MAPeriod,
                           MAMethod, 1, 2);
// - 1 - == Окончание блока =============================================================

// - 2 - == Генерация сигнала покупки ===================================================
   if (CCI1 > MAcci1 && CCI2 < MAcci2)             // Линия CCI пересекла линию МА..
                                                   // ..снизу вверх
      Signal = 1;                                  // Сигнал покупки       
// - 2 - == Окончание блока =============================================================

// - 3 - == Генерация сигнала продажи ===================================================
   if (CCI1 < MAcci1 && CCI2 > MAcci2)             // Линия CCI пересекла линию МА..
                                                   // ..сверху вниз
      Signal = -1;                                 // Сигнал продажи        
// - 3 - == Окончание блока =============================================================
}

В отличие от обычного вызова функции расчета значения пользовательского индикатора iCustom, при котором в качестве второго параметра мы указывали 0 (использовать текущий таймфрейм), теперь передается строго определенное значение - то, которое указал пользователь в качестве рабочего периода графика.

Сигналом покупки для создаваемой стратегии является пересечение линией CCI линии МА снизу вверх, а сигналом продажи - сверху вниз. Факт пересечения двух линий определяется по двум последним значениям линий. Поэтому в первом блоке функции вычисляются значения линий CCI и МА на двух последних барах. Буфер индикатора, содержащий значения индикатора CCI, имеет индекс 0 (предпоследний аргумент при вызове iCustom). Буфер, в котором содержатся значения МА, имеет индекс 1.

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

Значительные изменения затронут еще одну функцию эксперта - start:

 
//+-------------------------------------------------------------------------------------+
//| Функция start эксперта                                                              |
//+-------------------------------------------------------------------------------------+
int start()
{
// - 1 - == Можно ли работать эксперту? =================================================
   if (!Activate || FatalError) return(0);
// - 1 - == Окончание блока =============================================================

// - 2 - == Контроль открытия нового бара ===============================================
   datetime cur_bar_time = iTime(NULL, WorkTF, 0);
   if (cur_bar_time == 0)
   {
      Print("Нет доступной истории для даты/времени ", TimeToStr(TimeCurrent()));
      return(0);
   }
   if (LastBar == cur_bar_time)                    // Если на текущем баре уже были..
      return(0);                                   // ..произведены необходимые действия,
                                                   // ..то прерываем работу до..
                                                   // ..следующего тика
// - 2 - == Окончание блока =============================================================

// - 3 - == Слежение за изменением рыночного окружения ==================================
   if (!IsTesting())
   {
      Tick = MarketInfo(Symbol(), MODE_TICKSIZE);  // минимальный тик    
      Spread = ND(MarketInfo(Symbol(), MODE_SPREAD)*Point);// текущий спред
      StopLevel = ND(MarketInfo(Symbol(), MODE_STOPLEVEL)*Point);//текущий уровень стопов
      FreezeLevel = ND(MarketInfo(Symbol(), MODE_FREEZELEVEL)*Point);// уровень заморозки
   } 
// - 3 - == Окончание блока =============================================================

// - 4 - == Расчет сигналов =============================================================
   if (LastSignal != cur_bar_time)                 // На текущем баре еще не был..
   {                                               // ..произведен расчет сигнала
      GetSignal();                                 // Определяем наличие сигнала
      LastSignal = cur_bar_time;                   // Определение сигнала на текущем баре
   }                                               // ..произведено
// - 4 - == Окончание блока =============================================================
   
// - 5 - == Выполнение торговых операций ================================================
   if (Signal != 0)                                // Если есть сигнал
      if (!Trade()) return(0);                     // Открытие/закрытие позиций
// - 5 - == Окончание блока =============================================================

   LastBar = cur_bar_time;

   return(0);
}

Второй блок функции, как обычно, служит для оптимизации расчетов, не позволяя выполняться последующим трем блокам чаще, чем один раз за один бар. Для этого в предыдущей версии советника мы сравнивали значение переменной LastBar, в которой хранится время открытия бара, соответствующее времени успешного выполнения последних расчетов, со значением Time[0]. В новой версии так делать нельзя, т.к. Time[0] возвращает время открытия бара текущего таймфрейма. При тестировании советника мы не можем в качестве текущего таймфрейма указать нестандартный таймфрейм, потому что его нет в списке доступных. Текущим таймфреймом в этом случае всегда будет М1, т.к. ему кратен любой нестандартный таймфрейм. Поэтому для получения времени открытия бара периода графика М52 необходимо воспользоваться другой функцией - iTime, которая вернет время открытия бара указанного таймфрейма, а не текущего.

Также стоит учесть вариант, при котором история нестандартного таймфрейма может оказаться неполной или пользователь начнет тестирование с такой даты, для которой не сгенерированы данные. В этом случае время открытия нулевого бара будет равно 0. Поэтому результат, который вернула функция iTime, необходимо постоянно проверять. В случае равенства результата нулю нельзя допускать выполнение блоков 3 -5, т.к. это может привести к непредсказуемым последствиям. Для этой цели введена проверка равенства переменной cur_bar_time нулю. При выполнении условия равенства в журнал записывается сообщение об отсутствии истории, и прерывается выполнение функции start.

Дальнейшие проверки значений переменных LastBar и LastSignal имеют дело с переменной cur_bar_time. В итоге лишние обращения к функции iTime не производятся.

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

Проверим работу эксперта в тестере стратегий. Диапазон тестирования выберем 01.01.2010 - 01.10.2011. Валютная пара EURUSD.

 

ВНИМАНИЕ!!! Корректное тестирование эксперта возможно только при использовании периода графика М1.

 

Значения всех настроечных параметров использовались те, которые установлены по умолчанию. Результаты тестирования приведены на рис. 5.

        Рис. 5. Результаты тестирования эксперта NonStandart_Timeframe на валютной паре EURUSD.

Показана чистая прибыль 2 768 долларов при максимальной просадке 593 доллара. Фактор восстановления 4.67. Качество моделирования равно 25% по той причине, что при тестировании использовался минимальный стандартный таймфрейм М1, для которого невозможно получение более высокого качества моделирования.

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

 

Игорь Герасько

Октябрь 2011

Специально для компании Admiral Markets

2.81818
 
 
X
Loading