Forextrade

MQLabs: Очень важный день

Советник  MajorDay

Файлы стратегий для AutoGraf 4.0

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

   

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

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

    Использовать "очень важный день" просто - в какую сторону произошло пробитие экстремумов дня, в ту сторону и совершается сделка, которая должна быть закрыта в конце торговой недели (см. Рис. 1)

Рис. 1. - Использование "очень важного дня".

        В качестве "очень важного дня" на рис.1 выступает понедельник. С первыми секундами вторника на уровень максимальной цены понедельника устанавливается отложенный ордер BuyStop, а на уровень минимальной цены - ордер SellStop. При достижении ценой минимума понедельника ордер SellStop превращается в позицию Sell. В этот же момент удаляется противоположный ордер, что гарантирует отсутствие случаев существования встречных позиций.

    Открытая сделка присутствует в рынке до конца недели и закрывается с последними свечами пятницы. Момент закрытия - время открытия одного из последних баров таймфрейма Н1 торговой недели. Рекомендуется производить закрытие с началом последнего торгового часа недели. Котировки большинства валютных пар компании Admiral Markets открывают последний час работы недели в 20:00 по серверному времени.

    Если до конца недели ни один из двух отложенных ордеров так и не сработал, то производится их автоматическое удаление на стороне брокера, т.к. при установке ордера указывается время истечения. Расчет уровней стоп-приказа и профита в стратегии не предусмотрен. Поэтому важнейшим требованием при использовании системы является соблюдение правил управления капиталом: объем средств, используемых при открытии сделки, не должен превышать 5% от размера депозита.

    Советник MajorDay, реализующий описанную тактику торговли, помимо стандартных параметров Lots, OrderOpenSound и MagicNumber, обладает двумя специфическими настроечными параметрами: DayOfTheWeek и FreedayEndHour. При помощи первого параметра пользователь может указать номер дня недели, соответствующего "очень важному дню". Суббота и воскресенье в качестве таких дней указаны быть не могут, т.к. не относятся к рабочим дням. Пятница также исключается из списка по той причине, что следующий за ней рабочий день - понедельник, который относится уже к следующей неделе. В итоге остается лишь четыре рабочих дня, которые можно указать в качестве "очень важных". Понедельнику соответствует число 1, а четвергу - 4.

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

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

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

// - 2 - ================== Обновление информации о настройках сервера ==================
   Spread = ND(MarketInfo(Symbol(), MODE_SPREAD)*Point);                 // текущий спрэд
   StopLevel = ND(MarketInfo(Symbol(), MODE_STOPLEVEL)*Point);  // текущий уровень стопов
// - 2 - ================================ Окончание блока ===============================
        
// - 3 - ============================== Поиск своих ордеров =============================
   FindOrders();     
// - 3 - ================================ Окончание блока ===============================

// - 4 - ================== Установка и удаление ордеров, закрытие сделок ===============
   Trade();                                                    
// - 4 - ================================ Окончание блока ===============================

   return();
}

    Во время исполнения функции start происходит вызов всего двух пользовательских функций: FindOrders и Trade. Причем функция FindOrders была взята из эксперта MorningBreakout, описанного в статье Утренний флэт. Часть 2, и не претерпела никаких изменений. По-другому дела обстоят с функцией Trade:

 
