Admiral Markets Homepage  


Left Nav Register FAQ FAQ Calendar Search Today's Posts Mark Forums Read Right Nav

Left Container Right Container
 
Old 28-12-2009, 14:10   #1
Scriptong
Senior Member
Scriptong's Avatar
 

Default Утренний флэт

В канун Нового Года, как и полагается, рабочее настроение улетучивается. Направление мыслей при этом тоже соответствующее. У кого-то они греются под жарким солнцем на берегу Индийского океана, у кого-то в заснеженных Альпах стремглав несутся к подножию Монблана. А у кого-то мысли более спокойные. Ведь все можно устроить все по старинке, в семейном кругу спокойно и непринужденно открыть бутылочку "Советского", наслаждаясь теплом и уютом родного дома.

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

Думаю, многие весной-летом нынешнего года слышали о торговой стратегии "Пробой утреннего флэта". Заключается она в построении горизонтального канала по максимумам и минимумам азиатской сессии. Все сделки совершаются при пробитии границ канала с целями, расположенными на популярных уровнях линий Фибоначчи - 161.8, 238.2 и т. д.

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

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

Рис. 1. - Общий вид индикатора MorningFlat_OpenLevel и стратегия торговли на его основе.

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

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

Начало и окончание утреннего флэта может быть изменено и указано с точностью до минут. Это делается при помощи установки нужных значений в параметрах индикатора MorningFlat_OpenLevel:
  • StartHour - час начала диапазона.
  • StartMinute - минуты начала диапазона. Свеча, соответствующая времени StartHour:StartMinute открывает канал.
  • EndHour - час окончания диапазона.
  • EndMinute - минуты окончания диапазона. Свеча, соответствующая времени EndHour:EndMinute является первой, которая не является частью канала утреннего флэта.
Параметр TargetLevel не относится к стратегии. Его индикатор унаследовал от старшего брата - индикатора MorningFlat_V3. Оставлен для удобства пользователей. Вернемся непосредственно к стратегии и опишем ее сигнальную часть в функции GetSignal:
Code:
//+-------------------------------------------------------------------------------------+
//| Расчет границ канала и подсчет баров ниже и выше линии открытия                     |
//+-------------------------------------------------------------------------------------+
void GetSignal()
{
 Signal = 0;
// - 1 - ====================== Получение значений границ канала ========================
 // Бар, соответсвующий началу суток плюс смещение в часах и минутах
 int StartBar = iBarShift(Symbol(), 0, BeginDay+StartHour*3600+StartMinute*60);
 // Бар, соответствующий последнему бару "утреннего флэта"
 int FinishBar = iBarShift(Symbol(), 0, BeginDay+EndHour*3600+EndMinute*60)+1; 
        
 double LowV = Low[iLowest(Symbol(), 0, MODE_LOW, StartBar-FinishBar+1,         // Нижняя
                   FinishBar)];                                         // граница канала
 double HighV = High[iHighest(Symbol(), 0, MODE_HIGH, StartBar-FinishBar+1,
                     FinishBar)];                               // Верхняя граница канала
 double OpenL = Open[StartBar];                                // Цена открытия диапазона
 double CloseL = Close[FinishBar];                             // Цена закрытия диапазона
 OpenAfterFlat = Open[FinishBar-1];                               // Цена открытия сделки
 int AboveBars = 0;                               // Закрытие и открытие свечи выше линии
 int BelowBars = 0;                               // Закрытие и открытие свечи ниже линии
 int CenterBars = 0;              // Закрытие и открытие свечи по разные стороны от линии
 for (int j = StartBar; j >= FinishBar; j--)
   {
    if (Open[j] >= OpenL && Close[j] >= OpenL)   // Подсчет баров, закрывшихся выше линии
      AboveBars++;
     else
      if (Open[j] <= OpenL && Close[j] <= OpenL) // Подсчет баров, закрывшихся ниже линии
        BelowBars++;
       else
        CenterBars++;  
   }
// - 1 - == Окончание блока =============================================================

// - 2 - == Генерация сигнала ===========================================================
 if (CloseL < OpenL && BelowBars > AboveBars+CenterBars)  // Цена закрытия диапазона ниже
            //  цены открытия диапазона и количество баров ниже цены открытия больше, чем
                                                       // количество всех остальных баров
   Signal = 1;                                                            // Открытие BUY
 
 if (CloseL > OpenL && AboveBars > BelowBars+CenterBars)  // Цена закрытия диапазона выше
            //  цены открытия диапазона и количество баров выше цены открытия больше, чем
                                                       // количество всех остальных баров
   Signal = -1;                                                          // Открытие SELL
// - 2 - == Окончание блока =============================================================
 return(True);
}
Первый блок подготавливает данные. Сначала находятся номера баров, которые соответствуют первому и последнему бару, входящих в канал (StartBar и FinishBar). Рассчитываются они путем поиска бара, соответствующего времени открытия дневного бара, к которому добавлено необходимое количество часов и минут. Зная номера начального и конечного баров, не составляет особого труда найти между ними максимальное (HighV) и минимальное (LowV) значение цены. Еще проще находятся цены открытия (OpenL) и закрытия (CloseL) диапазона. Здесь же определяется рекомендуемая цена открытия сделки, которая равна цене открытия свечи, следующей за окончанием формирования утреннего флэта.

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

