Вход в кабинет трейдера

Логин/E-mail *
Пароль *
 
Компания Трейдеру Обучение Аналитика Справка ForexBall™ Admiral Club™ MQLabs™ Форум

Статьи MQLabs™

Диверсификация рисков

Советник SimpleMACross

Советник SimpleMACross_Reverse

Советник SimpleMACrossDouble

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

       

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

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

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

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

        Более подробно рассмотрим суть сказанного на простейшей стратегии пересечения двух скользящих средних. Всем известен недостаток этого метода торговли: большое запаздывание при входе и выходе из сделки. Достоинством стратегии является ведение торговли "по тренду", что позволяет трейдеру комфортно себя чувствовать в долгосрочной перспективе.

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

                                            Рис. 1 - Открытие сделок при пересечении средних скользящих.

          Красным цветом обозначена быстрая средняя. Пересечение ею синей линии (медленной средней) дало сигнал покупки (обозначен синей стрелкой). Движение оказалось не очень мощным. Поэтому к моменту получения обратного сигнала прибыль была мизерной. За то обратный сигнал (обозначен красной стрелкой) указал на стремительный тренд, который принес значительную прибыль.

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

 
//+-------------------------------------------------------------------------------------+
   //| Расчет значений средней с формированием сигналов для открытия позиций               |
   //+-------------------------------------------------------------------------------------+
   void GetSignal()
   {
    Signal = 0;
   // - 1 - == Получение значений индикаторов ==============================================
    double FMA1 = iMA(Symbol(), 0, FastMAPeriod, FastMAShift, FastMAMethod, FastMAPrice, 1);
    double FMA2 = iMA(Symbol(), 0, FastMAPeriod, FastMAShift, FastMAMethod, FastMAPrice, 2);
    double SMA1 = iMA(Symbol(), 0, SlowMAPeriod, SlowMAShift, SlowMAMethod, SlowMAPrice, 1);
    double SMA2 = iMA(Symbol(), 0, SlowMAPeriod, SlowMAShift, SlowMAMethod, SlowMAPrice, 2);
   // - 1 - == Окончание блока =============================================================
   
   // - 2 - == Генерация сигнала ===========================================================
    if (FMA1 > SMA1 && FMA2 < SMA2)
       Signal = 1;                                        // Открытие BUY
    
    if (FMA1 < SMA1 && FMA2 > SMA2)
       Signal = -1;                                        // Открытие SELL
   // - 2 - == Окончание блока =============================================================================================
   }

        Здесь все просто - получение значений средних на первом и втором барах с последующим отслеживанием момента пересечения. От характера пересечения (снизу вверх или сверху вниз) зависит значение сигнала: 1 - BUY, -1 - SELL.

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

 
// - 2 - == Генерация сигнала ===========================================================
    if (FMA1 > SMA1 && FMA2 < SMA2)
       Signal = -1;                                        // Открытие BUY
    
    if (FMA1 < SMA1 && FMA2 > SMA2)
       Signal = 1;                                        // Открытие SELL
   // - 2 - == Окончание блока =============================================================
   

        Иными словами, значения 1 и -1 просто поменяли свои места. Но даже такое незначительное изменение стратегии оформляем в виде отдельного эксперта SimpleMACross_Reverse.

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

 
   if ((FastMAPeriod == SlowMAPeriod && FastMAShift == SlowMAShift && 
           FastMAMethod == SlowMAMethod && FastMAPrice == SlowMAPrice) || 
           SlowMAPeriod < FastMAPeriod)
        {
         Comment("FastМАPeriod должен быть меньше SlowМАPeriod. Советник отключен!");   
         Print("FastМАPeriod должен быть меньше SlowМАPeriod. Советник отключен!");   
         return(0);  
        }
       
      Activate = True;
   

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

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

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

         Оптимизация будет производиться за относительно большой промежуток времени - последние четыре года на часовом таймфрейме. Это позволит уменьшить вероятность получения случайных значений параметров. Начнем с валютной пары EURUSD (см. рис. 2):

                Рис. 2. - Результаты оптимизации прямой системы на валютной паре EURUSD.

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

                Рис. 3. - Результаты оптимизации реверсной системы на валютной паре EURUSD.

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

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

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

            Эксперт,  реализующий совмещение стратегий, назовем SimpleMACrossDouble. Его сигнальная часть, по сравнению с предыдущими экспертами, сложнее не стала. Объем немного увеличился:

 