//+-------------------------------------------------------------------------------------+
//| Открытие и модификация рыночных ордеров                                             |
//+-------------------------------------------------------------------------------------+
void Trade()
{
// - 1 - ===== Удаление отложенного ордера при срабатывании противоположного ордера =====
 if (BuyType == OP_BUY && SellType == OP_SELLSTOP)             // Сработал ордер BuyStop,
   if (!DeleteOrder(SellTicket))                                     // удаление SellStop
     return;

 if (SellType == OP_SELL && BuyType == OP_BUYSTOP)                  // Сработал SellStop,
   if (!DeleteOrder(BuyTicket))                                       // удаление BuyStop
     return;
// - 1 - =============================== Окончание блока ================================

// - 2 - ============================= Установка отложенных ордеров =====================
 if (DayOfWeek() == DayOfTheWeek + 1)               // Текущий день следует за сигнальным
   {                            // Необходимо проверить, установлены ли отложенные ордера
   
    // - 2.1 - ======================= Получение расчетных данных =======================
    datetime NowDay = GetTime();  // Время открытия бара, соответсвующего текущим суткам
    double HighV = GetData(MODE_HIGH, 1);                     // Максимум предыдущего дня
    double LowV = GetData(MODE_LOW, 1);                        // Минимум предыдущего дня
    if (NowDay ==  || HighV ==  || LowV == ) return;  // Если при получении каких-либо
                                 // данных произошла ошибка, то функция Trade прерывается
    datetime Exp = NowDay + (5 - DayOfWeek())*PERIOD_D1*60 + FreedayEndHour*3600; // Рас-
                                         // чет даты/времени истечения отложенных ордеров
    if (Exp - TimeCurrent() < 600) return;    // Если до времени истечения осталось менее
                                                // 10 минут, то ордера не устанавливаются
    // - 2.1 - ============================== Окончание блока ===========================

    // - 2.2 - ======================= Установка ордера BuyStop =========================
    if (BuyTime < NowDay)    // Последний ордер BUY был открыт раньше начала текущего дня
      if (BuyType < )                                         // Ордер BUY не существует
        if (OpenOrderCorrect(OP_BUYSTOP, Lots, NP(HighV + Spread + Point), 
                             , , Exp) != )                         // Открытие BuyStop
          return;                    
    // - 2.2 - ============================== Окончание блока ===========================

    // - 2.3 - ======================= Установка ордера SellStop ========================
    if (SellTime < NowDay)  // Последний ордер SELL был открыт раньше начала текущего дня
      if (SellType < )                                       // Ордер SELL не существует
        if (OpenOrderCorrect(OP_SELLSTOP, Lots, NP(LowV - Point),
                             , , Exp) != )                        // Открытие SellStop
          return;                    
    // - 2.2 - ============================== Окончание блока ===========================
   }
// - 2 - =============================== Окончание блока ================================

// - 3 - ============================= Закрытие сделок в конце недели ===================
 if ((DayOfWeek() == 5 && Hour() >= FreedayEndHour) ||                // Пятница, "вечер"
     DayOfWeek() < 2)           // Или начало следующей недели - понедельник, воскресенье
   {
    if (BuyType == OP_BUY)                           // Если существует BUY, то закрываем
      CloseOrder(BuyTicket);
    if (SellType == OP_SELL)                        // Если существует SELL, то закрываем
      CloseOrder(SellTicket);  
   }          
// - 3 - =============================== Окончание блока ================================
 
 return;    
}

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

      Задачу слежения за срабатыванием одного из отложенных ордеров выполняет первый блок функции. Определение момента превращения отложенного ордера в позицию производится путем проверки типов имеющихся ордеров советника, которые отражены в переменных BuyType и SellType. Если значение BuyType равно OP_BUY, а значение SellType равно OP_SELLSTOP, то обнаружено срабатывание ордера BuyStop. Следующим действием является удаление ордера SellStop, что производится при помощи вызова функции DeleteOrder, заимствованной из советника WorthyFractal (Достойный фрактал). Аналогичные действия производятся при нахождении сочетания: BuyType равно OP_BUYSTOP и SellType равно OP_SELL. В этом случае удалению подлежит ордер BuyStop.

     Второй блок производит установку двух отложенных ордеров в начале суток, следующих за днем недели, который указан в качестве "очень важного дня". Если наступило время для установки ордеров, то исполняется вложенный блок 2.1. Здесь определяется время начала текущего торгового дня NowDay, рассчитываются максимум и минимум предыдущего дня (HighV и LowV), а также время истечения устанавливаемых ордеров Exp. Определение значения NowDay производится при помощи вызова пользовательской функции GetTime, которая обеспечивает корректное обращение к данным таймфрейма D1. Значения HighV и LowV также рассчитываются при помощи вызова пользовательской функции GetData, которая лишь в деталях отличается от одноименной функции советника PairsDependence (Зависимость в движении валютных пар. Часть 2). В случае если не удалось получить нужные данные (соответствующее значение равно нулю), выполнение функции Trade досрочно прерывается.

     Во вложенном блоке 2.2 происходит проверка существования ордера Buy-типа (Buy или BuyStop). При этом учитывается, что ордер (сделка) мог быть удален (закрыта) пользователем. Если ни того, ни другого события не наступало, то ордер BuyStop будет установлен. Аналогичным образом функционирует вложенный блок 2.3, где производится установка ордера SellStop.

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

      Все три задачи функции Trade решены. Белым пятном остается функция GetTime, вызов которой использован в блоке 2.1 для получения времени начала торгового дня. Она во многом похожа на функцию GetData:

 