Второй блок, как обычно, анализирует полученные данные и присваивает флагу Signal нужное значение. Для сигнала BUY требуется, чтобы цена закрытия диапазона была ниже цены открытия (CloseL < OpenL), а количество свечей, принадлежащих нижней части канала, было больше половины всех свечей канала (BelowBars > AboveBars+CenterBars). Для сигнала SELL необходимо, чтобы цена закрытия диапазона была выше цены открытия (CloseL > OpenL), а количество свечей, принадлежащих верхней части канала, было больше половины всех свечей, составляющих канал (AboveBars > BelowBars+CenterBars).

После формирования сигналов открытия и закрытия можно приступать к их непосредственному использованию в функции start:
Code:
//+-------------------------------------------------------------------------------------+
//| Функция START эксперта                                                              |
//+-------------------------------------------------------------------------------------+
int start()
  {
// - 1 -  == Разрешено ли советнику работать? ===========================================
   if (!Activate || FatalError)             // Отключается работа советника, если функция
    return(0);           //  init завершилась с ошибкой  или имела место фатальная ошибка
// - 1 -  == Окончание блока ============================================================
     
// - 2 - == Сбор информации об условиях торговли ========================================
   Spread = ND(MarketInfo(Symbol(), MODE_SPREAD)*Point);                 // текущий спрэд
   StopLevel = ND(MarketInfo(Symbol(), MODE_STOPLEVEL)*Point);  // текущий уровень стопов
// - 2 -  == Окончание блока ============================================================

// - 3 - ==================== Проверка срабатывания сигнала за текущий день =============
   BeginDay = iTime(Symbol(), PERIOD_D1, 0);
   if (LastOpen > BeginDay)
     return(0);
    else
     if (!CheckOpen())
       return(0);
// - 3 -  == Окончание блока ============================================================

// - 4 - =============== Расчет сигнала при окончании флэта =============================
   if (LastChannel < BeginDay && (Hour() > EndHour || 
       (Hour() == EndHour && Minute() > EndMinute)))
     {  
      GetSignal();
      LastChannel = BeginDay;
     } 
// - 4 -  == Окончание блока ============================================================

// - 5 - == Открытие позиций ============================================================
   if (Signal == 1 &&                            // Открытие BUY, если сигнал для покупки
       Bid <= OpenAfterFlat)     //и текущая цена лучше, чем цена открытия самого первого
     {                                            // бара после окончания утреннего флэта
      RefreshRates();
      double SL = ND(IF(StopLoss == 0, 0, Ask - StopLoss*Tick));
      double TP = ND(IF(TakeProfit == 0, 0, Ask + TakeProfit*Tick));
      if (OpenOrderCorrect(OP_BUY, ND(Ask), SL, TP, True) != 0)       // открытие позиции
        return(0);    // если не удалось открыть, то попытка переносится на следующий тик
     }

   if (Signal == -1 &&                          // Открытие SELL, если сигнал для продажи
       Bid >= OpenAfterFlat)     //и текущая цена лучше, чем цена открытия самого первого
     {                                            // бара после окончания утреннего флэта
      RefreshRates();
      SL = ND(IF(StopLoss == 0, 0, Bid + StopLoss*Tick));
      TP = ND(IF(TakeProfit == 0, 0, Bid - TakeProfit*Tick));
      if (OpenOrderCorrect(OP_SELL, ND(Bid), SL, TP, True) != 0)      // открытие позиции
        return(0);    // если не удалось открыть, то попытка переносится на следующий тик
     }
// - 5 -  == Окончание блока ============================================================

   return(0);
  }
Как обычно, начнем рассмотрение функции с третьего блока, так как первые два кочуют из эксперта в эксперт без изменений.

В третьем блоке сперва формируется значение времени открытия текущего дневного бара BeginDay, которое впоследствии также используется в функции GetSignal при подсчете времени начала и окончания диапазона утреннего флэта. Затем сравнивается время открытия последней совершенной сделки и время начала дня. Если последняя сделка была совершена в течение текущего дня, то функция start завершается досрочно. Этим приемом ограничивается до одной количество сделок в день.

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

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

В пятом блоке открываются сделки. Делается это в соответствии со значением флага Signal. Причем в обоих случаях присутствует дополнительное условие (Bid <= OpenAfterFlat или Bid >= OpenAfterFlat). Это условие введено для ситуаций, когда трейдер не успел включить компьютер до времени окончания формирования утреннего флэта. В результате вход в сделку может произойти по худшей цене, чем предполагается в стратегии. Дополнительное условие как раз отслеживает момент возврата цены к нужному значению, на котором и открывается сделка.

Оставшаяся функция CheckOpen довольно компактная:
Code:
//+-------------------------------------------------------------------------------------+
//| Проверка существования позиции и закрытие ее, если наступил следующий день          |
//| Также проверяется время окончания утреннего флэта                                   |
//+-------------------------------------------------------------------------------------+
bool CheckOpen()
{
 if (OrderSelect(LastTicket, SELECT_BY_TICKET) && OrderCloseTime() == 0)
   if (WaitForTradeContext())
     {
      if (OrderType() == OP_BUY)
        double Price = Bid;
       else
        Price = Ask;
      if (!OrderClose(OrderTicket(), OrderLots(), ND(Price), 3))
        return(False);   
     }
 if (Hour() > EndHour || (Hour() == EndHour && Minute() > EndMinute))    
   return(True);
  else
   return(False); 
}
Вначале определяется наличие позиции, открытой в течение предыдущего торгового дня (по условиям функции start CheckOpen будет вызвана только, если нет позиций, открытых в этот же день). Если такая позиция существует, то она будет закрыта. При неудачной попытке закрытия функция вернет False, что не позволит эксперту работать, пока сделка все же не будет закрыта.

Если сделки уже нет, то проверяется окончание формирования утреннего флэта. Только при этом условии CheckOpen вернет True. Иначе результат будет False.

К тестированию эксперта подойдем через оптимизацию входных параметров. Поэтому приведенные на рис. 2 - 5 графики изменения кривых баланса являются уже окончательными результатами подбора параметров. Исторический промежуток выбран для всех пар одинаковый 01.01.2008 - 26.12.2009, равно как и таймфрейм - М15. Отличие составляют лишь значения TakeProfit и StopLoss.

Для валютной пары EURUSD параметр TakeProfit выбран равным 45 пунктам, а StopLoss равен 170 пунктам.

Рис. 2. - График кривой баланса, получаемый при тестировании советника на валютной паре EURUSD.

Чистая прибыль добралась до отметки 1433 доллара, а максимальная просадка до 1169 долларов, что дало фактор восстановления чуть больше единицы (1.23). Прибыль была достигнута за счет доминирования прибыльных сделок над убыточными (68% против 32%). Можно взять на заметку.

Для валютной пары USDCHF наилучшими оказались значения TakeProfit = 15, StopLoss = 95.

Рис. 3. - График кривой баланса, получаемый при тестировании советника на валютной паре USDCHF.

Чистая прибыль не смогла остаться в положительной зоне и составила -30 долларов при максимальной просадке 696 долларов. Поэтому дальнейшее рассмотрение результатов не является интересным.

Валютная пара GBPUSD остановила свой выбор на таких параметрах: TakeProfit = 265, StopLoss = 230. Результат не заставил себя ждать.

Рис. 4. - График кривой баланса, получаемый при тестировании советника на валютной паре GBPUSD.

Чистая прибыль достигла рекордных 7445 долларов при скромной для такого результата максимальной просадке 1164 доллара. Фактор восстановления смог достичь отметки 6.40. В данном случае о доминировании прибыльных сделок над убыточными речь не идет. Хотя небольшой перевес в сторону прибыльных сделок и наблюдается - 56% против 44%. Стабильный вид кривой баланса дает все основания для доверия такой стратегии на GBPUSD.

И, наконец, для USDJPY параметры подобраны такие: TakeProfit = 20, StopLoss = 90.

Рис. 5. - График кривой баланса, получаемый при тестировании советника на валютной паре USDJPY.

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

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