//+-------------------------------------------------------------------------------------+
   //| Расчет значений средней с формированием сигналов для открытия позиций               |
   //+-------------------------------------------------------------------------------------+
   void GetSignal()
   {
    Signal = 0;
   // - 1 - == Получение значений индикаторов ==============================================
    double FMA1 = iMA(Symbol(), 0, FastMAPeriod, FastMAShift, FastMAMethod, FastMAPrice, 1);
    double FMA2 = iMA(Symbol(), 0, FastMAPeriod, FastMAShift, FastMAMethod, FastMAPrice, 2);
    double SMA1 = iMA(Symbol(), 0, SlowMAPeriod, SlowMAShift, SlowMAMethod, SlowMAPrice, 1);
    double SMA2 = iMA(Symbol(), 0, SlowMAPeriod, SlowMAShift, SlowMAMethod, SlowMAPrice, 2);
   
    double FMAR1 = iMA(Symbol(), 0, FastMAPeriod_Rev, FastMAShift_Rev, FastMAMethod_Rev,
                       FastMAPrice_Rev, 1);
    double FMAR2 = iMA(Symbol(), 0, FastMAPeriod_Rev, FastMAShift_Rev, FastMAMethod_Rev,
                       FastMAPrice_Rev, 2);
    double SMAR1 = iMA(Symbol(), 0, SlowMAPeriod_Rev, SlowMAShift_Rev, SlowMAMethod_Rev,
                       SlowMAPrice_Rev, 1);
    double SMAR2 = iMA(Symbol(), 0, SlowMAPeriod_Rev, SlowMAShift_Rev, SlowMAMethod_Rev,
                       SlowMAPrice_Rev, 2);
   // - 1 - == Окончание блока =============================================================
   
   // - 2 - == Генерация сигнала для прямой системы ========================================
    if (FMA1 > SMA1 && FMA2 < SMA2)
       Signal = 1;                                                           // Открытие BUY
    
    if (FMA1 < SMA1 && FMA2 > SMA2)
       Signal = -1;                                                         // Открытие SELL
   // - 2 - == Окончание блока =============================================================
   
   // - 3 - == Генерация сигнала для обратной системы ======================================
    if (FMAR1 > SMAR1 && FMAR2 < SMAR2)
       Signal = Signal - 2;                                                  // Открытие BUY
    
    if (FMAR1 < SMAR1 && FMAR2 > SMAR2)
       Signal = Signal + 2;                                                 // Открытие SELL
   // - 3 - == Окончание блока =============================================================
   }

               Вместо расчета значений по двум средним скользящим, используется расчет по четырем скользящим средним. Генерация сигналов теперь разделена на два блока - для прямой и для реверсной систем. Чтобы впоследствии различать сигналы, прямой системе присвоен вес сигнала 1, а реверсной - вес 2. В результате, значения сигналов от прямой системы будут 1 и -1, от реверсной 2 и -2, а от обеих систем сразу 3 и -3.

              Так как полученная стратегия объединяет две системы, будут возникать периоды с одновременным присутствием двух позиций, одинаковых по направлению. То есть две позиции BUY или две позиции SELL. Вариант с одновременным существованием BUY и SELL будем исключать, так как такое положение дел соответствует отсутствию позиции. Если же у нас присутствует две одинаковых по направлению торговли позиции, то необходимо различать, какой из систем принадлежит сделка. Организовать отличие сделок можно при помощи разного значения Magic Number. Примем, что позиции, открытые по прямой системе, будут иметь Magic Number, заканчивающийся нулем, а позиции, открытые по реверсной системе, будут с Magic Number, заканчивающимся единицей.

              Сортировка позиций по типам и системам производится в теле функции OrdersFind:

 
