Введение
В первой статье "Alert и Comment для внешних индикаторов" мы рассмотрели способ получения информации от индикаторов, которые используют в качестве источника информации значки из таблицы Wingdings, отображенные на графике.
Здесь мы рассмотрим, как можно получать значения из индикаторных буферов и использовать их для информирования пользователя о тех или иных событиях, происходящих в индикаторе.
Если для пользовательского считывания параметров графических построений есть группа операторов, с помощью которых можно получить требуемые характеристики, то параметры индикаторных буферов можно только задать. Здесь мы не можем получить, например, цвет. Все, что мы можем извлечь - это ценовые и временные характеристики. Для примера мы возьмем индикатор, который построен на принципе смены цвета при отображении на индикаторе.
Один из вариантов хранения информации в индикаторных буферах таких индикаторов организован таким образом, что для отображения одной линии используется два индикаторных буфера. Каждому буферу назначен статический цвет. А вывод информации организован таким образом, что в каждый момент времени в отображении участвует только один из двух буферов. В активном буфере значения параметра больше нуля. В неактивном буфере значение параметра равно нулю.
Таким образом, мы имеем значения, которые можно проанализировать и вывести информацию об изменении индикатора.
Вывод информации из индикаторных буферов
Средства MQL допускают ввод/вывод информации в восемь буферов индикатора.
Поэтому будем анализировать все восемь.
Условия для анализа следующие: При изменении значения индикатора с нулевого на значимое, а также при обратном изменении, т.е. при перемене со значимого на нулевой, необходимо информировать пользователя. Причем берем значение первого изменившегося индикаторного буфера. Попеременно проверяем значения всех буферов начиная с первого или иного бара, который укажет пользователь во внешней переменной
extern int StartBar=1; // Стартовый бар
Для примера возьмем индикатор Slope Trend_mtf, который выводит информацию следующим образом:

Рисунок 1
При нахождении изменения индикатор фиксирует это изменение и останавливается.
Для вывода информации есть средства MQL4, которые можно использовать для вывода:
- окна Алертов;
- комментариев в окне индикатора;
- для проигрывания музыкального файла.
Подпрограмма вывода информации будет выглядеть следующим образом.
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, он обладает достаточными возможностями для широкого использования его в программировании разнообразных торговых и информативных приложений. Плюс к тому - интуитивное изучение и огромная библиотека уже наработанного программного обеспечения.
Весь код информационного индикатора выглядит так:
#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 ");
int deinit()
{
for(int i=0;i<8;i++)
ObjectDelete(STRING_ID+"VL_"+i);
return(0);
}
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);
}
void AlertComment(string text)
{
if(SignalAlert==true) Alert(text);
if(SignalComment==true) Comment(text);
if(SignalPlay==true) PlaySound(Signal);
}