Нестандартная автоматическая торговля

Leonid Borsky | 9 июля, 2007

Введение

Насколько реально можно успешно и комфортно торговать, используя торговую платформу МТ4, и не слишком обременяя себя, при этом, скрупулезным анализом рынка? Возможно ли практически реализовать такую торговую систему?

Пожалуй - да!

Особенно в плане автоматической торговли! Возможности MQL4 позволяют это сделать. Описанная ниже автоматическая торговая система обладает хорошей повторяемостью. И вполне по силам для реализации даже тем, кто только начинает знакомиться с основами написания экспертов.

Сама же система практически полностью срисована из окружающего нас мира. Жизнь, гармонично развиваясь, диктует нам свои законы. Все мы в детстве, на природе наблюдали такую картину: муравьи, облепив со всех сторон, например, соломинку тянут её в муравейник. Причем, каждый муравей по отдельности тянет соломинку в свою сторону. Однако, в конечном итоге соломинка непостижимым образом движется в сторону муравейника! Загадка природы? Попробуем смоделировать ситуацию. На торговой платформе.

Нестандартная автоматическая система

Предположим, мы имеем некую автоматическую торговую систему. Профитную. При этом, система удовлетворяет следующим условиям:

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

Практически получилось, что такая система дает за год не менее +3000 пунктов профита даже без включения блока Money Management. Далее, мы включаем эту систему в, так называемом, реверсном режиме. Иначе говоря, теперь она будет работать следующим образом:

  1. Там, где ранее, изначально, в прямом режиме мы покупали, теперь будем продавать! А там, где изначально продавали, - теперь будем покупать! После чего вновь оптимизируем систему, используя статические параметры. И опять добиваемся на выходе этой, уже реверсной версии, получения максимальной прибыли с разумной просадкой. Сделать это будет нетрудно. Так как наша автоматическая торговая система изначально построена на случайных входах в рынок.
  2. После чего, запускаем в рынок сразу обе версии, прямую и реверсную одновременно. Одновременность работы двух версий - это важный, ключевой момент описываемой торговой системы!

А теперь посмотрим, что же у нас получилось?

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

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

Но общая, суммарная прибыль на счете будет у нас поступательно расти! Думаю,что это очевидно. Так как обе системы, как прямая, так и реверсная, оптимизированы на профитную работу. Более того, текущий убыток одной версии практически постоянно будет компенсироваться текущей прибылью другой версии! Таким образом, мы получаем максимальную прибыль при минимальной просадке.

Некоторый недостаток такой торговли - увеличение залога. Но можно ли это назвать недостатком? Фактически, здесь работают две независимые торговые системы - прямая и реверсная. И, конечно, залог будет двойным. А вот что касается рисков, то они сильно уменьшаются! Именно в этом и предполагаю конечный смысл идеи. Не столько увеличить прибыль, сколько свести к минимуму просадку. Но одно влечет за собой другое. И, повторюсь, суммарная прибыль при такой торговле поступательно растет. А значит, мы смело можем теперь подключить блок Money Management .

На сайте MQL4.community имеется широкий выбор различных экспертов. В том числе и советники, удовлетворяющие условиям, перечисленным в начале статьи. Было бы желание. А рынок заставляет нас ставить новые задачи и искать различные, нестандартные решения этих задач! Обнаружились и возможности для дальнейшего поиска.

