Не очень ясна логика принятия решений в Эксперте MQL5 при нескольких сигналах

 

День добрый!

Никак не получается скомбинировать 2 сигнала в Эксперте MQL5. Буду благодарен за любую помощь.

Сигнал 1 у меня свечной паттерн, а сигнал 2 - выше или ниже Moving Average.

Хочу отбирать только такие ситуации, когда есть свечной паттер и при этом цена выше MA.

Вот как я это себе представляю после чтения статей:

Оба сигнала имеют вес = 1

 Сигнал 1. Лонг = 100
 Сигнал 1. Шорт = 0
 Сигнал 2.Лонг = 100
 (100*1+100*1)/2=100 (100*1+0*1)/2=50
Сигнал 2. Шорт = 100
(-100*1+100*1)/2=0
(-100*1+0*1)/2=-50

Я думал, что если поставить TresholdOpen=90, то я получу только Сигнал1 Лог+Сигнал2 Лонг, но оказалось, что это не так и система срабатывает вообще на любой сигнал.

Поясните, пожалуйста, что я делаю не так?

Буду очень сильно благодарен Вам за помощь.

Евгений

 
varenich:

День добрый!

Никак не получается скомбинировать 2 сигнала в Эксперте MQL5. Буду благодарен за любую помощь.

Сигнал 1 у меня свечной паттерн, а сигнал 2 - выше или ниже Moving Average.

Хочу отбирать только такие ситуации, когда есть свечной паттер и при этом цена выше MA.

Вот как я это себе представляю после чтения статей:

Оба сигнала имеют вес = 1

 Сигнал 1. Лонг = 100
 Сигнал 1. Шорт = 0
 Сигнал 2.Лонг = 100
 (100*1+100*1)/2=100 (100*1+0*1)/2=50
Сигнал 2. Шорт = 100
(-100*1+100*1)/2=0
(-100*1+0*1)/2=-50

Я думал, что если поставить TresholdOpen=90, то я получу только Сигнал1 Лог+Сигнал2 Лонг, но оказалось, что это не так и система срабатывает вообще на любой сигнал.

Поясните, пожалуйста, что я делаю не так?

Буду очень сильно благодарен Вам за помощь.

Евгений

В таблице изначальные ошибки: или Вы неправильно сконструировали модули сигналов или неправильно представили в виде таблицы. Взять хотя бы первый столбец: в парадигме конструирования модулей сигналов не может быть таких условий "Сигнал 2.Лонг = 100" и "Сигнал 2. Шорт = 100" - в модуле сигналов есть МОДЕЛИ (паттерны/Pattern_ххх).

Покажите, пожалуйста, код из обоих модулей:

  1. часть где видно, сколько моделей в модуле, 
  2. объявление методов для моделей и 
  3. инициализация моделей. 
