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

MQLabs: Измерение ускорения цены

Советник PiceAcceleration

Индикатор PriceAcceleration

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

 

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

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

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

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

 

В качестве справки.

Для определения участков роста или падения функции используется расчет значения ее производной в некоторой точке. Значение больше нуля свидетельствует о росте функции, меньше нуля - о падении, а нулевое значение свидетельствует об экстремуме. Тип экстремума (минимум или максимум) определяется по значению производной функции в двух соседних с экстремумом точках. Переход с "+" на "-" указывает на максимум функции, а переход с "-" на "+" указывает на минимум функции.

 

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

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

где period - это заданный период средней скользящей линии.

При периоде средней скользящей, равном 9 баров, величина коэффициента составит 0.2.

Текущее значение цены учитывается в искомой величине с коэффициентом k (0.2). Затем к результату добавляется предыдущее значение средней скользящей линии, умноженное на (1-k):

 

где EMAi - значение средней скользящей линии на текущем баре,

      pricei - цена на текущем баре,

      EMAi-1 - значение средней скользящей линии на предыдущем баре. Когда предыдущего значения нет (начало расчета), берется предыдущая разность цен.

Для расчета ускорения движения цены (т.е. для расчета производной скорости изменения цены) мы вместо цены (pricei) будем использовать разность цен соседних баров (см. рис. 1). Соответственно, итоговым расчетным значением будет не EMA, а ускорение цены - PA (Price Acceleration).

Рис. 1. Разность цен в качестве скорости изменения цены.

В качестве цены бара на рис. 1 принята типичная цена ((High + Low + Close)/3). Поэтому цена позднего бара 1.3021, а раннего - 1.3037. Разность цен выходит отрицательная -  (-0.0016). Если предыдущее значение ускорения цены было равно (-0.0025), то текущее ускорение, согласно формуле (2) будет равно:

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

Рис. 2. Индикатор PriceAcceleration.

Для удобства конечные значения индикатора умножены на 1 000 000. Это значение рассчитано из количества знаков в котировке пары EURUSD после запятой (четыре знака, т.е. для приведения к целому числу нужно умножить на 104). Затем полученное значение увеличивается еще на два порядка, чтобы оперировать процентным уровнем. Поэтому рассчитанное по формуле (3) значение отображалось бы индикатором как 2 320.

 

Торговая система Price Acceleration

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

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

Рис. 3. Первичные и подтверждающие сигналы торговой системы.

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

Профит каждой позиции устанавливается в пунктах или в волатильностях, заданных пользователем параметрами UseTPInPoints, TakeProfit и TPATR.

Для полной ясности сформулируем техническое задание при помощи структуры.

1. Торговая операция "Покупка".

1.1 В момент фиксации пересечения нулевого уровня линией индикатора PriceAcceleration снизу вверх производится попытка установки ордера Buy Stop на уровне пробоя максимума сигнальной свечи (плюс один пункт). При этом учитывается, что ордера Buy-типа открываются по цене Ask. Поэтому к расчетному уровню добавляется спред.

1.2 Уровень Stop Loss устанавливается за минимальной ценой (минус один пункт), которая была достигнута от момента предыдущего пересечения нуля линией индикатора PriceAcceleration до текущего момента. Уровень Take Profit рассчитывается, исходя из заданных пользователем величин (в пунктах или волатильностях от цены открытия).

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

1.4 Если к моменту пересечения ценой уровня сопротивления ордер Buy Stop так и не был установлен, производится открытие рыночного ордера Buy.

1.5 В момент пересечения нулевого уровня линией индикатора PriceAcceleration сверху вниз:

    1.5.1 У существующего рыночного ордера Buy изменяется уровень Stop Loss. Он перемещается за минимум сигнальной свечи (минус один пункт). Если переместить Stop Loss невозможно, то ордер принудительно закрывается в момент пересечения ценой уровня поддержки.

    1.5.2 Если существует ордер Buy Stop, то он удаляется.

2. Торговая операция "Продажа".

2.1 В момент фиксации пересечения нулевого уровня линией индикатора PriceAcceleration сверху вниз производится попытка установки ордера Sell Stop на уровне пробоя минимума сигнальной свечи (минус один пункт).

2.2 Уровень Stop Loss устанавливается за максимальной ценой (плюс пункт и плюс спред, т.к. ордера Sell-типа закрываются по цене Ask), которая была достигнута от момента предыдущего пересечения нуля линией индикатора PriceAcceleration до текущего момента. Уровень Take Profit рассчитывается, исходя из заданных пользователем величин (в пунктах или волатильностях от цены открытия).

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

