Русский

Учебник по MQL4  Создание обычной программы  Информационная функция

Информационная функция


Обычный эксперт, используемый в практической работе, выгодно отличается от своих простых аналогов тем, что предоставляет трейдеру качественное информационное сопровождение.

Во время торгов ситуация всё время меняется, происходят различные события. Для того чтобы принимать правильные торговые решения, трейдеру необходимо быть в полной мере информированным. С этой целью в экспертах используются различные функции, назначение которых - довести до сведения пользователя некоторый набор информации.

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

Здесь рассматривается принципиально иной метод вывода информации - все сообщения выводятся в отдельное окно, а для формирования текстов сообщений используются графические объекты. Применение графических объектов даёт ощутимое преимущество, т.к. объекты (в отличие от текстов, выводимых с помощью Comment()) можно перемещать, создавая, таким образом, историю сообщений.

Отдельное подокно для вывода информации создаётся с помощью пользовательского индикатора с соответствующей настройкой. Единственным назначением этого индикатора является создание подокна, поэтому в индикаторе не выполняются никакие вычисления, не ставится также цель построения индикаторных линий. Код индикатора Inform.mq4 может выглядеть так:

//--------------------------------------------------------------------
// Inform.mq4
// Предназначен для использования в качестве примера в учебнике MQL4.
//--------------------------------------------------------------------
#property indicator_separate_window // Отдельное окно индикатора
//--------------------------------------------------------------------
int start() // Специальная функция start()
{
}
//--------------------------------------------------------------------

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


Пользовательская функция Inform()

int Inform(int Mess_Number,int Number=0,double Value=0.0)

Функция выводит сообщения, созданные с помощью графических объектов, в подокно индикатора Inform.mq4. Функция управляет положением графических объектов в подокне индикатора: каждое новое сообщение выводится в нижнюю часть окна (нижнюю строку) и окрашивается нужным цветом, при этом ранее выведенные сообщения перемещаются в верхнюю часть окна (на одну строку выше). Если в течение 15 секунд не было выведено новых сообщений, то при обращении к функции все ранее выведенные сообщения окрашиваются в серый цвет (чтобы не отвлекать внимание пользователя).

Параметры:

Mess_Number - номер сообщения, может принимать следующие значения:

  • (ноль) 0 - сообщение не выводится, режим используется для сброса счётчика времени;
  • (минус единица) -1 - все графические объекты, созданные функцией, удаляются;
  • (единица и более) - номер сообщения, которое необходимо вывести в подокно индикатора;

Number - целое число, используемое в некоторых сообщениях;

Value - действительное число, используемое в некоторых сообщениях.

Функция Inform(), создающая графические объекты, как и другие функции в обычном эксперте, оформлена в виде включаемого файла Inform.mqh:

