Alert и Comment для внешних индикаторов (часть вторая)

Vladimir | 3 июля, 2009

Введение

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

Здесь мы рассмотрим, как можно получать значения из индикаторных буферов и использовать их для информирования пользователя о тех или иных событиях, происходящих в индикаторе.

Если для пользовательского считывания параметров графических построений есть группа операторов, с помощью которых можно получить требуемые характеристики, то параметры индикаторных буферов можно только задать. Здесь мы не можем получить, например, цвет. Все, что мы можем извлечь - это ценовые и временные характеристики. Для примера мы возьмем индикатор, который построен на принципе смены цвета при отображении на индикаторе.
Один из вариантов хранения информации в индикаторных буферах таких индикаторов организован таким образом, что для отображения одной линии используется два индикаторных буфера. Каждому буферу назначен статический цвет. А вывод информации организован таким образом, что в каждый момент времени в отображении участвует только один из двух буферов. В активном буфере значения параметра больше нуля. В неактивном буфере значение параметра равно нулю.

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


Вывод информации из индикаторных буферов

Средства MQL допускают ввод/вывод информации в восемь буферов индикатора.
Поэтому будем анализировать все восемь.

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

extern int     StartBar=1;       // Стартовый бар

Для примера возьмем индикатор Slope Trend_mtf, который выводит информацию следующим образом:


Рисунок 1

При нахождении изменения индикатор фиксирует это изменение и останавливается.

Для вывода информации есть средства MQL4, которые можно использовать для вывода:

Подпрограмма вывода информации будет выглядеть следующим образом.

//+------------------------------------------------------------------+
//| AlertSignal_v1 indicator Subfunction                             |
//+------------------------------------------------------------------+

void AlertComment (string text)
   {
      if (SignalAlert   == true)    Alert    (text);
      if (SignalComment == true)    Comment  (text);
      if (SignalPlay    == true)    PlaySound(Signal);
   }

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

Предусмотрим так же возможность выведения пользовательского комментария по выбору пользователя

extern int     StartBar=1;                            // Стартовый бар
extern string  indicator = "Insert Indicator Name";   // Пользовательский индикатор
extern bool    VLine = true;                          // Переключатель вывода вертикальных линий
extern bool    SignalAlert=false;                     // Переключатель вывода "Алертов"
extern bool    SignalComment=true;                    // Переключатель вывода "Комментов"
extern bool    SignalPlay= false;                     // Переключатель проигрывания мелодии
extern string  Signal = "alert.wav";                  // Музыкальный файл пользователя
extern string  UserText = "изменил направление";      // Комментарий пользователя

где:

StartBar

Переменная, назначенная для указания начала расчета:

indicator 

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

Далее идет серия логических параметров, с помощью которых пользователь может оперировать выводом соответствующих параметров программы.

VLine 

Выводить - true - или не выводить - false - вертикальную линию в точке изменения параметров индикатора.

SignalAlert

Выводить - true - или не выводить - false - информационное окно при изменении параметров индикатора.

SignalComment

Выводить - true - или не выводить - false - информацию на график при изменении параметров индикатора.

SignalPlay

Проигрывать - true или не проигрывать - false музыкальный файл при изменении параметров индикатора.

Signal 

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

UserText 

В это окно мы вводим текст, который желаем видеть на графике при изменении параметров индикатора, если стандартный нас не устраивает.

Аналогично можно ввести параметр для отправки информации на email.

Теперь нам остается только считать данные из индикатора и обработать их с помощью наших настроек.

Сам код блока обработки будет выглядеть так:

   for(int ii=StartBar;ii<ExtBars;ii++)
      for(int i=0;i<8;i++)
        {
         First =iCustom(NULL,0,indicator,i,ii);
         Second=iCustom(NULL,0,indicator,i,ii+1);
         if((Second==0 && First>0) || (Second>0 && First==0))
           {
            text=StringConcatenate(Str+" -  На ",ii+1," баре ",Symbol()," -  ",indicator," ");
            AlertComment(text+UserText);
            if(VLine==true)
               ObjectCreate(STRING_ID+"VL_"+i,0,0,Time[ii],Bid);
            return;
           }
        }

Применив указанный подход и указав в параметрах вывод вертикальной линии, мы получим такой вид на графике:


Рисунок 2


Заключение

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

Весь код информационного индикатора выглядит так:

//+------------------------------------------------------------------+
//|                                               AlertSignal_v1.mq4 |
//|                                  Copyright © 2009, WWW.FIBOOK.RU |
//|                                                 http://fibook.ru |
//+------------------------------------------------------------------+
#property copyright  "Copyright © 2009, FIBOOK.RU"
#property link       "http://fibook.ru"
#define Str           "http://fibook.ru"
#define STRING_ID    "AlertSignal_"
#property indicator_chart_window
extern int     StartBar=1;                       // Стартовый бар
extern string indicator="Insert Indicator Name"; // Пользовательский индикатор
extern bool    VLine=true;                       // Переключатель вывода вертикальных линий
extern bool    SignalAlert=false;                // Переключатель вывода "Алертов"
extern bool    SignalComment=true;               // Переключатель вывода "Комментов"
extern bool    SignalPlay=false;                 // Переключатель проигрывания мелодии
extern string  Signal="alert.wav";               // Музыкальный файл пользователя
extern string  UserText="изменил направление";   // Комментарий пользователя
IndicatorShortName("AlertSignal_v1 ");
//+------------------------------------------------------------------+
//| AlertSignal_v1 indicator deinitialization function               |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   for(int i=0;i<8;i++)
      ObjectDelete(STRING_ID+"VL_"+i);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| AlertSignal_v1 indicator iteration function                      |
//+------------------------------------------------------------------+
int start()
  {
   string     text;
   int        ExtBars=150;  // Количество последних баров для расчета
   double     First;        // Внутренняя переменная
   double     Second;       // Внутренняя переменная
   int        per;          // Внутренняя переменная
   if(indicator=="Insert Indicator Name")
     {
      Alert(indicator);
      return;
     }
   if(per==Time[0]) return; // Корректируем один раз в период
   per=Time[0];
//----
   for(int ii=StartBar;ii<ExtBars;ii++)
      for(int i=0;i<8;i++)
        {
         First =iCustom(NULL,0,indicator,i,ii);
         Second=iCustom(NULL,0,indicator,i,ii+1);
         if((Second==0 && First>0) || (Second>0 && First==0))
           {
            text=StringConcatenate(Str+" - На ",ii+1," баре ",Symbol()," -  ",indicator," ");
            AlertComment(text+UserText);
            if(VLine==true)
               ObjectCreate(STRING_ID+"VL_"+i,0,0,Time[ii],Bid);
            return;
           }
        }
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| AlertSignal_v1 indicator Subfunction                             |
//+------------------------------------------------------------------+

void AlertComment(string text)
  {
   if(SignalAlert==true) Alert(text);
   if(SignalComment==true) Comment(text);
   if(SignalPlay==true) PlaySound(Signal);
  }
//+------------------------------------------------------------------+