2.4 Если к моменту пересечения ценой уровня поддержки ордер Sell Stop так и не был установлен, производится открытие рыночного ордера Sell.

2.5 В момент пересечения нулевого уровня линией индикатора PriceAcceleration снизу вверх:

    2.5.1 У существующего рыночного ордера Sell изменяется уровень Stop Loss. Он перемещается за максимум сигнальной свечи (плюс один пункт и плюс спред). Если переместить Stop Loss невозможно, то ордер принудительно закрывается в момент пересечения ценой уровня сопротивления.

    2.5.2 Если существует ордер Sell Stop, то он удаляется.

 

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

Функцией генерации сигнала на этот раз будет являться функция, формирующая уровни сопротивления и поддержки. Соответственно, ее название теперь не GetSignal, а CalcLevels:

 
//+-------------------------------------------------------------------------------------+
//| Расчет значения уровня поддержки и сопротивления                                    |
//+-------------------------------------------------------------------------------------+
void CalcLevels()
{
// - 1 - == Определение состояния рынка =================================================
   double acc1 = iCustom(NULL, 0, "PriceAcceleration", accelerationPeriod, 
                         accelerationPrice, 0, 1);
   double acc2 = iCustom(NULL, 0, "PriceAcceleration", accelerationPeriod, 
                         accelerationPrice, 0, 2);
// - 1 - == Окончание блока =============================================================

// - 2 - == Расчет цены уровня сопротивления ============================================
   if (acc1 > 0 && acc2 < 0)
   {
      g_resistance = High[1] + g_tickSize;
      g_support = 0;
      g_stopLoss = Low[iLowest(NULL, 0, MODE_LOW, GetLastCrossIndex(2), 1)]
                   - g_tickSize;
   }
// - 2 - == Окончание блока =============================================================

// - 3 - == Расчет цены уровня поддержки ================================================
   if (acc1 < 0 && acc2 > 0)
   {
      g_support = Low[1] - g_tickSize;
      g_resistance = 0;
      g_stopLoss = High[iHighest(NULL, 0, MODE_HIGH, GetLastCrossIndex(2), 1)]
                   + g_tickSize + g_spread;
   }
// - 3 - == Окончание блока =============================================================
}

Первый блок функции запрашивает текущие значения линии ускорения цены путем обращения к индикатору PriceAcceleration через функцию iCustom. В переменной acc1 сохраняется значение ускорения на первом баре, а в переменной acc2 - на втором. Переменные accelerationPeriod и accelerationPrice - настроечные параметры эксперта. С их помощью пользователь может настраивать период расчета ускорения цены и фактически используемую цену.

Второй блок функции проверяет условие пересечения уровня нуля линией ускорения снизу вверх. Если пересечение зафиксировано, то линия сопротивления  (глобальная переменная g_resistance) устанавливается активной, а линия поддержки удаляется (глобальная переменная g_support). Расчет уровня Stop Loss будущей позиции осуществляется путем поиска минимальной цены от бара с индексом 1 до бара с индексом, рассчитанным функцией GetLastCrossIndex.

Аналогичным образом работает третий блок функции CalcLevels, определяя пересечение уровня нуля линией ускорения сверху вниз. При этом заполняется переменная g_support и обнуляется переменная g_resistance. Уровень Stop Loss позиции устанавливается выше максимума цены от бара №1 до бара №(GetLastCrossIndex) на один пункт и спред.

Функция GetLastCrossIndex возвращает индекс бара, на котором было обнаружено предыдущее пересечение нулевого уровня линией ускорения:

 
//+-------------------------------------------------------------------------------------+
//| Поиск ближайшего пересечения линии ускорения цены с нулем                           |
//+-------------------------------------------------------------------------------------+
int GetLastCrossIndex(int i)
{
   double acc1 = iCustom(NULL, 0, "PriceAcceleration",// Начальное значение ускорения..
                         accelerationPeriod, accelerationPrice, 0, i);// ..(правый бар)
   for (i++; i < Bars - 2; i++)                    // Идем до конца истории
   {
      double acc2 = iCustom(NULL, 0, "PriceAcceleration", // Следующее значение ускорения
                            accelerationPeriod, accelerationPrice, 0, i);// ..(левый бар)
      if ((acc1 > 0 && acc2 < 0) ||                // Если найдено пересечение нулевого..
          (acc1 < 0 && acc2 > 0))                  // ..уровня снизу вверх или сверху..
         break;                                    // ..вниз, то цикл прерывается
      acc1 = acc2;                                 // Значение левого бара на следующей..
   }                                               // ..итерации становится значением..
                                                   // ..правого бара
   return(i-1);                                    // Вернем индекс бара пересечения
}