Для поклонников AutoGraf по традиции произведем некоторые изменения в эксперте, чтобы он смог работать под управлением AG. В советнике присутствует четыре очень важных параметра - время начала и окончания действия диапазона утреннего флэта. Они должны быть настраиваемыми. Поэтому необходимо вынести их во внешние переменные AutoGraf. В результате, параметру StartHour будет соответствовать параметр AT_1, параметру StartMinute - AT_2, EndHour - AT_3 и EndMinute - AT_4.

Остальные настройки эксперта (Lots, TakeProfit, StopLoss) доступны в AutoGraf в режиме реального времени и могут быть изменены в любой момент. В итоге для запуска советника из-под AutoGraf 4.0 потребуется проделать следующие шаги:
  • Воспользоваться ссылкой Файлы стратегий для Autograf 4.0 и полученный архив распаковать в папку MT4\experts\libraries.
  • Запустить AutoGraf и во входных параметрах AT_1 - AT_4 указать необходимые значения. Например, для параметров по умолчанию: AT_1 = 0, AT_2 = 0, AT_3 = 8, AT_4 = 0.
  • Для получения похожих с тестами результатов работы выставить объем открываемой позиции (Lots) 0.1, настроить правильные значения SL и TP. Например, для пары GBPUSD установить SL = 230, а TP= 265.
  • Выбрать стратегию №3. Для этого передвинуть вверх значок So и среди названий стратегий найти S3
  • Запустить функцию автоматической торговли, передвинув значок AT в верхнее положение.
На этой мажорной ноте мы и заканчиваем 2009 год. Разработанные в течение последних шести месяцев стратегии могут стать для вас серьезным подспорьем в борьбе с акулами финансовых рынков. Изучайте и пользуйтесь предложенными тактиками. Только при упорном труде успех может заглянуть на вашу улицу.

В заключение поздравляю всех с наступающим Новым Годом. Пусть в Новом Году все ваши планы осуществятся самым наилучшим образом, а удача, здоровье и любовь станут верными спутницами! До новых встреч в Новом Году.

Использование полученного советника рекомендуется только в полуавтоматическом режиме под присмотром трейдера и после всестороннего изучения слабых и сильных сторон стратегии.
Индикатор MorningFlat_OpenLevel
Советник MorningFlat_OpenLevel_Expert
Файлы стратегии для AutoGraf 4.0
Развернутые результаты тестирования эксперта

Last edited by Scriptong; 28-12-2009 at 14:21..
Scriptong is offline   Reply With Quote
Old 09-03-2010, 22:03   #2
simplesimple
Senior Member
 

Default

уважаемый, вот здесь речь идет о пробитии сессии .. в другой статье идет речь о сессионой торговле внутри канала..
http://www.forextrade.ru/mqlabs/30.0...naya-torgovlya

объясните пжлст как вы определяете границы в индикаторе sessionsflat ???
simplesimple is offline   Reply With Quote
Old 10-03-2010, 06:03   #3
Scriptong
Senior Member
Scriptong's Avatar
 

Default

Quote:
Originally Posted by simplesimple View Post
уважаемый, вот здесь речь идет о пробитии сессии .. в другой статье идет речь о сессионой торговле внутри канала..
http://www.forextrade.ru/mqlabs/30.0...naya-torgovlya

объясните пжлст как вы определяете границы в индикаторе sessionsflat ???
Это максимум и минимум за предыдущую сессию.
Scriptong is offline   Reply With Quote
Old 10-03-2010, 12:24   #4
simplesimple
Senior Member
 

Default

ок понятно... в ваших советниках, как сделать чтоб в *комментариях* высвечивал название советника по которой был открыт ордер?? спасибо
simplesimple is offline   Reply With Quote
Old 10-03-2010, 17:53   #5
Scriptong
Senior Member
Scriptong's Avatar
 

Default

Quote:
Originally Posted by simplesimple View Post
ок понятно... в ваших советниках, как сделать чтоб в *комментариях* высвечивал название советника по которой был открыт ордер?? спасибо
Только изменять код советника - вставить соответствующую строку в поле Comment функции OrderSend
Scriptong is offline   Reply With Quote
Old 11-03-2010, 10:24   #6
simplesimple
Senior Member
 

Default

в данном случае конкретнее?
simplesimple is offline   Reply With Quote
Old 11-03-2010, 10:31   #7
Scriptong
Senior Member
Scriptong's Avatar
 

Default