//+-------------------------------------------------------------------------------------+
   //| Поиск позиций с заполнением массивов тикетов BuyTicket и SellTicket                 |
   //+-------------------------------------------------------------------------------------+
   void OrdersFind()
   {
    ArrayInitialize(BuyTicket, -1);
    ArrayInitialize(SellTicket, -1);
    for (int i = OrdersTotal()-1; i >= 0; i--)
      if (OrderSelect(i, SELECT_BY_POS))
        if (OrderSymbol() == Symbol() && MathFloor(OrderMagicNumber()/10) == MagicNumber &&
            OrderType() < 2)
          {
           int ID = MathMod(OrderMagicNumber(), 10);
           if (OrderType() == OP_BUY)
             BuyTicket[ID] = OrderTicket();
            else
             SellTicket[ID] = OrderTicket(); 
          } 
   }

                Первые  элементы массивов (индекс 0) BuyTicket и SellTicket содержат тикеты позиций, открытых по прямой системе, а вторые элементы (индекс 1) - по реверсной. Отрицательное значение содержимого массива соответствует отсутствию позиции.

                Все операции по открытию и закрытию позиций производятся в теле функции Trades:

 
//+-------------------------------------------------------------------------------------+
   //| Открытие и закрытие позиций                                                         |
   //+-------------------------------------------------------------------------------------+
   bool Trades()
   {
   // - 1 - ============================ Инициализация "рабочих" переменных ================
    int i = MathAbs(Signal);                         // Количество итераций цикла 0, 1 или 2
    while (i > 0)
      {
       int ID = MathFloor(i/2);            // Идентификатор системы 0 - прямая, 1 - обратная
       int Rev = MathAbs(ID-1);                     // Идентификатор противоположной системы
   // - 1 - ===================================== Окончание блока ==========================
     
   // - 2 - ==================== Действия при сигнале открытия длинных позиций =============
       if (Signal > 0)                                                  
         if (SellTicket[ID] > 0)                              // найден SELL текущей системы
           {                                              // нужно закрыть его и открыть BUY
            if (!ClosePos(SellTicket[ID]))                          // Попытка закрытия SELL
              return(False);
            if (SellTicket[Rev] > 0)                  // найден SELL противоположной системы
              {                                  // закрываем его, но новый BUY не открываем
               if (!ClosePos(SellTicket[Rev]))
                 return(False);
              }
             else                   // не найден SELL противоположной системы, открываем BUY
              if (OpenOrderCorrect(OP_BUY, NP(Ask), 0, 0, ID) != 0)
                return(False); 
           }
          else 
           if (BuyTicket[ID] < 0) // не найден BUY текущей системы, т. е. вообще нет позиций
                    // текущей системы. Проверяем существование SELL противоположной системы
             if (SellTicket[Rev] > 0)           // Если найден SELL, то закрываем его, но не
               {                                                            // открываем BUY
                if (!ClosePos(SellTicket[Rev]))
                  return(False);
               }
              else
               // Если не было закрытия SELL на текущей свече или существует BUY 
               // противоположной системы, то открываем новый BUY
               if (BuyTicket[Rev] > 0 || !IsCloseOnThisCandle(OP_SELL, Rev))
                 if (OpenOrderCorrect(OP_BUY, NP(Ask), 0, 0, ID) != 0)
                   return(False);
   // - 2 - ===================================== Окончание блока ==========================
          
   // - 3 - ==================== Действия при сигнале открытия коротких позиций ============
       if (Signal < 0)
         if (BuyTicket[ID] > 0)                                // найден BUY текущей системы
           {                                             // нужно закрыть его и открыть SELL
            if (!ClosePos(BuyTicket[ID]))            // Попытка закрытия BUY текущей системы
              return(False);
            if (BuyTicket[Rev] > 0)                    // найден BUY противоположной системы
              {                                 // закрываем его, но новый SELL не открываем
               if (!ClosePos(BuyTicket[Rev]))// Попытка закрытия BUY противоположной системы
                 return(False);
              }
             else           // Нет позиции BUY противоположной системы, можно открывать SELL
              if (OpenOrderCorrect(OP_SELL, NP(Bid), 0, 0, ID) != 0)
                return(False);  
           }
          else                                            // Нет позиции BUY текущей системы
           if (SellTicket[ID] < 0)       // не найден SELL текущей системы, т. е. вообще нет
                    // текущей системы. Проверяем существование SELL противоположной системы
             if (BuyTicket[Rev] > 0)             // Если найден BUY противоположной системы,
               {                                   // то закрываем его, но SELL не открываем
                if (!ClosePos(BuyTicket[Rev]))
                  return(False);
               }
              else
               // Если не было закрытия BUY на текущей свече или существует SELL 
               // противоположной системы, то открываем новый SELL
               if (SellTicket[Rev] > 0 || !IsCloseOnThisCandle(OP_BUY, Rev))
                 if (OpenOrderCorrect(OP_SELL, NP(Bid), 0, 0, ID) != 0)
                   return(False);  
   // - 3 - ===================================== Окончание блока ==========================
              
       i = i - 2;            // Учитываем, что сигнал мог быть по обратной системе с весом 2
      } 
    return(True);
   }

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

         Для правильного понимания дальнейших действий эксперта, рассмотрим таблицу 1.      

 