//+-------------------------------------------------------------------------------------+
//| Получение времени открытия дня Num                                                  |
//+-------------------------------------------------------------------------------------+
datetime GetTime(int Num)
{
 datetime Res;                                            // Результат вычисления функции
 int P = ;                                                 // Счетчик обращения к данным
 while (P < 120)                                     // Обращение не более 120 раз подряд
   {
    Res = iTime(NULL, PERIOD_D1, Num);
    if (GetLastError() != 4066) break;//Ошибка 4066 свидетельствует о неготовности данных
    Sleep(1000);                  // Пауза 1 сек. для того чтобы данные успели обновиться
    P++;                                                           // Увеличение счетчика
   }
 if (P == 120)       // Если выход из цикла по причине переполнения счетчика (долго ждали)
   return();        // то функция вернет ошибку
 return(Res);        // Если же цикл прерывался успешным получением значения, то функция
                     // вернет Res
}

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

    Судить о корректности данных можно только после проверки кода последней ошибки. Код ошибки 4066 соответствует сообщению: "Запрошенные исторические данные в состоянии обновления". После получения такого сообщения необходимо дождаться завершения обновления данных. В функции GetTime используется пауза в 1 сек, после чего запрос повторяется. Если суммарное время ожидания превысило 2 минуты, то функция GetTime возвращает нулевое значение, что соответствует ошибке. При успешном получении времени открытия дня возвращаемое значение не будет равно нулю.

Тестирование советника

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

    Специфика стратегии предполагает низкую частоту совершения сделок - максимум одна сделка в неделю. Поэтому для получения репрезентативной выборки требуется использование достаточно протяженного исторического периода. В данном случае хватило интервала в 4.5 года: 01.01.2006 - 25.08.2010.

     Различие в значениях входных параметров при тестировании на отличных друг от друга валютных парах в этот раз сведено к минимуму. Три из четырех валютных пар показали достойные результаты при использовании в качестве "очень важного дня" четверга (DayOfTheWeek = 4). Одна валютная пара (USDJPY) показала хорошие результаты после признания понедельника "очень важным днем" (DayOfTheWeek = 1). Время закрытия сделок в пятницу для всех валютных пар одинаково - 20:00 (FreedayEndHour = 20).

 

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

EURUSD. Вид кривой баланса нельзя отнести к стабильным, беспокоит лишь малый угол наклона, относящийся к первым 120-ти сделкам. Затем ситуация улучшилась, но вновь вернулась в свое русло после 170-ой сделки. Беспокоит тот факт, что наибольшая просадка была зафиксирована как раз в период прекращения роста, который очень близок к текущей дате. С другой стороны, судя по статистическим данным, все не так уж плохо: чистая прибыль 2656 долларов, максимальная просадка 894 доллара, фактор восстановления 2.97.

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

                Рис. 3. - Результаты тестирования эксперта MajorDay на валютной паре USDCHF.

USDCHF. По сравнению с EURUSD, франк показал больший угол наклона кривой баланса. Также имеет значение, что рост кривой более равномерен, а форма близка к наклонной прямой. Фактором, вызывающим беспокойство, является некоторый сбой в равномерном течении теста, проявляющийся после 160-ой сделки. Не удивительно, что статистические показатели франка немного лучше, чем у евро: чистая прибыль 2374 доллара, максимальная просадка 724 долларов, фактор восстановления 3.28.