Для реализации идеи и последующих экспериментов в качестве основы был взят советник Юрия Решетова Artificial Intelligence (Исскусственный Интеллект). Описанный ранее в этом же разделе (смотрите статью Ю.Решетова "Как найти прибыльную торговую стратегию". С некоторыми изменениями и дополнениями. В частности, предусмотрен вызов иного базового индикатора для работы Перцептрона. А также, предусмотрены некоторые дополнительные условия для открытия и последующего сопровождения позиций.

Вот некоторые результаты эксперимента, полученные при тестировании пары GBPUSD на таймфрейме H1. Исходный депозит - 10000 единиц. 2.5-летняя история, с января 2005г. по май 2007г.

В прямой версии за этот период наблюдалось 250 сделок. В реверсной - 360 сделок. Число сделок различно за счет того, что уровень стоплосса при оптимизации оказался разным по каждой версии. Чистая прибыль примерно равна +10000 в обоих случаях. При работе 0.1-лотом, без подключения блока Money Management. Отношение прибыльных сделок к убыточным, примерно, 3:2 в обоих версиях.

Графики балансов (эквити) прямой и реверсной версий по истории выглядят так, - см. рисунок:

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

Более того! Там, где на одном графике наблюдается "флет", - на другом графике идет подъём! В итоге получаем максимальную суммарную прибыль при минимальном риске, т.е. при минимальной просадке. Нетрудно свести историю сделок в Excel и построить результирующий график, наглядно демонстрирующий суть идеи.

Следующий шаг - это установка блока Money Management. Мы вправе ожидать, что при такой торговой системе установка этого блока значительно улучшит конечные результаты. По таким критериям, как прибыль, просадка и комфортность торговли. В прямом и реверсном вариантах я предусмотрел вызов библиотеки расчета лотов "b-lots" по версии И.Кима. Легко вставляется в исходный код. И работает очень прилично: https://www.mql5.com/ru/code/8048

При тестировании использовал фракционно-пропорциональный метод расчета лотов ( LotsWayChoice=2 ). Который дает разумную, минимальную просадку с относительно хорошими прибыльными выходами ( Райан Джонс, "Сделай миллионы, играя числами" ). Результаты получились неплохими. По сравнению с иными методами расчета лотов. Которые зачастую показывают заоблачную прибыль, при такой-же, заоблачной просадке.

На той же истории, с января 2005г. по май 2007г. Результаты тестирования при тех же внешних параметрах, что и ранее:

Реверсная версия:

Прямая версия:

Графики балансов - на рисунке:

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

Практическая реализация

Для примера и последующих начальных экспериментов привожу код реверсной версии. Которая работает "против" прямой версии авторского варианта советника "AI" Ю.Решетова. Прямую же версию и её описание можно взять по ссылке: https://www.mql5.com/ru/code/10289

Кроме того, в прилагаемом к моей статье файле, имеется индикатор Перцептрон (автор - NoName с Украины, г. Кременчуг). Позволяющий визуально контролировать текущую работу советников, прямого и реверсного. И заранее знать, в какую сторону перевернется, либо откроется новая позиция! Понятно, что значения весовых коэффициентов X1-X4 индикатора Перцептрон следует установить равными соответствующим значениям советников. Пример для реверсной версии - на графике:

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

//+------------------------------------------------------------------+
//|                                 ArtificialIntelligenceRevers.mq4 |
//|                               Copyright й 2006, Yury V. Reshetov |
//|                                Modifed by   Leonid553            |
//|                                  http://www.tradersforum.net.ru/ | 
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright й 2006, Yury V. Reshetov ICQ:282715499"
#property link      "http://reshetov.xnet.uz/"
//---- input parameters
extern int    x1 = 88;
extern int    x2 = 172;
extern int    x3 = 39;
extern int    x4 = 172;
// StopLoss level
extern double sl = 50;
extern double lots = 0.1;
extern int    MagicNumber = 808;
static int prevtime = 0;
static int spread = 3;
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
     Comment(perceptron());   
// Ждем, когда сформируется новая свеча
// Если появляется новая свеча, то проверяем возможность сделки 
   if(Time[0] == prevtime) return(0);
   prevtime = Time[0];
//----
   if(IsTradeAllowed()) 
     {
       spread = MarketInfo(Symbol(), MODE_SPREAD);
     } 
   else 
     {
       prevtime = Time[1];
       return(0);
     }
   int ticket = -1;
   // check for opened position
   // сопровождение открытой позиции :
   int total = OrdersTotal();   
   for(int i = 0; i < total; i++) 
     {
       OrderSelect(i, SELECT_BY_POS, MODE_TRADES); 
       // check for symbol & magic number
       //проверяем символ и магик-номер
       if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) 
         {
           int prevticket = OrderTicket();
           // long position is opened
           if(OrderType() == OP_BUY) 
              // если открыта длинная позиция и ...
             {
               // check profit 
               // и текущий профит больше величины =(стоплосс плюс спред) и ...
               if(Bid > (OrderStopLoss() + (sl * 2  + spread) * Point)) 
                 {               
                   if(perceptron() > 0) 
                     { 
                    // и  перцептрон больше нуля , то переворачиваемся в Селл
                       // reverse
                       ticket = OrderSend(Symbol(), OP_SELL, lots * 2, Bid, 3, 
                         Ask + sl * Point, 0, "AI", MagicNumber, 
                                          0, Red); 
                       Sleep(30000);
                       if(ticket < 0) 
                         {
                           prevtime = Time[1];
                         } 
                       else 
                         {
                           OrderCloseBy(ticket, prevticket, Blue);   
                         }
                     } 
                   else 
//если перцептрон меньше нуля, то подтягиваем стоплосс на расстояние =sl
//от текущей цены                 
  { 
                       // trailing stop
                       if(!OrderModify(OrderTicket(), OrderOpenPrice(), 
                          Bid - sl * Point, 0, 0, Blue)) 
                         {
                           Sleep(30000);
                           prevtime = Time[1];
                         }
                     }
                 }  
               // short position is opened
             } 
           else 
             {
               // если открыта короткая позиция и ...
               // check profit 
              if(Ask < (OrderStopLoss() - (sl * 2 + spread) * Point)) 
                 {
                  // текущий профит больше величины =(стоплосс плюс спред) и ...
                   if(perceptron() < 0) 
                     { 
             // и  перцептрон меньше нуля, то переворачиваемся в Бай
                       // reverse
                       ticket = OrderSend(Symbol(), OP_BUY, lots * 2, Ask, 3, 
                           Bid - sl * Point, 0, "AI", MagicNumber,
                                          0, Blue); 
                       Sleep(30000);
                       if(ticket < 0) 
                         {
                           prevtime = Time[1];
                         } 
                       else 
                         {
                           OrderCloseBy(ticket, prevticket, Blue);   
                         }
                     } 
                   else 
//если перцептрон больше нуля то, подтягиваем стоплосс на расстояние =sl  
//от текущей цены
                   { 
                       // trailing stop
                       if(!OrderModify(OrderTicket(), OrderOpenPrice(), 
                          Ask + sl * Point, 0, 0, Blue)) 
                         {
                           Sleep(30000);
                           prevtime = Time[1];
                         }  
                     }
                 }  
             }
           // exit
           return(0);
         }
     }
