Скачать MetaTrader 5

Защита от ложных срабатываний торгового робота

23 ноября 2015, 11:52
Alexander Masterskikh
64
15 526

Введение

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


Суть проблемы

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

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

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

Итак, приступаем к решению проблемы. В качестве шаблона для примера я буду использовать эксперт из стандартного комплекта, имеющегося в клиентском терминале МetaТrader 4, под названием "MACD Sample".

Вот как визуально выглядит сама проблема дребезга на примере резкого скачка цены EURUSD 2-го октября этого года (таймфрейм М15, эксперт "MACD Sample" с настройками по умолчанию):

На скриншоте хорошо видно, что имеется 8 последовательных срабатываний (входы Buy) на одной свече. Из них корректный (с точки зрения нормальной рыночной логики) только первый вход, остальные 7 являются дребезгом.

Причины ложных срабатываний в данном конкретном случае:

  • это малая величина TakeProfit в настройках по умолчанию (а это алгоритм выхода), из-за чего каждая позиция быстро закрывается;
  • а также алгоритм входа эксперта "MACD Sample", который срабатывает сразу после закрытия предыдущей позиции, допуская повторный вход независимо от количества входов на данной свече.

Мы договорились, что вопросы фильтрации рыночных колебаний мы намеренно не учитываем (так как у каждого трейдера свой алгоритм входа и выхода), поэтому для решения проблемы, с целью универсальности применения, рассмотрим следующие факторы более общего характера:

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


Решение в алгоритме входа

Наиболее простым, но в то же время и самым надежным вариантом фиксации точки входа, является фактор времени, причины следующие:

  • Счетчик количества срабатываний подразумевает создание цикла в программе, что не только усложнит алгоритм, но и снизит быстродействие торгового эксперта.
  • Амплитуда и связанные с ней контрольные уровни цены могут повторяться из-за возврата цен при разворотах внутри свечи, что делает критерий уровня цены неоднозначным.
  • А вот время необратимо, движется только в одном направлении (нарастания), а значит, является самым точным и к тому же однозначным критерием для решения задачи — обеспечения однократного срабатывания и устранения дребезга.

Таким образом, главным фактором является момент срабатывания алгоритма входа, вернее, момент срабатывания ордера для открытия позиции (OrderSend), так как эти два момента могут не совпадать при наличии в алгоритме каких-либо специальных задержек открытия ордера.

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

Решение довольно простое. Сначала напишу код с некоторыми комментариями, а потом поясню более подробно. Вот дополнительный код (помечен желтым фоном), который нужно вставить в алгоритм торгового эксперта (см. файл MACD_Sample_plus1.mq4):

//+------------------------------------------------------------------+
//|                                                  MACD Sample.mq4 |
//|                   Copyright 2005-2014, MetaQuotes Software Corp. |
//|                                              http://www.mql4.com |
//+------------------------------------------------------------------+
#property copyright   "2005-2014, MetaQuotes Software Corp."
#property link        "http://www.mql4.com"