Quote:
Originally Posted by simplesimple View Post
в данном случае конкретнее?
Поясните, что именно "конкретнее"? Если вы хотите, чтобы не вы сами, а кто-то за вас (например, я) внес изменения в советник, то так и говорите. Только четко укажите, какие именно изменения (что советник должен писать, нужно ли это настраивать и т. д.) вас интересуют.

Если вы можете сами это сделать, что-то сделать, то предоставленной мною информации вполне достаточно.
Scriptong is offline   Reply With Quote
Old 11-03-2010, 15:25   #8
simplesimple
Senior Member
 

Default

ок сам я не могу написать... поэтому, нужно чтоб в окне *терминал* там где столбец *комментарий* было написано например *morning flat* если эта позиция открыта по этой стратегии, а не вручную! понимаете когда разные советники + вручную, трудно фильтровать кто когда и как открыл сделку...если не трудно напишите код, чтоб потом вдруг если понадобится вставлять и в другие советники или нереально??
simplesimple is offline   Reply With Quote
Old 11-03-2010, 21:37   #9
Scriptong
Senior Member
Scriptong's Avatar
 

Default

Quote:
Originally Posted by simplesimple View Post
ок сам я не могу написать... поэтому, нужно чтоб в окне *терминал* там где столбец *комментарий* было написано например *morning flat* если эта позиция открыта по этой стратегии, а не вручную! понимаете когда разные советники + вручную, трудно фильтровать кто когда и как открыл сделку...если не трудно напишите код, чтоб потом вдруг если понадобится вставлять и в другие советники или нереально??
Ок, просто внесу необходимые изменения в код советника.

Насчет универсального механизма все не так просто. Показать это можно. Но в любом случае потребуются хотя бы минимальные знания в программировании, чтобы не перепутать различные параметры между собой. Ведь неправильно поставленная запятая может перевернуть все с ног на голову.
Scriptong is offline   Reply With Quote
Old 12-03-2010, 00:32   #10
simplesimple
Senior Member
 

Default

спасибо
на заметку... по индикатору sessions flat (из другой системы)
постоянно виснет терминал при добавлении этого индикатора, причем может работать днем..вечером виснет
.. почему так?
simplesimple is offline   Reply With Quote
Old 12-03-2010, 16:05   #11
Scriptong
Senior Member
Scriptong's Avatar
 

Default

Quote:
Originally Posted by simplesimple View Post
спасибо
на заметку... по индикатору sessions flat (из другой системы)
постоянно виснет терминал при добавлении этого индикатора, причем может работать днем..вечером виснет
.. почему так?
Забыл обновить версию. Первая была с таким глюком.
Attached Files
File Type: zip SessionsFlat.zip (2.3 KB, 42 views)
Scriptong is offline   Reply With Quote
Old 16-03-2010, 16:31   #12
Scriptong
Senior Member
Scriptong's Avatar
 

Default

Quote:
Originally Posted by simplesimple View Post
ок понятно... в ваших советниках, как сделать чтоб в *комментариях* высвечивал название советника по которой был открыт ордер?? спасибо
Во второй версии добавлен параметр Comm. В нем можно указать содержимое поля "Комментарий" ордера. По умолчанию будет отображаться "MorningFlat"
Attached Files
File Type: zip MorningFlat_OpenLevel_V2_Expert.zip (5.0 KB, 47 views)
Scriptong is offline   Reply With Quote
Old 16-03-2010, 22:54   #13
simplesimple
Senior Member
 

Default

сенк ю вери мач скриптонг!
simplesimple is offline   Reply With Quote
Old 22-04-2010, 22:10   #14
simplesimple
Senior Member
 

Default

проблема с выставлением ордеров..поставил например на кросс йены... входит в рынок сразу же?!?! у меня сейчас 23:09
simplesimple is offline   Reply With Quote
Old 26-04-2010, 16:33   #15
Scriptong
Senior Member
Scriptong's Avatar
 

Default

Quote:
Originally Posted by simplesimple View Post
проблема с выставлением ордеров..поставил например на кросс йены... входит в рынок сразу же?!?! у меня сейчас 23:09
Правильно. Утренний флэт в этот день уже прошел, а ордера советником открыты еще не были. При этом цена была лучше той, по которой бы позиция была открыта сразу после утреннего флэта. В советнике не предусмотрено ограничение действия сигнала по времени. Вот если бы время было 00:00:01, то позиция не открылась бы, так как утренний флэт еще не закончен.
Scriptong is offline   Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
Forum Jump


All times are GMT +1. The time now is 15:16.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Admiral Markets