//********************************************************************
   // check for long or short position possibility
   // изначальный вход в рынок:
 
   if(perceptron() < 0) 
     { 
       // если перцептрон меньше нуля, то открываем длинную позицию :
       //long
       ticket = OrderSend(Symbol(), OP_BUY, lots, Ask, 3, Bid - sl * Point, 0, 
                      "AI", MagicNumber, 0, Blue); 
       if(ticket < 0) 
         {
           Sleep(30000);
           prevtime = Time[1];
         }
     } 
   else 
      // если перцептрон больше нуля, то открываем короткую позицию:
     { 
       // short
       ticket = OrderSend(Symbol(), OP_SELL, lots, Bid, 3, Ask + sl * Point, 0, 
                      "AI", MagicNumber, 0, Red); 
       if(ticket < 0) 
         {
           Sleep(30000);
           prevtime = Time[1];
         }
     }
//--- exit
   return(0);
  }
//+------------------------------------------------------------------+
//|  The PERCEPRRON - a perceiving and recognizing function          |
//+------------------------------------------------------------------+
double perceptron() 
  {
   double w1 = x1 - 100.0;
   double w2 = x2 - 100.0;
   double w3 = x3 - 100.0;
   double w4 = x4 - 100.0;
   double a1 = iAC(Symbol(), 0, 0);
   double a2 = iAC(Symbol(), 0, 7);
   double a3 = iAC(Symbol(), 0, 14);
   double a4 = iAC(Symbol(), 0, 21);
   return (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4);
  }
//+------------------------------------------------------------------+}

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

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

Но это в перспективе.


Заключение

Предвижу возражения скептиков. А не случится ли так, что обе версии одновременно начнут работать в убыток?

Что-ж, возможно такое и произойдет в редких, исключительных случаях. Но не более того - "нет в мире идеала". Однако, при практически случайных входах обе версии работают, всё-таки, по сигналам одного индикатора. И, повторюсь, во встречных режимах, друг против друга!

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