Значение аргумента функции i - это индекс бара, с которого начинается поиск пересечения. На этом баре и запрашивается значение индикатора PriceAcceleration. Полученное значение сохраняется в переменной acc1.

Далее производится последовательное обращение к барам, находящимся слева от бара i. Окончание поиска возможно при достижении конца истории или обнаружении пересечения. Значение ускорения на баре, находящемся слева от бара i, сохраняется в переменной acc2. В итоге пара переменных acc1 и acc2 используется точно так же, как и в теле функции CalcLevels, а именно: если переменные имеют различный знак, то обнаружено пересечение. В такие моменты цикл перебора прерывается, а функция возвращает индекс бара пересечения. Если же на текущей итерации цикла пересечение не обнаружено, то значение переменной acc2 копируется в переменную acc1, становясь значением ускорения правого бара, а значение ускорения левого бара вновь рассчитывается и записывается в acc2.

В отличие от большинства экспертов, разработанных в MQLabs, создаваемый советник может оперировать одновременно двумя ордерами. Существование двух ордеров становится возможным при появлении первичного сигнала открытия позиции. Например, при существующем ордере Buy появляется первичный сигнал продажи, что приводит к перемещению уровня Stop Loss позиции на уровень поддержки, а на уровне поддержки устанавливается ордер Sell Stop. По этой причине привычный код функции FindOrders требует изменений:

 
//+-------------------------------------------------------------------------------------+
//| Функция поиска своих ордеров.                                                       |
//+-------------------------------------------------------------------------------------+
void FindOrders()
{
// - 1 - == Инициализация переменных перед поиском ======================================
   int total = OrdersTotal() - 1;
   g_ticketSell = -1; g_ticketBuy = -1;
   g_typeSell = -1; g_typeBuy = -1;
// - 1 - == Окончание блока =============================================================
 
// - 2 - == Непосредственно поиск =======================================================
   for (int i = total; i >= 0; i--)                // Используется весь список ордеров
      if (OrderSelect(i, SELECT_BY_POS))           // Убедимся, что ордер выбран
         if (OrderMagicNumber() == MagicNumber &&  // Ордер открыт экспертом, который
             OrderSymbol() == Symbol())            // ..прикреплен к текущей паре
         {
            if (OrderType() == OP_SELL || OrderType() == OP_SELLSTOP)
            {
               g_ticketSell = OrderTicket();       // Найден ордер Sell-типа
               g_typeSell = OrderType();
            }
            else
            {
               g_ticketBuy = OrderTicket();        // Найден ордер Buy-типа
               g_typeBuy = OrderType();
            }
         } 
// - 2 - == Окончание блока =============================================================
}

В итоге вместо двух переменных g_ticket и g_type появилось четыре глобальных переменных: g_ticketBuy и g_typeBuy, g_ticketSell и g_typeSell. Каждая пара переменных отвечает за свой тип ордеров (Buy или BuyStop, Sell или Sell Stop). При нахождении ордера заполняются соответствующие его типу переменные. Отсутствие ордера заданного типа определяется отрицательным значением любой из соответствующих ему переменных.

Осуществление торговых операций, как обычно, возложено на функцию Trade. Ее вызов происходит сразу после вызова функции FindOrders, что означает правильное содержимое переменных g_ticketXXX и g_typeXXX:

 
//+-------------------------------------------------------------------------------------+
//| Открытие позиций                                                                    |
//+-------------------------------------------------------------------------------------+
bool Trade()
{
   double price = 0, tp = 0;                       // Цена и профит
   int type = -1;                                  // Тип ордера

// - 1 - == Обработка существования уровня сопротивления ================================
   if (g_resistance != 0)                          // Существует сопротивление
      if (!GetLongType(type, price, tp))           // Получим тип, цену и профит..
         return(false);                            // ..открываемого ордера
// - 1 - == Окончание блока =============================================================
           
// - 2 - == Обработка существования уровня сопротивления ================================
   if (g_support != 0)                             // Существует поддержка
      if (!GetShortType(type, price, tp))          // Получим тип, цену и профит..
         return(false);                            // ..открываемого ордера
// - 2 - == Окончание блока =============================================================

// - 3 - == Открытие ордера =============================================================
   if (type >= OP_BUY)
      if (OpenOrderCorrect(type, GetLots(), price, NP(g_stopLoss), tp, false) != 0)
         return(false);
// - 3 - == Окончание блока =============================================================

// - 4 - == Сброс значений ценовых уровней ==============================================
   g_support = 0;
   g_resistance = 0;
// - 4 - == Окончание блока =============================================================

   return(True);    
}