input double TakeProfit    =50;
input double Lots          =0.1;
input double TrailingStop  =30;
input double MACDOpenLevel =3;
input double MACDCloseLevel=2;
input int    MATrendPeriod =26;
//--- вводим новую переменную (величина в секундах для 1 бара данного ТФ, для М15 равно 60 с х 15 = 900 с)
datetime Time_open=900;
//--- вводим новую переменную (время открытия бара,где будет 1-й вход)
datetime Time_bar = 0;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTick(void)
  {
   double MacdCurrent,MacdPrevious;
   double SignalCurrent,SignalPrevious;
   double MaCurrent,MaPrevious;
   int    cnt,ticket,total;
//---
// initial data checks
// it is important to make sure that the expert works with a normal
// chart and the user did not make any mistakes setting external 
// variables (Lots, StopLoss, TakeProfit, 
// TrailingStop) in our case, we check TakeProfit
// on a chart of less than 100 bars
//---
   if(Bars<100)
     {
      Print("bars less than 100");
      return;
     }
   if(TakeProfit<10)
     {
      Print("TakeProfit less than 10");
      return;
     }
//--- to simplify the coding and speed up access data are put into internal variables
   MacdCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,0);
   MacdPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,1);
   SignalCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,0);
   SignalPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,1);
   MaCurrent=iMA(NULL,0,MATrendPeriod,0,MODE_EMA,PRICE_CLOSE,0);
   MaPrevious=iMA(NULL,0,MATrendPeriod,0,MODE_EMA,PRICE_CLOSE,1);

   total=OrdersTotal();
   if(total<1)
     {
      //--- no opened orders identified
      if(AccountFreeMargin()<(1000*Lots))
        {
         Print("We have no money. Free Margin = ",AccountFreeMargin());
         return;
        }
      //--- check for long position (BUY) possibility
      
      //--- вводим новую строку (снимает запрет на повторный вход, если открылся новый бар)
      if( (TimeCurrent() - Time_bar) > 900 ) Time_open = 900; 
      
      if(MacdCurrent<0 && MacdCurrent>SignalCurrent && MacdPrevious<SignalPrevious && 
         MathAbs(MacdCurrent)>(MACDOpenLevel*Point) && MaCurrent>MaPrevious && 
         (TimeCurrent()-Time[0])<Time_open) //вводим новую строку в алгоритм входа (выполнится только 1 раз, т.к. далее условие на данной свече невыполнимо)
        {
         ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0,Ask+TakeProfit*Point,"macd sample",16384,0,Green);
         if(ticket>0)
           {
            if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
             {
              Print("BUY order opened : ",OrderOpenPrice());
              Time_open = TimeCurrent()-Time[0]; //вводим новую строку (запоминаем интервал от времени открытия бара, на котором был вход, до момента входа)
              Time_bar = Time[0]; //вводим новую строку (запоминаем время открытия того бара, где был 1-й вход)
             }
           }
         else
            Print("Error opening BUY order : ",GetLastError());
         return;
        }

Подробнее:

Используем не абсолютное время (момент входа), а относительное — интервал времени от момента открытия текущей свечи до момента входа. И далее эту величину сравниваем с заранее заданной, достаточно большой величиной времени (длительности всей свечи), что позволяет сработать первому входу. В момент открытия позиции мы меняем (уменьшаем) величину переменной Time_open, записывая в нее значение интервала времени с начала свечи до момента фактического открытия. А так как в любой последующий момент времени значение (TimeCurrent() - Time[0]) будет больше величины, записанной нами в момент входа, то условие (TimeCurrent() - Time[0]) < Time_open становится невыполнимым, чем и достигается блокировка второго и следующих входов на данной свече.

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

Вот результат такой простой доработки исходного алгоритма входа эксперта ("MACD Sample_plus1"):

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

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


Решение в алгоритме выхода

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

Ранее мы использовали надежный параметр — фактор времени, снова воспользуемся им — жестко регламентируем момент закрытия позиции по времени, а именно в момент открытия следующей (после входа) свечи. Этот момент в алгоритме выхода отразим так:

if(!OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))
         continue;
      if(OrderType()<=OP_SELL &&   // check for opened position 
         OrderSymbol()==Symbol())  // check for symbol
        {
         //--- long position is opened
         if(OrderType()==OP_BUY)
           {
            //--- should it be closed?
            if(/* MacdCurrent>0 && MacdCurrent<SignalCurrent && MacdPrevious>SignalPrevious && // убираем код срабатывания выхода по MACD, чтобы не мешать новому условию закрытия (см. далее)
               MacdCurrent>(MACDCloseLevel*Point) &&
             */
               Bid > OrderOpenPrice() &&  // вводим новую строку - необязательно (цена в положительной области относительно уровня входа)
               TimeCurrent() == Time[0] ) // вводим новую строку (простая доработка алгоритма выхода: выход строго в момент открытия текущей свечи)
              {
               //--- close order and exit
               if(!OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet))
                  Print("OrderClose error ",GetLastError());

               return;
              }

Такая небольшая модификация позволит "работать" алгоритму входа (позиция открылась, условий для закрытия нет), позиция длится до момента TimeCurrent() == Time[0] и закрывается одномоментно в начале новой после импульса свечи. В результате, помимо защиты от дребезга, неплохо заработали (смотри фото, "MACD Sample_plus2"):

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

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


Увязка алгоритмов входа и выхода

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

Например, если вы используете в алгоритме выхода условие TimeCurrent() = Time[0], то есть точка выхода задана строго началом текущей свечи, то алгоритм входа должен отработать на предыдущих, завершенных барах, чтобы условие выхода смогло выполниться. То есть, чтобы закрыть позицию по условию TimeCurrent() = Time[0] без дополнительных условий, необходимо, чтобы весь алгоритм сравнения (на входе) был осуществлен (закончен) на предыдущем баре. Для этого в настройках индикаторов, участвующих в сравнении величин, должен быть сдвиг, равный 1. В этом случае сравнение величин будет корректным, а начало текущей свечи будет логичным завершением алгоритма выхода.

Таким образом, увязка алгоритмов входа и выхода также связана с фактором времени.


Заключение

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

Ниже представлены коды экспертов: в начальном виде (MACD_Sample.mq4), с доработанным входом (MACD_Sample_plus1.mq4), с доработанным выходом (MACD_Sample_plus2.mq4). Причем доработаны только каналы Buy, а каналы Sell намеренно оставлены без изменения, чтобы можно было сравнить исходные и доработанные алгоритмы.

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

Прикрепленные файлы |
MACD_Sample.mq4 (6.1 KB)
Последние комментарии | Перейти к обсуждению на форуме трейдеров (64)
Oleg Teselsky
Oleg Teselsky | 3 янв 2016 в 11:41
Andrey F. Zelinsky:

Ваш "принцип" откровенная неработоспособная ахинея.

Вот что вы предлагаете:

-- вы вводите некую переменную Time_open (секунды)

-- которая даёт возможность отработать сигнал только в пределах: от начала бара +  Time_open

-- если ордер открывается, то диапазон переменной  Time_open сужается 

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

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

И вся эта муть в Статьях, куда реально обращаются за правильными работоспособными идеями, решениями, подсказками, советами.

Нельзя такими "статьями" девальвировать ценность раздела. 

+++
Alexander Masterskikh
Alexander Masterskikh | 5 янв 2016 в 10:05

Олег и Андрей, вы действительно зациклены на желании не видеть очевидного.

Поэтому ваша критика - это действительно муть и ахинея.

Всё прекрасно работает на реальной торговой системе.

Igor Gerasimets
Igor Gerasimets | 22 янв 2016 в 22:48
Да простит меня автор, эта статья ни о чем. И жутко сложный алгоритм для оч простой вещи.
Bahrom Juraev
Bahrom Juraev | 27 янв 2016 в 19:32
Igor Gerasimets:
Да простит меня автор, эта статья ни о чем. И жутко сложный алгоритм для оч простой вещи.
Я с вами согласен. Процесс открытия ордера максимум 1 раз в пределах одного бара очень просто реализовать в очень коротком коде.
Sainidyl Olmi
Sainidyl Olmi | 21 июл 2016 в 12:02
Статья полезная как раз для такого новичка как я.  Более опытным коллегам она уже покажется сухой и скучной
Применение нечеткой логики в трейдинге средствами MQL4 Применение нечеткой логики в трейдинге средствами MQL4

В данной статье предлагаются примеры применения теории нечетких множеств в трейдинге средствами MQL4. Описывается разработка индикатора и советника с использованием библиотеки FuzzyNet для MQL4.

Price Action. Автоматизация торговли по паттерну "Поглощение" Price Action. Автоматизация торговли по паттерну "Поглощение"

В статье описывается создание советника для MetaTrader 4, торгующего по паттерну "Поглощение", включая принцип нахождения паттерна, правила установки отложенных и стоп-ордеров. Приведены результаты тестирования и оптимизации.

Создание ручных торговых стратегий с использованием нечеткой логики Создание ручных торговых стратегий с использованием нечеткой логики

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

Вклад Томаса Демарка в технический анализ Вклад Томаса Демарка в технический анализ

В статье описаны изобретенные Томасом Демарком TD-точки и TD-линии. Показано их применение на практике. Также продемонстрирован процесс написания трех индикаторов и двух экспертов с использованием идей Томаса Демарка.