Сигнал Позиция текущей системы Позиция противоположной системы Действие
BUY Нет Нет BUY
Нет Buy BUY
Buy Нет Нет
Buy Buy Нет
Нет Sell Закрыть Sell
Sell Нет Закрыть Sell, открыть Buy
Sell Sell Закрыть оба Sell
SELL Нет Нет SELL
Нет Buy Закрыть Buy
Buy Нет Закрыть Buy, открыть Sell
Buy Buy Закрыть оба Buy
Нет Sell SELL
Sell Нет Нет
Sell Sell Нет

                    Табл. 1. - Действия эксперта при получении сигнала.

            Важным моментом является отличие действий в случае присутствия одной противоположной позиции, открытой по текущей или противоположной системе. Так, если получен сигнал BUY и существует короткая позиция по текущей системе, то производится переворот, то есть закрытие Sell и открытие Buy. Если же короткая позиция открыта по противоположной системе, то новый Buy не открывается, он компенсируется закрытием короткой позиции. Точно также объясняются действия, в случае присутствия двух коротких позиций. Сначала закрывается Sell текущей системы, после чего следовало бы открыть длинную позицию. Но так как существует еще одна короткая позиция, то открытие Buy компенсируется ее закрытием.

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

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

            Аналогичные действия производятся в блоке 3, который обрабатывает сигнала открытия коротких позиций.

            После прохождения блоков 2 и 3 исполняется операция уменьшения переменной цикла i на 2. Если сигнал был один, то больше цикл while не выполняется. Только в случае одновременного присутствия сигналов от обеих систем цикл переходит к следующей итерации.

            Функция ClosePos выполняет закрытие позиции, тикет которой ей передан:

 