В качестве сигналов на проведение торговых операций в теле функции используется проверка значений глобальных переменных g_resistance и g_support. Если одна из переменных имеет значение, отличное от нуля, то исполняется соответствующая функция (GetLongType или GetShortType), которая заполняет локальные переменные price, type и tp. Кроме формирования значений перечисленных переменных функция выполняет тот перечень сопутствующих операций, который соответствует одной из веток алгоритма ТЗ (операция "Покупка" или операция "Продажа").

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

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

Коды функций GetLongType и GetShortType аналогичны. Поэтому рассмотрим их код на примере только одной функции GetLongType:

 
//+-------------------------------------------------------------------------------------+
//| Проверка необходимости открытия длинной позиции или ордера Buy Stop                 |
//+-------------------------------------------------------------------------------------+
bool GetLongType(int &type, double &price, double &tp)
{
// - 1 - == Проверка существования и закрытие короткой позиции ==========================
   if (g_typeSell == OP_SELL)                      // Существует короткая позиция
   {
      if (Bid >= g_resistance)                     // Цена пробила сопротивление
      {
         if (!CloseDeal(g_ticketSell))             // Закроем позицию
            return(false);                         // При неудаче вернем false
      }
      else                                         // Цена не дошла до сопротивления
         if (!CheckSL(g_ticketSell, g_typeSell,    // Проверка правильности..
                      g_resistance + g_spread))    // ..стоп-приказа
            return(false);                     
   }
// - 1 - == Окончание блока =============================================================

// - 2 - == Проверка существования и удаление ордера Sell Stop ==========================
   if (g_typeSell == OP_SELLSTOP)                  // Существует ордер
      if (!DeleteOrder(g_ticketSell))              // Удаление ордера
         return(false);                            // При неудаче вернем false
// - 2 - == Окончание блока =============================================================

// - 3 - == Проверка существования и коррекция длинной позиции ==========================
   if (g_typeBuy == OP_BUY)                        // Существует длинная позиция
   {
      if (!CheckSL(g_ticketBuy, g_typeBuy, g_stopLoss))// Проверка правильности..
         return(false);                            // ..стоп-приказа
      return(True);                                // В любом случае завершаем функцию
   }
// - 3 - == Окончание блока =============================================================

// - 4 - == Расчет цены открытия и профита позиции или ордера ===========================
   price = NP(g_resistance + g_spread);            // Цена открытия ордера
   type = OP_BUYSTOP;                              // Тип ордера - Buy Stop
   if (price - Ask < g_stopLevel && Ask < price)   // Если цена открытия ордера находится
      return(false);                               // ..слишком близко к текущей цене, то
                                                   // ..уходим
   tp = GetLevel(UseTPInPoints, TakeProfit,        // Расчет уровня профита
                 TPATR, price, 1);   
// - 4 - == Окончание блока =============================================================

// - 5 - == Определение типа устанавливаемого ордера ====================================
   if (Ask >= price)                               // Произошел пробой сопротивления
   {
      price = NP(Ask);                             // Открывается по цене Ask..
      type = OP_BUY;                               // ..рыночный ордер Buy
   }
   
   return(True);
// - 5 - == Окончание блока =============================================================
}

Первый блок функции реализует пункт 2.5.1 технического задания, т.е. в момент появления первичного сигнала покупки производится проверка уровня Stop Loss короткой позиции. Если же уровень сопротивления был преодолен ценой, то позиция и вовсе закрывается. Для закрытия используется функция CloseDeal, известная по другим экспертам MQLabs, а для проверки уровня Stop Loss - функция CheckSL, которая будет рассмотрена ниже.

Блок 2 соответствует пункту 2.5.2 технического задания. Для удаления ордера Sell Stop используется стандартная функция MQLabs - DeleteOrder.

Блок 3 проверяет правильность уровня Stop Loss длинной позиции. Так как кроме такой проверки при наличии ордера Buy других действий не предусматривается, то функция безусловно завершается с отправкой результата успешности выполнения проверки стоп-приказа.

Блок 4 реализует выполнение пунктов 1.1 - 1.1.3 технического задания, производя попытку установки ордера Buy Stop с необходимыми уровнями стоп-приказа и профита.

Блок 5  соответствует пункту 1.4 технического задания. Он вступает в силу, если цена преодолела уровень сопротивления без срабатывания отложенного ордера Buy Stop.

Остальные пункты технического задания (1.5 и 2.1 - 2.4) обрабатываются функцией GetShortType.

