Как получить цену закрытия бара на котором пересеклись МАшки

Программирование прибыли: от азов к секретам мастерства. Читайте, спрашивайте, делитесь опытом.
Бонус за сообщение 0.5$
Ответственный Модератор - Haos

Как получить цену закрытия бара на котором пересеклись МАшки

Сообщение Haos » 02 сен 2016, 11:29

Иногда в торговой системе, применяющие скользящие средние необходимо определить не факт пересечения скользящих средних, а цену (закрытия бара) на котором произошло пересечение.
В функции, приведенной ниже, решается эта задача. При этом, может быть возвращена цена не только последнего пересечения, но и заданного по номеру. Т.е. 1- последнее пересечение, 2 - второе назад пересечение, ... , 20 - двадцатое назад пересечение и т.д. Можно также задавать условие какое именно по типу пересечение нужно (на покупку, на продажу, любое).
Код: выделить все
double f_GetPriceMACross(int pef, int pes, int mef, int mes, int apf, int aps, string ty, int shi)
{
/*
   Описание:
   Функция возвращает цену закрытия бара, на котором пересеклись скользящие средние. Если
   таковая не была найдена, то функция вернет -1.
   Параметры:
   pef - период быстрой МАшки
   pes - период медленной МАшки
   mef - метод усреднения быстрой МАшки
   mes - метод усреднения медленной МАшки
   apf - тип цены быстрой МАшки
   aps - тип цены медленной МАшки
   ty  - тип пересечения (на покупку - "B", или продажу - "S" или любое - "A")
   shi - номер пересечения МАшек (от последнего к началу, т.е. 1 - последние пересечение)
*/
   double   dblMAF_1,      // значение быстрой MA на i-ом баре
            dblMAF_2,      // значение быстрой MA на i + 1 баре
            dblMAS_1,      // значение медленной MA на i-ом баре
            dblMAS_2;      // значение медленной MA i + 1 баре
   bool     bol_B,
            bol_S;       
   int      int_N = 0;    // кол-во найденных пересечений
     
   for(int i = 1; i < Bars - pes - 2; i++)
   {
      dblMAF_1 = iMA(NULL, 0, pef, 0, mef, apf, i);
      dblMAF_2 = iMA(NULL, 0, pef, 0, mef, apf, i + 1);
      dblMAS_1 = iMA(NULL, 0, pes, 0, mes, apf, i);
      dblMAS_2 = iMA(NULL, 0, pes, 0, mes, apf, i + 1);
     
      if((dblMAF_1 > dblMAS_1) && (dblMAF_2 < dblMAS_2)) bol_B = true;
      else bol_B = false;
      if((dblMAF_1 < dblMAS_1) && (dblMAF_2 > dblMAS_2)) bol_S = true;
      else bol_S = false;
           
      if(ty == "B") 
      {
         if(bol_B)
         {
            int_N++;
            if(int_N == shi) return(Close[i]);
         }
      }
      else if(ty == "S")
      {
         if(bol_S)
         {
            int_N++;
            if(int_N == shi) return(Close[i]);
         }     
      }
      else if(ty == "A")
      {
         if(bol_B || bol_S)
         {
            int_N++;
            if(int_N == shi) return(Close[i]);
         }     
      }
   }

return(-1);
}

На рисунке ниже видно как советник, использующий данную функцию выводит в комментарий значение цены закрытия бара на котором произошло 2-ое назад пересечение скользящих средних на покупку:
Вложения
03.png
Аватар пользователя
Haos
Специалист MQL
 
Сообщений: 24699
Зарегистрирован: 29 мар 2014, 16:07
Средств на руках: 193.70 Доллар
Группа: Главные модераторы
Благодарил (а): 3379 раз.
Поблагодарили: 8200 раз.

Как получить цену закрытия бара на котором пересеклись МАшки

Сообщение Paramon » 02 сен 2016, 13:31

Спасибо. Весьма практичный пример. Хотел уточнить:

return(-1); - это как я понимаю функция возврата к началу, то есть зацикливание операции? Или нет? Если да, то в рамках полноценного торгового советника эта функция все равно тут будет прописываться?
Аватар пользователя
Paramon
 
Сообщений: 730
Зарегистрирован: 15 авг 2013, 07:55
Средств на руках: 147.03 Доллар
Награды: 1
Ветеран II (1)
Группа: Базовая
Благодарил (а): 224 раз.
Поблагодарили: 75 раз.

Re: Как получить цену закрытия бара на котором пересеклись МАшки

Сообщение Haos » 02 сен 2016, 13:35