//+-------------------------------------------------------------------------------------+
   //| Закрывает выбранную позицию. Если закрыть не удалось, то False, иначе True.         |
   //+-------------------------------------------------------------------------------------+
   bool ClosePos(int Ticket)
   {
    if (OrderSelect(Ticket, SELECT_BY_TICKET) && OrderCloseTime() == 0)
      if (WaitForTradeContext())  
        {
         if (OrderType() == OP_BUY)
           double Pr = ND(MarketInfo(Symbol(), MODE_BID));
          else
           Pr = ND(MarketInfo(Symbol(), MODE_ASK));
         if (OrderClose(OrderTicket(), OrderLots(), Pr, 3))        
           return(True);  
        }   
    return(False);
   }

            Для предотвращения попыток закрытия уже закрытой позиции сначала проверяется существование позиции. Если позиция действительно существует, то по ее типу определяется необходимая цена закрытия - Bid или Ask. Успешное закрытие позиции приводит к возврату результата True вызывающей функции. Во всех остальных случаях возвращаемый результат False.

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

 
//+-------------------------------------------------------------------------------------+
   //| Поиск закрытия позиции нужного типа на текущей свече. Если найдено закрытие, то True|
   //| В противном случае результат False                                                  |
   //+-------------------------------------------------------------------------------------+
   bool IsCloseOnThisCandle(int Type, int ID)
   {
   // - 1 - ============== Блок проверки для режима тестирования ===========================
    if (IsTesting())
      {
       if (OrderSelect(OrdersHistoryTotal()-1, SELECT_BY_POS, MODE_HISTORY))
         if (OrderCloseTime() >= Time[0])
           if (OrderType() == Type)
             if (MathMod(OrderMagicNumber(), 10) == ID)
               return(True);
      }
   // - 1 - =========================== Окончание блока ====================================
     else 
   // - 2 - ==================== Блок проверки для режима онлайн ===========================
      {
       for (int i = 0; i < OrdersHistoryTotal(); i++)
         if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
           if (OrderSymbol() == Symbol())
             if (OrderCloseTime() >= Time[0])
               if (OrderType() == Type && MathFloor(OrderMagicNumber()/10) == MagicNumber)
                 if (MathMod(OrderMagicNumber(), 10) == ID)
                   return(True);
      }       
   // - 2 - =========================== Окончание блока ====================================
    return(False);  
   }

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

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

            Такими функциями обладает эксперт SimpleMACrossDouble. Для правильного его тестирования нужно присвоить полученные в результате оптимизации значения соответствующим параметрам эксперта. Так, периоды быстрой и медленной МА прямой системы нужно указать в параметрах FastMAPeriod и SlowMAPeriod. Периоды быстрой и медленной МА реверсной системы нужно указать в параметрах FastMAPeriod_Rev и SlowMAPeriod_Rev. Для валютной пары EURUSD параметры будут такие: FastMAPeriod = 110, SlowMAPeriod = 124, FastMAPeriod_Rev = 265 и SlowMAPeriod_Rev = 284. Проведем тестирование на том же самом историческом промежутке (01.01.2005 - 06.03.2010) и на том же таймфрейме - Н1 (см. рис. 4):

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

        Главная цель (уменьшение максимальной просадки) оказалась достигнутой - значение 1302 доллара. Напомним, просадка прямой системы составляла 2117 долларов, а реверсной 2341 доллар. Ничуть не пострадала чистая прибыль. Она, конечно, не стала равной сумме прибылей двух систем (чуть больше 10000), но все же оказалась большей, чем прибыль каждой из систем в отдельности  - 7851 доллар. Наибольший успех сводная стратегия получила за высоковолатильный период, начавшийся с августа 2008-го года. Но и до этого система по большей части находилась в прибыльной зоне. Поэтому можно считать эксперимент успешным. Результирующий фактор восстановления составил 3.35.

        Для подтверждения неслучайности полученных результатов проделаем такую же работу с еще тремя валютными парами. Возьмем USDCHF. Результаты оптимизации прямой и реверсной систем с использованием котировок USDCHF приведены на рис. 5 и 6:

                                     Рис. 5. - Результаты оптимизации прямой системы на валютной паре USDCHF.

                                    Рис. 6. - Результаты оптимизации реверсной системы на валютной паре USDCHF.

        Таким образом, наилучшие результаты прямой системы получены при значениях периодов средних 237 и 241, а для реверсной системы - 12 и 281. Эти значения заносим в параметры эксперта SimpleMACrossDouble (см. рис. 7).

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

        Вид кривой баланса очень напоминает кривую баланса, полученную при тестировании эксперта на паре EURUSD. Точно также до августа 2008-го года стратегия просто держалась на плаву, а затем предприняла мощный скачок. В итоге максимальная просадка уменьшилась до 1693 долларов. До этого минимальное значение показала прямая система  - 1869 долларов. Поэтому и в данном случае получаем экономический эффект от совмещения систем. Чистая прибыль по сравнению с каждой из систем тоже выросла, но уменьшилась, если сравнивать с совокупной чистой прибылью - 8390 долларов. Фактор восстановления оказался выше, чем у евро - 4.49.

        Подобный опыт проведем с валютной парой GBPUSD. Сначала произведем оптимизацию прямой и реверсной систем (см. рис. 8 и 9).

                                         Рис. 8. - Результаты оптимизации прямой системы на валютной паре GBPUSD.

                                        Рис. 9. - Результаты оптимизации обратной системы на валютной паре GBPUSD.

           Прямая система отлично зарекомендовала себя при значениях быстрой и медленной средней соответственно 6 и 59. Реверсная система показала еще лучшие результаты при периоде быстрой средней 261 и при периоде медленной средней 264. Сводим результаты в едином советнике SimpleMACrossDouble (см. рис 10).

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

         Вновь получаем похожий вид кривой баланса. Правда, до 2008-го года стратегия также дала приличный прирост, который, все же, несравним с прибылью, показанной за последние два года. Снова констатируем уменьшение максимальной просадки с 2244 долларов до 1816 долларов. А вот чистая прибыль дошла до серьезного пика - 15050 долларов. В результате фактор восстановления добрался до отметки 8.29.

         Последняя валютная пара USDJPY. Результаты ее оптимизации такие (см. рис 11 и 12):

                                    Рис. 11. - Результаты оптимизации прямой системы на валютной паре USDJPY.

                                    Рис. 12. - Результаты оптимизации обратной системы на валютной паре USDJPY.

        На этот раз планка изначально поднята высоко - прямая система показала фактор восстановления больше 10. Улучшить такой результат сродни подвигу. И все же никто не запрещает попробовать. Периоды средних скользящих прямой системы - 9 и 27, а реверсной - 277 и 294 (см. рис. 13).

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

        Из всех полученных сегодня результатов данный вид кривой баланса можно назвать наиболее идеальным. Хотя и здесь прослеживается увеличение угла наклона с 2008-го года. Уменьшить максимальную просадку не удалось - 901 доллар, но чистая прибыль все же выросла, дойдя до 9966 долларов. Это позволило увеличить более важный показатель - фактор восстановления. Его значение достигло рекордных 11.06.

        Заключение

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

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

 

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

 

 