Проверка правильности уровня Stop Loss текущей позиции (позиция может быть только одна - Buy или Sell, одновременное существование возможно лишь отложенного ордера и позиции) производится функцией CheckSL:

 
//+-------------------------------------------------------------------------------------+
//| Расчет и проверка стоп-приказа имеющейся позиции                                    |
//+-------------------------------------------------------------------------------------+
bool CheckSL(int ticket, int type, double sl)
{
// - 1 - == Проверка существования позиции ==============================================
   if (type < 0 || type > OP_SELL)                 // Если нет открытой позиции, то..
      return(True);                                // ..уходим
// - 1 - == Окончание блока =============================================================
      
// - 2 - == Определение возможности изменения стоп-приказа позиции ======================
   if (type == OP_BUY)
   {
      if (Bid - sl < g_stopLevel)                  // Проверим возможность установки..
         return(false);                            // ..уровня
   }
   else
      if (sl - Ask < g_stopLevel)                  // Проверим возможность установки..
         return(false);                            // ..уровня
// - 2 - == Окончание блока =============================================================

// - 3 - == Проверка или перемещение уровня стоп-приказа позиции ========================
   if (MoveStopLoss(ticket, sl))                   // При успешном перемещении..
      return(True);                                // ..стоп-приказа вернем этот признак
// - 3 - == Окончание блока =============================================================
           
   return(False);                                  // Неудачное перемещение стоп-приказа
}

Функция сравнивает текущий уровень Stop Loss позиции, имеющей тикет ticket и тип type, со значением sl. При равенстве значений или при успешном изменении уровня Stop Loss, или если указанный ордер не является рыночным, функция возвращает результат true - успешное выполнение. Если же изменить уровень Stop Loss нельзя (из-за ограничений дистанции от цены до него) или в результате операции изменения получена ошибка, функция возвращает результат false - ошибочное выполнение.

Первый блок проверяет принадлежность позиции к типу "рыночный ордер". Если ордер не рыночный, выполнение функции прекращается.

Второй блок проверяет допустимость операции изменения уровня Stop Loss, сравнивая текущую цену с новым уровнем Stop Loss.

Третий блок производит операцию изменения стоп-приказа, вызывая функцию MoveStopLoss, которую рассматривать не будем вследствие ее простоты. Отметим лишь, что функция MoveStopLoss проверяет необходимость модификации уровня Stop Loss ордера и производит модификацию в случае необходимости.

 

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

Советник PriceAcceleration был протестирован на таймфрейме Н1. В качестве диапазона тестирования был выбран исторический период 01.01.2010 - 31.12.2011.

Для каждой валютной пары был подобран свой набор настроечных параметров. Отличия от пары к паре заключались в значениях четырех настроечных параметров: accelerationPeriod, accelerationPrice, TakeProfit и TPATR. Остальные параметры использовались со значениями, принятыми по умолчанию. Результаты тестирования показаны на рис. 4-7.

EURUSD. Значения настроечных параметров: accelerationPeriod = 195, accelerationPrice = 4 (Median Price), TakeProfit = 6 и TPATR = 17. Кривая баланса изменяется достаточно равномерно, показывая уверенный рост, который к концу тестирования становится менее явным. Чистая прибыль  3 101 доллар, максимальная просадка 778 долларов. Фактор восстановления 3.98. Как и в прошлый раз, это наилучший сегодняшний результат.

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

 

USDCHF. Значения настроечных параметров: accelerationPeriod = 180, accelerationPrice = 3 (Low), TakeProfit = 6 и TPATR = 10. Кривая баланса в значительной мере неравномерна: вначале наблюдается очень слабо прослеживаемый рост, который к концу тестирования принимает взрывной характер. Чистая прибыль  2 494 доллара, максимальная просадка 535 долларов. Фактор восстановления 4.66. По значению результат лучше предыдущего, но по совокупности показателей уступает паре EURUSD.

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

 

GBPUSD. Значения настроечных параметров: accelerationPeriod = 95, accelerationPrice = 0 (Close), TakeProfit = 1.5 и TPATR = 30. Кривая баланса выглядит не очень стабильно, проявляя неуверенный рост. Чистая прибыль 1 391 доллар, максимальная просадка 958 долларов. Фактор восстановления 1.45.

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

 

USDJPY. Значения настроечных параметров: accelerationPeriod = 90, accelerationPrice = 2 (High), TakeProfit = 3 и TPATR = 11. Кривая баланса вновь ведет себя неуверенно.  Вряд ли стоит полагаться на подобную благосклонность рынка в дальнейшем. Чистая прибыль 1 168 долларов, максимальная просадка 506 долларов. Фактор восстановления 2.31.

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

 

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

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

Январь 2012

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

2.133335
 
 
X
Loading