Paramon писал(а):Спасибо. Весьма практичный пример. Хотел уточнить:
return(-1); - это как я понимаю функция возврата к началу, то есть зацикливание операции? Или нет? Если да, то в рамках полноценного торгового советника эта функция все равно тут будет прописываться?

В данной функции return(-1) , т.е. возврат минус единицы произойдет если не сработал ни один случай, анализируемый функцией, по каким-то причинам. Т.е. не получено искомое значение цены нужного пересечения. Таким образом, минус единица - это всего лишь удобный способ понять что функция не нашла искомое значение.
Аватар пользователя
Haos
Специалист MQL
 
Сообщений: 24699
Зарегистрирован: 29 мар 2014, 16:07
Средств на руках: 193.70 Доллар
Группа: Главные модераторы
Благодарил (а): 3379 раз.
Поблагодарили: 8200 раз.

Как получить цену закрытия бара на котором пересеклись МАшки

Сообщение Haos » 23 июл 2019, 07:52

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

Несколько преобразуем написанную выше функцию:
Код: выделить все
string f_GetTypeMACross(int pef, int pes, int mef, int mes, int apf, int aps, int shi)
{
/*
   Описание:
   Функция возвращает тип пересечения скользящих средних по номеру.
   Если пересечений по номеру не было, то функция вернет "NO".
   Параметры:
   pef - период быстрой МАшки
   pes - период медленной МАшки
   mef - метод усреднения быстрой МАшки
   mes - метод усреднения медленной МАшки
   apf - тип цены быстрой МАшки
   aps - тип цены медленной МАшки
   shi - номер пересечения МАшек (от последнего к началу, т.е. 1 - последние пересечение)
*/
   double   dblMAF_1,      // значение быстрой MA на i-ом баре
            dblMAF_2,      // значение быстрой MA на i + 1 баре
            dblMAS_1,      // значение медленной MA на i-ом баре
            dblMAS_2;      // значение медленной MA i + 1 баре
   bool     bol_B,
            bol_S;       
   int      int_N = 0;    // кол-во найденных пересечений
     
   for(int i = 1; i < Bars - pes - 2; i++)
   {
      dblMAF_1 = iMA(NULL, 0, pef, 0, mef, apf, i);
      dblMAF_2 = iMA(NULL, 0, pef, 0, mef, apf, i + 1);
      dblMAS_1 = iMA(NULL, 0, pes, 0, mes, apf, i);
      dblMAS_2 = iMA(NULL, 0, pes, 0, mes, apf, i + 1);
     
      if((dblMAF_1 > dblMAS_1) && (dblMAF_2 < dblMAS_2)) bol_B = true;
      else bol_B = false;
      if((dblMAF_1 < dblMAS_1) && (dblMAF_2 > dblMAS_2)) bol_S = true;
      else bol_S = false;

      if(bol_B)
      {
         int_N++;
         if(int_N == shi) return("B");
      }
      if(bol_S)
      {
         int_N++;
         if(int_N == shi) return("S");
      }     
   }

return("NO");
}

Теперь функция будет возвращать значение типа string, т.е. строковое. Как обычно, я использую символику значений: "В" - покупка, "S" - продажа, "NO" - нет сигнала.
Параметры, передающиеся в функцию, аналогичны тем, что были в функции, написанной ранее.
Аватар пользователя
Haos
Специалист MQL
 
Сообщений: 24699
Зарегистрирован: 29 мар 2014, 16:07
Средств на руках: 193.70 Доллар
Группа: Главные модераторы
Благодарил (а): 3379 раз.
Поблагодарили: 8200 раз.

Как получить цену закрытия бара на котором пересеклись МАшки

Сообщение Haos » 23 июл 2019, 07:58

Для чего вообще данный код может быть использован? Например, как часть кода для анализа того как вел себя эксперт после получения сигнала. Например, сигнал был несколько баров назад, при этом советник не открыл сделку по какой-то причине. Зная каким был последний сигнал и проверив наличие позиции, можно контролировать её открытие (закрытие).
Аналогично пересечению скользящих средних данный подход может быть распространен на любые сигналы индикаторов. Тем самым приобретается контроль над ситуацией не только в момент поступления сигнала, но и между сигналами на нескольких барах.
Аватар пользователя
Haos
Специалист MQL
 
Сообщений: 24699
Зарегистрирован: 29 мар 2014, 16:07
Средств на руках: 193.70 Доллар
Группа: Главные модераторы
Благодарил (а): 3379 раз.
Поблагодарили: 8200 раз.


Вернуться в MQL – теория и практика

Кто сейчас на форуме?

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 49

Права доступа к форуму

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения