Как сделать стрелочный индикатор?

 

Добрый день. Я новичок в программировании, поделитесь ссылкой на пример того как пишется стрелочный индикатор, желательно чтобы стрелки не перерисовывались. Нужно по стохастику и параболику обозначить стрелки там где выполняются условия входа. С чего начать? Нужен простой пример. Главное, чтобы объяснялось как сделать, чтобы стрелки не перерисовывались а оставались там где они должны быть при появлении сигнала.

Условия для сигнала такие:

Главная линия стохастика 8,3,3 достигла уровня 20..30 или 70..80, при этом параболик (шаг 0.01, максимум 0.1) должен быть соответственно ниже или выше цены, т.е. не пробитым обратно, чтобы стрелка отображала вход на откате цены в направлении тренда. Все это нужно определять по первому закрывшемуся бару, не по нулевому и не перерисовывать стрелку если следующий бар закрылся не пробив параболик но по стохастику тоже есть условия для входа. Сигнал выхода это пробой параболика. Вот такая простенькая система.

 
WebProger:
Добрый день. Я новичок в программировании, поделитесь ссылкой на пример того как пишется стрелочный индикатор, желательно чтобы стрелки не перерисовывались. Нужно по стохастику и параболику обозначить стрелки там где выполняются условия входа. С чего начать? Нужен простой пример. Главное, чтобы объяснялось как сделать, чтобы стрелки не перерисовывались а оставались там где они должны быть при появлении сигнала.

Условия входа (появлении стрелки).

Пример

Читаем

Здесь чтото похожее

 

Нашел кажется то, что нужно.

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

http://s003.radikal.ru/i202/1212/7b/646ae37c56a0.jpg

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

http://s019.radikal.ru/i610/1212/d9/af6a0fd70613.jpg

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

http://s020.radikal.ru/i721/1212/50/6e42df8cb346.jpg

Шаблон индикатора:

//|------------------------------------------------------------------|
 //| Indicator Arrow.mq4|
 //| Copyright © 2012, Mr.SilverKZ |
 //| SilverKZ@mail.kz |
 //+------------------------------------------------------------------+
 #property copyright "SilverKZ"
 #property link "SilverKZ@mail.kz"
 //---- отрисовка индикатора в главном окне
 #property indicator_chart_window
 //---- количество индикаторных буфферов
 #property indicator_buffers 2
 //---- цвета индикатора
 #property indicator_color1 Blue
 #property indicator_color2 Red
 //---- входные параметры индикатора
 extern int MA_Fast = 12;
 extern int MA_Slow = 26;
 //---- индикаторные буфферы
 double buf_1[];
 double buf_2[];
 //+------------------------------------------------------------------+
 //| Функция инициализации, запускается один раз |
 //+------------------------------------------------------------------+
 int init() 
 {
 //---- 2 индикаторных буффера использованы для счёта
 SetIndexBuffer(0, buf_1);
 SetIndexBuffer(1, buf_2);
 //---- Стиль исполнения графика 
 //---- DRAW_ARROW - стрелки(символы)
 SetIndexStyle (0, DRAW_ARROW, STYLE_SOLID, 3);
 SetIndexStyle (1, DRAW_ARROW, STYLE_SOLID, 3);
 SetIndexArrow (0, 233);
 SetIndexArrow (1, 234);
 //---- установка значений индикатора, которые не будут видимы на графике
 SetIndexEmptyValue(0,0.0);
 SetIndexEmptyValue(1,0.0);
 //---- установка номера бара, начиная с которого будет отрисовываться индикатор 
 SetIndexDrawBegin(0,MA_Slow);
 SetIndexDrawBegin(1,MA_Slow);
 //---- завершение инициализации
 return (0);
 }
 //+------------------------------------------------------------------+
 //| Основная Функция, запускается на каждом тике |
 //+------------------------------------------------------------------+
 int start() 
 {
 //---- проверка количества баров на достаточность для расчёта
 if (Bars <= MA_Slow) return (0);
 //---- получение уже посчитанных баров
 int ExtCountedBars = IndicatorCounted();
 //---- проверка на возможные ошибки
 if (ExtCountedBars < 0) return (-1);
 //---- последний посчитанный бар должен быть пересчитан 
 if (ExtCountedBars > 0) ExtCountedBars--;
 //---- основной цикл расчёта индиатора
 for (int i=Bars - ExtCountedBars-1;i>=0; i--)
 { 
 //---- получение значений индикатора в переменные
 double MA_Fast_1 = iMA(NULL, 0, MA_Fast, 0, MODE_EMA, PRICE_CLOSE, i+1);
 double MA_Slow_1 = iMA(NULL, 0, MA_Slow, 3, MODE_LWMA, PRICE_CLOSE, i+1);
 double MA_Fast_2 = iMA(NULL, 0, MA_Fast, 0, MODE_EMA, PRICE_CLOSE, i+2);
 double MA_Slow_2 = iMA(NULL, 0, MA_Slow, 3, MODE_LWMA, PRICE_CLOSE, i+2);
 //---- проверка условий по вашим правилам и отрисовка стрелки
 if (MA_Fast_1 > MA_Slow_1 && MA_Fast_2 <= MA_Slow_2) buf_1[i+1] = Low[i+1] - 10 * Point;
 if (MA_Fast_1 < MA_Slow_1 && MA_Fast_2 >= MA_Slow_2) buf_2[i+1] = High[i+1] + 10 * Point;
 }
 //---- завершение основной функции
 return (0);
 }
 //---- end

Вместо стрелок можно использовать другие символы. Для этого в данных строках необходимо заменить коды символов (233 и 234).

SetIndexArrow (0, 233);
SetIndexArrow (1, 234);
Коды символов:
http://s017.radikal.ru/i412/1212/07/6ba2d9530ca7.jpg

Для создания своего сигнальщика изменения вносите только в следующий код:
1)
//---- входные параметры индикатора
 extern int MA_Fast = 12;
 extern int MA_Slow = 26;

2)

//---- получение значений индикатора в переменные
 double MA_Fast_1 = iMA(NULL, 0, MA_Fast, 0, MODE_EMA, PRICE_CLOSE, i+1);
 double MA_Slow_1 = iMA(NULL, 0, MA_Slow, 3, MODE_LWMA, PRICE_CLOSE, i+1);
 double MA_Fast_2 = iMA(NULL, 0, MA_Fast, 0, MODE_EMA, PRICE_CLOSE, i+2);
 double MA_Slow_2 = iMA(NULL, 0, MA_Slow, 3, MODE_LWMA, PRICE_CLOSE, i+2);
 //---- проверка условий по вашим правилам и отрисовка стрелки
 if (MA_Fast_1 > MA_Slow_1 && MA_Fast_2 <= MA_Slow_2) buf_1[i+1] = Low[i+1] - 10 * Point;
 if (MA_Fast_1 < MA_Slow_1 && MA_Fast_2 >= MA_Slow_2) buf_2[i+1] = High[i+1] + 10 * Point;
 

Подскажите, почему через некоторое время, если не переключаться по таймфреймам, на графике появляются стрелки далеко не там, где нужно.

int start()
  {
  int spred = MarketInfo(Symbol(),MODE_SPREAD);
   //---- проверка количества баров на достаточность для расчёта
   if (Bars <= StartBar) return (0);
   //---- получение уже посчитанных баров
   int ExtCountedBars = IndicatorCounted();
   //---- проверка на возможные ошибки
   if (ExtCountedBars < 0) return (-1);
   //---- последний посчитанный бар должен быть пересчитан 
   if (ExtCountedBars > 0) ExtCountedBars--;
   //---- основной цикл расчёта индиатора
   
   for (int i=Bars - ExtCountedBars-1;i>=0; i--)
   { 
      //---- получение значений индикатора в переменные
      double PriceMA1 = iMA(NULL,0,MA3,0,MODE_SMA,PRICE_CLOSE,i);
      double PriceMA2 = iMA(NULL,0,MA3,0,MODE_SMA,PRICE_CLOSE,i+5);
      double sMain    = iStochastic(NULL, 0, perK, perD, Slow, MODE_SMA, 0, MODE_MAIN, i);
      double sMain2   = iStochastic(NULL, 0, perK, perD, Slow, MODE_SMA, 0, MODE_MAIN, i+1);
      double psar     = iSAR(NULL, 0, step, maximum, i);
      double psar2    = iSAR(NULL, 0, step, maximum, i+1);
      double MA       = 1;
      
      //---- проверка условий и отрисовка стрелки
      
      // BUY
      if(sMain2 <= min && psar < Low[i+1] && PriceMA2 < Close[i+1]) continue;
      if(sMain <= min && psar < Low[i] && PriceMA1 < Close[i])
      {
         buf1[i+2] = Close[i+1]+spred*Point;
      }
      
      //SELL
      if(sMain2 >= max && psar > High[i+1] && PriceMA2 > Close[i+1]) continue;
      if(sMain >= max && psar > High[i] && PriceMA1 > Close[i])
      {   
         buf2[i+2] = Close[i+1];
      }

   }   

Отображается так:


А должно быть так:

 
WebProger:

Подскажите, почему через некоторое время, если не переключаться по таймфреймам, на графике появляются стрелки далеко не там, где нужно.

Это мусор от других ТФ из-за того что нет начальной инициализации массива. Обнуляйте при первом старте и будет вам щасте
 

Спасибо. Есть еще один вопрос. Почему работают только два массива? Я добавлял условия для выхода, но стрелки не рисуются. Заменял просто buf1[i+2] на buf3[i+2] но 3-й не используются, несмотря на то, что он объявлен как и первые два.

 
Смотрите по коду, наверное есть ошибки, например буфер не добавлен.
 
WebProger:

Спасибо. Есть еще один вопрос. Почему работают только два массива? Я добавлял условия для выхода, но стрелки не рисуются. Заменял просто buf1[i+2] на buf3[i+2] но 3-й не используются, несмотря на то, что он объявлен как и первые два.

#property indicator_buffers    3 // количество буферов для расчета индикатора, максимум до 8
indicator_buffers()

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

 
artmedia70:

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


Я объявлял как 3 шт.

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

#property indicator_chart_window
 //---- количество индикаторных буфферов
#property indicator_buffers 3
#property indicator_width1 1
#property indicator_width2 1
#property indicator_width3 1
//---- цвета индикатора
#property indicator_color1 Blue
#property indicator_color2 Red
#property indicator_color3 Green
//---- входные параметры индикатора
//...

//---- индикаторные буфферы
double buf1[];
double buf2[];
double buf3[];
 
 
 //+------------------------------------------------------------------+
 //| Функция инициализации, запускается один раз                      |
 //+------------------------------------------------------------------+
int init()
  {
   //---- индикаторные буфферы использованы для счёта
   SetIndexBuffer(0,buf1);
   SetIndexBuffer(1,buf2);
   SetIndexBuffer(2,buf3);
   //---- Стиль исполнения графика 
   //---- DRAW_ARROW - стрелки(символы)
   SetIndexStyle (0,DRAW_ARROW,EMPTY,EMPTY);
   SetIndexStyle (1,DRAW_ARROW,EMPTY,EMPTY);
   SetIndexStyle (2,DRAW_ARROW,EMPTY,EMPTY);
   SetIndexArrow (0, 232);
   SetIndexArrow (1, 232);
   SetIndexArrow (2, 251);
   //---- установка значений индикатора, которые не будут видимы на графике
   SetIndexEmptyValue(0,0.0);
   SetIndexEmptyValue(1,0.0);
   SetIndexEmptyValue(2,0.0);
   //---- установка номера бара, начиная с которого будет отрисовываться индикатор 
   SetIndexDrawBegin(0,StartBar);
   SetIndexDrawBegin(1,StartBar);
   SetIndexDrawBegin(2,StartBar);
   //---- завершение инициализации
   return(0);
  }
 
TheXpert:
Это мусор от других ТФ из-за того что нет начальной инициализации массива. Обнуляйте при первом старте и будет вам щасте


Как-то так, перед циклом отрисовки стрелок?

   ArrayInitialize(buf1,0.0);
   ArrayInitialize(buf2,0.0);
   ArrayInitialize(buf3,0.0);
 
WebProger:

Как-то так, перед циклом отрисовки стрелок?

Да, но только самый первый раз.