//--------------------------------------------------------------------
// Inform.mqh
// Предназначен для использования в качестве примера в учебнике MQL4.
//--------------------------------------------------------------- 1 --
// Функция вывода на экран графических сообщений.
//--------------------------------------------------------------- 2 --
int Inform(int Mess_Number, int Number=0, double Value=0.0)
{
// int Mess_Number // Номер сообщения
// int Number // Передаваемое целое значение
// double Value // Передаваемое действит. знач.
int Win_ind; // Номер окна индикатора
string Graf_Text; // Строка сообщения
color Color_GT; // Цвет строки сообщения
static int Time_Mess; // Время последней публикации сообщ.
static int Nom_Mess_Graf; // Счётчик графических сообщений
static string Name_Grf_Txt[30]; // Массив имён графич. сообщений
//--------------------------------------------------------------- 3 --
Win_ind= WindowFind("inform"); // Ищем номер окна индикатора
if (Win_ind<0)return; // Если такого окна нет, уходим
//--------------------------------------------------------------- 4 --
if (Mess_Number==0) // Это происходит в каждом тике
{
if (Time_Mess==0) return; // Если уже крашено серым
if (GetTickCount()-Time_Mess>15000)// За 15 сек цвет устарел
{
for(int i=0;i<=29; i++) // Красим cтроки серым
ObjectSet( Name_Grf_Txt[i], OBJPROP_COLOR, Gray);
Time_Mess=0; // Флажок: все строки серые
WindowRedraw(); // Перерисовываем объекты
}
return; // Выход из функции
}
//--------------------------------------------------------------- 5 --
if (Mess_Number==-1) // Это происходит при deinit()
{
for(i=0; i<=29; i++) // По индексам объектов
ObjectDelete(Name_Grf_Txt[i]);// Удаление объекта
return; // Выход из функции
}
//--------------------------------------------------------------- 6 --
Nom_Mess_Graf++; // Счётчик графических сообщ.
Time_Mess=GetTickCount(); // Время последней публикации
Color_GT=Lime;
//--------------------------------------------------------------- 7 --
switch(Mess_Number) // Переход на сообщение
{
case 1:
Graf_Text="Закрыт ордер Buy "+ Number;
PlaySound("Close_order.wav"); break;
case 2:
Graf_Text="Закрыт ордер Sell "+ Number;
PlaySound("Close_order.wav"); break;
case 3:
Graf_Text="Удалён отложенный ордер "+ Number;
PlaySound("Close_order.wav"); break;
case 4:
Graf_Text="Открыт ордер Buy "+ Number;
PlaySound("Ok.wav"); break;
case 5:
Graf_Text="Открыт ордер Sell "+ Number;
PlaySound("Ok.wav"); break;
case 6:
Graf_Text="Установлен отложенный ордер "+ Number;
PlaySound("Ok.wav"); break;
case 7:
Graf_Text="Ордер "+Number+" преобразовался в рыночный";
PlaySound("Transform.wav"); break;
case 8:
Graf_Text="Переоткрыт ордер "+ Number; break;
PlaySound("Bulk.wav");
case 9:
Graf_Text="Частично закрыт ордер "+ Number;
PlaySound("Close_order.wav"); break;
case 10:
Graf_Text="Новая минимальная дистанция: "+ Number;
PlaySound("Inform.wav"); break;
case 11:
Graf_Text=" Не хватает денег на "+
DoubleToStr(Value,2) + " лотов";
Color_GT=Red;
PlaySound("Oops.wav"); break;
case 12:
Graf_Text="Попытка закрыть ордер "+ Number;
PlaySound("expert.wav"); break;
case 13:
if (Number>0)
Graf_Text="Попытка открыть ордер Sell..";
else
Graf_Text="Попытка открыть ордер Buy..";
PlaySound("expert.wav"); break;
case 14:
Graf_Text="Неправильный пароль. Эксперт не работает.";
Color_GT=Red;
PlaySound("Oops.wav"); break;
case 15:
switch(Number) // Переход на номер ошибки
{
case 2: Graf_Text="Общая ошибка."; break;
case 129: Graf_Text="Неправильная цена. "; break;
case 135: Graf_Text="Цена изменилась. "; break;
case 136: Graf_Text="Нет цен. Ждём новый тик.."; break;
case 146: Graf_Text="Подсистема торговли занята";break;
case 5 : Graf_Text="Старая версия терминала."; break;
case 64: Graf_Text="Счет заблокирован."; break;
case 133: Graf_Text="Торговля запрещена"; break;
default: Graf_Text="Возникла ошибка " + Number;//Другие
}
Color_GT=Red;
PlaySound("Error.wav"); break;
case 16:
Graf_Text="Эксперт работает только на EURUSD";
Color_GT=Red;
PlaySound("Oops.wav"); break;
default:
Graf_Text="default "+ Mess_Number;
Color_GT=Red;
PlaySound("Bzrrr.wav");
}
//--------------------------------------------------------------- 8 --
ObjectDelete(Name_Grf_Txt[29]); // 29й(верхний) объект удаляем
for(i=29; i>=1; i--) // Цикл по индексам массива ..
{ // .. графических объектов
Name_Grf_Txt[i]=Name_Grf_Txt[i-1];// Поднимаем объекты:
ObjectSet( Name_Grf_Txt[i], OBJPROP_YDISTANCE, 2+15*i);
}
Name_Grf_Txt[0]="Inform_"+Nom_Mess_Graf+"_"+Symbol(); // Имя объект
ObjectCreate (Name_Grf_Txt[0],OBJ_LABEL, Win_ind,0,0);// Создаём
ObjectSet (Name_Grf_Txt[0],OBJPROP_CORNER, 3 ); // Угол
ObjectSet (Name_Grf_Txt[0],OBJPROP_XDISTANCE, 450);// Коорд. Х
ObjectSet (Name_Grf_Txt[0],OBJPROP_YDISTANCE, 2); // Коорд. Y
// Текстовое описание объекта
ObjectSetText(Name_Grf_Txt[0],Graf_Text,10,"Courier New",Color_GT);
WindowRedraw(); // Перерисовываем все объекты
return;
}
//--------------------------------------------------------------- 9 --