Март 2010

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

0
 
 

Комментарии

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

Содержание этого поля является приватным и не предназначено к показу.
CAPTCHA
Проверка на СПАМ:
  _       ____      _    ____     _  __  __  ____  
| |__ |___ \ (_) / ___| (_) \ \/ / / ___|
| '_ \ __) | | | | | | | \ / \___ \
| | | | / __/ | | | |___ | | / \ ___) |
|_| |_| |_____| _/ | \____| _/ | /_/\_\ |____/
|__/ |__/
Enter the code depicted in ASCII art style.


0% комиссии при платеже кредитной картой VISA/MasterCard

 

Комиссия за процессинг банковских карт Visa/MasterCard составляет 0%. Минимальная сумма платежа – 1 USD. Для перечисления средств на Ваш торговый счет воспользуйтесь соответствующей формой в Кабинете Трейдера (секция «Денежные операции»).
 






Общие вопросы
info@forextrade.ru
Техническая поддержка
support@fxservice.com
Необходимые файлы и документы
Филиальная сеть
Условия перепечатки материалов с сайта
Уведомление о рисках
Карта сайта
Международный валютный рынок Forex (Форекс) – крупнейший внебиржевой финансовый рынок в мире. Компания Admiral Markets является Forex брокером и предлагает своим клиентам инновационные технологии трейдинга и консалтинговые услуги на рынке FOREX (Форекс), а также на рынках акций (CFD), золота, фондовых индексов и фьючерсов. Компания создана в 2001 году и на данный момент имеет разветвленную сеть филиалов в 16 странах мира, что позволяет трейдерам оперативно получать всю необходимую информацию о наших брокерских услугах на рынке валют Форекс / Forex. Торговые операции проводятся с использованием многофункционального терминала MetaTrader 4 для ПК, MT4 Mobile для КПК, MetaTrader4 Smartphone Edition, а также MetaTrader Multiterminal для управления множеством счетов одновременно. Мы предлагаем уникальную в сфере интернет-трейдинга инвестиционную услугу – золотые счета, баланс которых представлен не в валюте, а в золоте (Gold, XAU). Базовым активом депозита золотых торговых счетов является драгоценный металл (перечисленные средства в валютах автоматически конвертируются в золото). Открыть реальный или демо счет можно за 5 минут из Кабинета Трейдера. Специалистами компании Admiral Markets разработан эффективный алгоритм обучения трейдингу на рынке Forex (Форекс). Бесплатные семинары и Forex курсы проводятся во всех городах, где есть филиалы компании Admiral Markets.