Для реального использования советника на валютной паре USDCHF потребуется минимальный депозит 2200 долларов (объем сделок 0.1 лота). Потенциальная годовая доходность при этом составит 23%, что не намного выше банковской ставки. Поэтому и в данном случае "игра не стоит свеч".

                      Рис. 4. Результаты тестирования эксперта MajorDay на валютной паре GBPUSD.

GBPUSD. Кривая баланса оставляет двоякое впечатление. С одной стороны, рост можно назвать равномерным, в нем отсутствует "сбой" конечного этапа тестирования, который был характерен для предыдущих двух валютных пар. С другой стороны, кривая не блещет стабильностью, допуская довольно ощутимые впадины, что не преминуло отразиться на статистических показателях: чистая прибыль 3243 доллара, максимальная просадка 1266 долларов, фактор восстановления 2.56.

Приходится констатировать, что и в данном случае о получении значительных дивидендов при реальном использовании стратегии речь не идет. Так, минимальный депозит для работы на валютной паре GBPUSD составляет 3800 долларов (0.1 лот) с потенциальной доходностью 18% годовых.

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

USDJPY.  Рост кривой баланса равномерностью не отличается. Стабильностью  кривая также похвастать не может. Радует лишь отсутствие значительного спада в конце тестирования и высокий угол наклона кривой после 60-ой сделки, что привело к формированию таких показателей: чистая прибыль 4079 долларов, максимальная просадка 1354 доллара, фактор восстановления 3.01.

Вновь нельзя посоветовать реальное применение советника на валютной паре USDJPY. Минимальный депозит для торговли объемом 0.1 лот потребуется в размере 4100 долларов. При этом потенциальная годовая доходность составляет 21%.

 Доработка стратегии для использования в AutoGraf 4.0

    Стратегия "Очень важный день" в среде AutoGraf обладает двумя настроечными параметрами - DayOfTheWeek и FreedayEndHour. Им соответствуют переменные AT_1 и AT_2, установку значения которых можно произвести в закладке "Входные параметры" при запуске приложения AutoGraf (если перенести эксперт AG_exp на график вручную, а не активировать приложение при помощи шаблона).

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

         Запуск стратегии "Очень важный день" в среде AutoGraf 4.0 состоит из следующих шагов:

  • Получить файл по ссылке Файлы стратегий для AutoGraf 4.0 и распаковать полученный архив в папку MT4\experts\libraries (с перезаписью файлов AG_AT.ex4 и AG_AT.mq4).

  •  Запустить AutoGraf.

  •  Для работы стратегии в ключе приведенных результатов в окне настроек AutoGraf (закладка "Входные параметры") установить нужные значения параметров AT_1 (например, 4) и AT_2 (например, 20). Полное повторение результатов при этом не гарантируется.

  • Выбрать стратегию №5. Для этого необходимо передвинуть вверх значок So и среди названий стратегий найти значок S5, который также потянуть вверх.

  • Запустить функцию автоматической торговли, передвинув значок AT в верхнее положение.

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

 

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

Август 2010

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

2.142855
 
 

Пред.: MQLabs: Зависимость в движении валютных пар. Часть 2.
След.: MQLabs: Летучая мышь. Часть 2.

Комментарии

Отправить комментарий

Содержание этого поля является приватным и не предназначено к показу.
CAPTCHA
Проверка на СПАМ:
  _               _____   ____        _   _____   _  _   
| | __ _ | ___| | ___| | | |___ | | || |
| | / _` | | |_ |___ \ _ | | / / | || |_
| |___ | (_| | | _| ___) | | |_| | / / |__ _|
|_____| \__, | |_| |____/ \___/ /_/ |_|
|___/
Enter the code depicted in ASCII art style.
Общие вопросы
info@forextrade.ru
Техническая поддержка
support@fxservice.com
Необходимые файлы и документы
Филиальная сеть
Условия перепечатки материалов с сайта
Уведомление о рисках
Карта сайта
Политика конфиденциальности
Мы принимаем Webmoney Мы принимаем Webmoney
iPhone iTrader Android Trader BlackBerry Trader MetaTrader для мобильных устройств MetaTrader Web Trader iPad iTrader