В блоке 2-3 описаны используемые в функции переменные. Для хранения имён графических объектов используется массив Name_Grf_Txt. Согласно принятому в функции методу для вывода каждого нового сообщения создаётся новый графический объект. Общее количество объектов - 30, каждый объект представляет текстовую надпись, располагаемую в одной строке. В случае большого разрешения экрана количество выводимых строк сообщений можно увеличить путём увеличения количества создаваемых объектов.

В блоке 3-4 вычисляется номер подокна индикатора "Inform", в которое выводятся сообщения. Если индикатор не установлен, то функция прекращает работу. Отсутствие окна не позволяет выводить сообщения, однако это не влияет на работоспособность эксперта - все другие функции будут работать в обычном режиме, в том числе будут осуществляться торговые операции.

В блоке 4-5 осуществляется анализ расцветки сообщений. Обращение к функции с параметром Mess_Number=0 выполняется в эксперте на каждом тике (см. функцию start() в эксперте usualexpert.mq4). Если в предыдущей истории все объекты уже обесцвечены (т.е. все объекты серого цвета), то функция заканчивает работу. Если же значение переменной Time_Mess не нулевое, то изменяются свойства всех объектов, а именно всем объектам сообщается серый цвет.

В случае (блок 5-6), если при вызове функции указан параметр Mess_Number=-1, то все объекты, ранее созданные при исполнении функции, удаляются. Такая необходимость возникает при отключении эксперта из окна финансового инструмента. В этом случае, в соответствии с общим правилом, каждая прикладная программа должна удалить все объекты, созданные ею в период исполнения (см. функцию deinit() в эксперте usualexpert.mq4).

Если управление в программе передаётся в блок 6-7, значит, необходимо создать новый графический объект с нужными свойствами и расположить его в нижней части подокна индикатора (в нижней строке; здесь термин "строка" - условный, в действительности положение графических объектов определяется заданными координатами). Каждый вновь создаваемый объект имеет уникальное имя. Для формирования имён объектов используется исторический порядковый номер сообщения, поэтому в блоке 6-7 установлен счётчик сообщений (в дальнейшем значение переменной Nom_Mess_Graf используется для формирования уникального имени, блок 8-9). Здесь же учитывается время последней публикации и устанавливается основной цвет для новых сообщений (зелёный).

Блок 7-8 состоит из оператора switch, управление внутри которого передаётся согласно заданному при вызове функции значению параметра Mess_Number. В каждом из вариантов case этого оператора переменной Graf_Text присваивается новое значение, которое и является содержанием выводимого сообщения. Для некоторых сообщений устанавливается собственный цвет, например, в случае вывода важного предупреждения цвет может быть красным. Все сообщения сопровождаются звуком - исполнением стандартной функции PlaySound() (см. Звуковые файлы).

Создание нового графического объекта и перемещение уже имеющихся объектов осуществляется в блоке 8-9. Количество объектов ограничено, поэтому при публикации каждого нового сообщения один их графических объектов (самый старый) удаляется. Все другие, уже имеющиеся, объекты перемещаются на одну строку выше. Перемещение объектов выполняется путём изменения их свойств - координат по вертикали. Координаты объектов по горизонтали остаются неизменными.

После того как выполнены необходимые подготовительные действия (все объекты подняты на одну строку вверх), создаётся новый объект с новым уникальным именем и со свойствами, частично определёнными в блоке 7-8. Тип графического объекта - текстовая метка. Объекты этого типа позиционируются относительно окна финансового инструмента, что позволяет пользователю произвольно перемещать ценовой график, не затрагивая этим действием положение надписей сообщений.

Вызов функции Inform() может осуществляться из любого места программы, где по смыслу необходимо вывести очередное сообщение. В результате длительного использования в окне накапливаются сообщения. Пользователь может посмотреть историю сообщений, изменив размер подокна индикатора (например, подняв его верхнюю границу). По желанию пользователя, можно также установить высоту окна таким образом, чтобы видимого пространства хватало для отображения необходимого количества строк сообщений (рекомендуется три - четыре строки).


Рис. 156. Окно финансового инструмента. Сообщения в подокне индикатора.

Легко заметить, что разнообразие сообщений, выводимых функцией, может быть увеличено. В случае если предполагается расширять программу, достаточно добавить новый вариант case в операторе switch (блок 7-8).