На примере модуля сигналов "SignalMA.mqh" это такие блоки кода:


  1.    //--- "weights" of market models (0-100)
       int               m_pattern_0;      // model 0 "price is on the necessary side from the indicator"
       int               m_pattern_1;      // model 1 "price crossed the indicator with opposite direction"
       int               m_pattern_2;      // model 2 "price crossed the indicator with the same direction"
       int               m_pattern_3;      // model 3 "piercing"

  2.    //--- methods of adjusting "weights" of market models
       void              Pattern_0(int value)                { m_pattern_0=value;          }
       void              Pattern_1(int value)                { m_pattern_1=value;          }
       void              Pattern_2(int value)                { m_pattern_2=value;          }
       void              Pattern_3(int value)                { m_pattern_3=value;          }

  3. //+------------------------------------------------------------------+
    //| Constructor                                                      |
    //+------------------------------------------------------------------+
    CSignalMA::CSignalMA(void) : m_ma_period(12),
                                 m_ma_shift(0),
                                 m_ma_method(MODE_SMA),
                                 m_ma_applied(PRICE_CLOSE),
                                 m_pattern_0(80),
                                 m_pattern_1(10),
                                 m_pattern_2(60),
                                 m_pattern_3(60)
      {
 
Karputov Vladimir:

В таблице изначальные ошибки: или Вы неправильно сконструировали модули сигналов или неправильно представили в виде таблицы. Взять хотя бы первый столбец: в парадигме конструирования модулей сигналов не может быть таких условий "Сигнал 2.Лонг = 100" и "Сигнал 2. Шорт = 100" - в модуле сигналов есть МОДЕЛИ (паттерны/Pattern_ххх).

Покажите, пожалуйста, код из обоих модулей:

  1. часть где видно, сколько моделей в модуле, 
  2. объявление методов для моделей и 
  3. инициализация моделей. 
На примере модуля сигналов "SignalMA.mqh" это такие блоки кода:


  1.    //--- "weights" of market models (0-100)
       int               m_pattern_0;      // model 0 "price is on the necessary side from the indicator"
       int               m_pattern_1;      // model 1 "price crossed the indicator with opposite direction"
       int               m_pattern_2;      // model 2 "price crossed the indicator with the same direction"
       int               m_pattern_3;      // model 3 "piercing"

  2.    //--- methods of adjusting "weights" of market models
       void              Pattern_0(int value)                { m_pattern_0=value;          }
       void              Pattern_1(int value)                { m_pattern_1=value;          }
       void              Pattern_2(int value)                { m_pattern_2=value;          }
       void              Pattern_3(int value)                { m_pattern_3=value;          }

  3. //+------------------------------------------------------------------+
    //| Constructor                                                      |
    //+------------------------------------------------------------------+
    CSignalMA::CSignalMA(void) : m_ma_period(12),
                                 m_ma_shift(0),
                                 m_ma_method(MODE_SMA),
                                 m_ma_applied(PRICE_CLOSE),
                                 m_pattern_0(80),
                                 m_pattern_1(10),
                                 m_pattern_2(60),
                                 m_pattern_3(60)
      {

Владимир, спасибо, что откликнулись.

Код смогу только сегодня вечером сюда поставить, но суть его в следующем:

 ==================

Сигнал1.mqh

 

Сигнал1::LongCondition()  {

если (две красных свечи) return (100);

иначе return(0); 

================== 

Сигнал2.mqh

 

Сигнал2::LongCondition()  {

если (цена выше MA) return (100);

иначе return(0); 

Сигнал2::ShortCondition()  {

если (цена ниже MA) return (100);

иначе return(0); 


=================

Комбинируя их через Эксперта MQL5 я надеялся входить в лонг когда возникли две красных свечи и цена выше MA. 

 

Что касается паттернов, то я понял их просто как разную силу сигнала, которую возвращаю функции LongCondition/ShortCondition.  В моём случае это не совсем актуально, если я правильно понимаю. 

 
varenich:

Владимир, спасибо, что откликнулись.

Код смогу только сегодня вечером сюда поставить, но суть его в следующем:

 ==================

Сигнал1.mqh

 

Сигнал1::LongCondition()  {

если (две красных свечи) return (100);

иначе return(0); 

================== 

Сигнал2.mqh

 

Сигнал2::LongCondition()  {

если (цена выше MA) return (100);

иначе return(0); 

Сигнал2::ShortCondition()  {

если (цена ниже MA) return (100);

иначе return(0); 


=================

Комбинируя их через Эксперта MQL5 я надеялся входить в лонг когда возникли две красных свечи и цена выше MA. 

 

Что касается паттернов, то я понял их просто как разную силу сигнала, которую возвращаю функции LongCondition/ShortCondition.  В моём случае это не совсем актуально, если я правильно понимаю. 

Не знаю, точно ли у Вас увязаны друг с другом изложенный логический код и таблица из первого поста, но пока я вижу явные отличия. Здесь при всех вариантах после проверки услоовий вы возвращаете либо 100, либо 0, а в таблице в посте 1 у Вас фигурируют 3 возращаемых значения: 100 и 0 для первой стратегии, и 100 и (-100) - для второй. При этом, если Вы подставите 0 в Вашу таблицу вместо (-100), то будете получать совсем другие суммарные значения.
 
BlackTomcat:
Не знаю, точно ли у Вас увязаны друг с другом изложенный логический код и таблица из первого поста, но пока я вижу явные отличия. Здесь при всех вариантах после проверки услоовий вы возвращаете либо 100, либо 0, а в таблице в посте 1 у Вас фигурируют 3 возращаемых значения: 100 и 0 для первой стратегии, и 100 и (-100) - для второй. При этом, если Вы подставите 0 в Вашу таблицу вместо (-100), то будете получать совсем другие суммарные значения.
Как я понял из статей, метод ShortCondition должен возвращать целое положительное значение и при подсчете итогового рейтинга ему автоматически присваивается минус. Хотя тут могу быть неправым - точного подтверждения пока не нашел нигде.
 
varenich:
Как я понял из статей, метод ShortCondition должен возвращать целое положительное значение и при подсчете итогового рейтинга ему автоматически присваивается минус. Хотя тут могу быть неправым - точного подтверждения пока не нашел нигде.

Сейчас смотрю на таблицу и понимаю, что должен:

1) Попробовать возвращать -100 в ShortCondition

2) Т.к. в Сигнале 1 у меня просто-напросто нет ShortCondition, то вполне может быть, что Эксперт вообще его учитывает и считает среднее арифметическое только по одному сигналу - Сигналу 2. В этом случае получается, что Шорт у меня всегда будет -100. Спасибо, что навели на мысль!

Попробую создать ShortCondition у Сигнала 1. Тогда среднее арифметическое должно будет считаться по двум сигналам.

 
varenich:

Сейчас смотрю на таблицу и понимаю, что должен:

1) Попробовать возвращать -100 в ShortCondition

2) Т.к. в Сигнале 1 у меня просто-напросто нет ShortCondition, то вполне может быть, что Эксперт вообще его учитывает и считает среднее арифметическое только по одному сигналу - Сигналу 2. В этом случае получается, что Шорт у меня всегда будет -100. Спасибо, что навели на мысль!

Попробую создать ShortCondition у Сигнала 1. Тогда среднее арифметическое должно будет считаться по двум сигналам.

Опять таки на примере сигнала "SignalMA.mqh": никто в методах ShortCondition() и LongCondition() не возвращает отрицательные значения! Вот код, обратите внимание, что здесь возвращается:

//+------------------------------------------------------------------+
//| "Voting" that price will fall.                                   |
//+------------------------------------------------------------------+
int CSignalMA::ShortCondition(void)
  {
   int result=0;
   int idx   =StartIndex();
//--- analyze positional relationship of the close price and the indicator at the first analyzed bar
   if(DiffCloseMA(idx)>0.0)
     {
      //--- the close price is above the indicator
      if(IS_PATTERN_USAGE(1) && DiffOpenMA(idx)<0.0 && DiffMA(idx)<0.0)
        {
         //--- the open price is below the indicator (i.e. there was an intersection), but the indicator is directed downwards
         result=m_pattern_1;
         //--- consider that this is an unformed "piercing" and suggest to enter the market at the current price
         m_base_price=0.0;
        }
     }
   else
     {
      //--- the close price is below the indicator (the indicator has no objections to buying)
      if(IS_PATTERN_USAGE(0))
         result=m_pattern_0;
      //--- the indicator is directed downwards
      if(DiffMA(idx)<0.0)
        {
         if(DiffOpenMA(idx)>0.0)
           {
            //--- if the model 2 is used
            if(IS_PATTERN_USAGE(2))
              {
               //--- the open price is above the indicator (i.e. there was an intersection)
               result=m_pattern_2;
               //--- suggest to enter the market at the "roll back"
               m_base_price=m_symbol.NormalizePrice(MA(idx));
              }
           }
         else
           {
            //--- if the model 3 is used and the open price is below the indicator
            if(IS_PATTERN_USAGE(3) && DiffHighMA(idx)>0.0)
              {
               //--- the high price is above the indicator
               result=m_pattern_3;
               //--- consider that this is a formed "piercing" and suggest to enter the market at the current price
               m_base_price=0.0;
              }
           }
        }
     }
//--- return the result
   return(result);
  }

А значения моделей инициализировались ранее:

//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CSignalMA::CSignalMA(void) : m_ma_period(12),
                             m_ma_shift(0),
                             m_ma_method(MODE_SMA),
                             m_ma_applied(PRICE_CLOSE),
                             m_pattern_0(80),
                             m_pattern_1(10),
                             m_pattern_2(60),
                             m_pattern_3(60)
  {

То есть никто в методах ShortCondition() и LongCondition() не возвращает отрицательные значения! Отрицательные значения получаются в недрах сигналов и это скрыто от пользователя - это как служебные расчёты, поэтому Вы должны в методах ShortCondition() и LongCondition() возвращать положительные значения.
 

 

В первом посте у вас всё правильно написано, так и должно работать.
Если функции ShortCondition() у вас нету то по дефолту будет возвращаться просто 0, так что с этим всё ок. Создавать свою функцию ShortCondition() и возвращать -100 точно не нужно, это сломает всю логику в стандартных классах, сигнал должен быть от 0 до 100. У вас проблемы где-то в коде в других местах.

Дописал:
Я чота повторил Владимира :) 
Я просто пока написал ответ и нажал кнопку отправить, прошло куча времени, его ответ я тогда ещё не видел.

 
Karputov Vladimir:

Опять таки на примере сигнала "SignalMA.mqh": никто в методах ShortCondition() и LongCondition() не возвращает отрицательные значения! Вот код, обратите внимание, что здесь возвращается:

//+------------------------------------------------------------------+
//| "Voting" that price will fall.                                   |
//+------------------------------------------------------------------+
int CSignalMA::ShortCondition(void)
  {
   int result=0;
   int idx   =StartIndex();
//--- analyze positional relationship of the close price and the indicator at the first analyzed bar
   if(DiffCloseMA(idx)>0.0)
     {
      //--- the close price is above the indicator
      if(IS_PATTERN_USAGE(1) && DiffOpenMA(idx)<0.0 && DiffMA(idx)<0.0)
        {
         //--- the open price is below the indicator (i.e. there was an intersection), but the indicator is directed downwards
         result=m_pattern_1;
         //--- consider that this is an unformed "piercing" and suggest to enter the market at the current price
         m_base_price=0.0;
        }
     }
   else
     {
      //--- the close price is below the indicator (the indicator has no objections to buying)
      if(IS_PATTERN_USAGE(0))
         result=m_pattern_0;
      //--- the indicator is directed downwards
      if(DiffMA(idx)<0.0)
        {
         if(DiffOpenMA(idx)>0.0)
           {
            //--- if the model 2 is used
            if(IS_PATTERN_USAGE(2))
              {
               //--- the open price is above the indicator (i.e. there was an intersection)
               result=m_pattern_2;
               //--- suggest to enter the market at the "roll back"
               m_base_price=m_symbol.NormalizePrice(MA(idx));
              }
           }
         else
           {
            //--- if the model 3 is used and the open price is below the indicator
            if(IS_PATTERN_USAGE(3) && DiffHighMA(idx)>0.0)
              {
               //--- the high price is above the indicator
               result=m_pattern_3;
               //--- consider that this is a formed "piercing" and suggest to enter the market at the current price
               m_base_price=0.0;
              }
           }
        }
     }
//--- return the result
   return(result);
  }

А значения моделей инициализировались ранее:

//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CSignalMA::CSignalMA(void) : m_ma_period(12),
                             m_ma_shift(0),
                             m_ma_method(MODE_SMA),
                             m_ma_applied(PRICE_CLOSE),
                             m_pattern_0(80),
                             m_pattern_1(10),
                             m_pattern_2(60),
                             m_pattern_3(60)
  {

То есть никто в методах ShortCondition() и LongCondition() не возвращает отрицательные значения! Отрицательные значения получаются в недрах сигналов и это скрыто от пользователя - это как служебные расчёты, поэтому Вы должны в методах ShortCondition() и LongCondition() возвращать положительные значения.
 

Значит я правильно понял статьи. Спасибо за примеры.

 

Остается один вариант - добавить ShortCondition в Сигнал 1. 

 
Dr.Trader:
В первом посте у вас всё правильно написано, так и должно работать.
Если функции ShortCondition() у вас нету то по дефолту будет возвращаться просто 0, так что с этим всё ок. Создавать свою функцию ShortCondition() и возвращать -100 точно не нужно, это сломает всю логику в стандартных классах, сигнал должен быть от 0 до 100. У вас проблемы где-то в коде в других местах.

У меня другого кода просто нет.  

Могу сегодня чуть позже привести пример, но он будет точно таким же. 

 

А ларчик просто открывался. У меня не стояла проверка, что MA >0.

Сделал и всё заработало как надо.