Рецепты MQL5 - Вывод информации на печать в разных режимах

Anatoli Kazharski | 21 февраля, 2013


Введение

Это первая статья из серии "Рецепты MQL5". Я начну с простых примеров, чтобы те, кто только начинает изучать программирование, могли плавно погрузиться в изучение этого языка. Я вспоминаю, как я начинал изучать разработку и программирование торговых систем, и, признаться, мне это было довольно сложно, так как это мой первый язык. До этого я вообще считал, что это не моё и вряд ли я смогу с этим когда-нибудь разобраться.

Но всё оказалось не так сложно, и уже через несколько месяцев я создал довольно сложную программу. Вы можете ознакомиться с этим продуктом в статье Безграничные возможности с MetaTrader 5 и MQL5.

Я постараюсь вести начинающего экспертописателя по принципу "от простого к сложному". Я не буду переписывать Справочное руководство, поэтому клавишей F1 в редакторе MetaEditor 5 Вам придётся пользоваться часто. Но зато в этой серии статей вы найдёте множество примеров, готовых функций и схем, которые сможете использовать в своих разработках как в исходном, так и в изменённом своими собственными силами виде.

Итак, начнем. В этой статье создадим простой скрипт, который выводит на печать некоторые свойства символа в разных режимах. При разработке программы очень часто, особенно в начале изучения, будут возникать ситуации, когда программа будет показывать не тот результат, который вы от неё ожидаете. Поэтому в таких случаях нужно будет проверять значения тех или иных переменных, которые участвуют в расчётах. Мы рассмотрим в этом примере три варианта, в которых будут использоваться функции Print(), Comment() и Alert(). Впоследствии вы сами сможете определить для себя тот способ, который для вас будет удобнее.


Мастер MQL5

Я начал изучать MQL5 именно со скриптов. Это довольно удобно и быстро. Скрипт загружается, исполняет созданную вами функцию и сам удаляется с графика. Таким образом можно быстро провести ряд экспериментов и выяснить, в каком направлении работать дальше.

Если у вас до сих пор не установлен торговый терминал MetaTrader 5, то установите его прямо сейчас. После установки, запустите терминал и откройте редактор, нажав клавишу F4. С помощью этой клавиши вы можете быстро переключаться от торгового терминала MetaTrader 5 к редактору MetaEditor 5 и обратно. Редактор можно также запустить, кликнув на соответствующей кнопку на панели инструментов терминала. Хорошо изучите интерфейс программ с помощью Справочного руководства (F1) торгового терминала и редактора, так как на этих вопросах мы не будем останавливаться или это будет очень кратко.

Откройте MetaEditor 5 и нажмите сочетание клавиш Ctrl+Nили нажмите на панели редактора под главным меню кнопку Создать. Открывается окно Мастер MQL5, в котором можно выбрать, какую программу будем создавать. В этом случае выберите Скрипти нажмите Далее:

Рис. 1. Окно "Мастер MQL5" - Скрипт

Рис. 1. Окно "Мастер MQL5" - Скрипт

На следующем шаге нужно будет ввести название скрипта (имя файла). Скрипты по умолчанию создаются в директории Metatrader 5\MQL5\Scripts\имя_файла.mq5. В этой директории можно создавать также и другие папки для группировки файлов по назначению.

Рис. 2. Окно "Мастер MQL5" - Имя файла

Рис. 2. Окно "Мастер MQL5" - Имя файла

Можно также сразу добавить входные параметры, если это необходимо. Когда всё настроено нужно нажать кнопку Готово. По шаблону будет создан и открыт новый документ для разработки скрипта:

//+------------------------------------------------------------------+
//|                                                   PrintModes.mq5 |
//|                        Copyright 2012, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2012, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
    
  }
//+------------------------------------------------------------------+


Пишем код

Всё, что пишется после двойной косой черты, относится к комментариям и никак не влияет на исполнение программы. Желательно всегда подробно комментировать код, так как это существенно облегчает понимание своего же кода, особенно, если был долгий перерыв.

В первых трёх строках кода выше, всё, что идёт после #property, относится к свойствам программы. Более подробно о каждой функции и свойстве можно прочитать в Справке по языку MQL5. Для того чтобы быстро перейти к описанию той или иной функции, нужно просто двойным щелчком выделить её и нажать F1. Откроется Справка с описанием запрошенной функции.

Далее идёт главная функция для скриптов - OnStart(). Именно в ней должны располагаться все другие функции и расчёты.

Сделаем так, чтобы перед выполнением программы можно было выбрать, каким способом будет выводиться запрошенная информация. Значит, нужно сделать внешний параметр, в котором с помощью выпадающего списка можно будет выбрать нужный режим. Нам понадобится указать ещё одно свойство (#property), которое отвечает за то, чтобы программа открывала окно с внешними параметрами скрипта перед выполнением. Это свойство script_show_inputs. Добавим его ниже всех остальных, которые уже есть в коде:

#property copyright "Copyright 2012, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#property script_show_inputs
//---

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

// ПЕРЕЧИСЛЕНИЕ
enum ENUM_PRINT_MODE
  {
   PRINT   = 0,
   COMMENT = 1,
   ALERT   = 2
  };
//---

Далее в коде следует единственный в этом скрипте внешний параметр PrintMode:

// ВХОДНЫЕ ПАРАМЕТРЫ
input ENUM_PRINT_MODE printMode=PRINT; // Режим печати

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

Рис. 3. Окно параметров скрипта

Рис. 3. Окно параметров скрипта

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

Для того чтобы создать функцию, нужно просто ввести код показанный ниже:

//+------------------------------------------------------------------+
//| ВЫВОДИТ В ПЕЧАТЬ СВОЙСТВА СИМВОЛА                                |
//+------------------------------------------------------------------+
void PrintSymbolProperties()
  {
    
  }

Перед именем функции указывается тип возвращаемого значения. Если же функция ничего не возвращает, как в этом случае, то нужно указать тип void. Далее, в теле функции PrintSymbolProperties() между фигурными скобками нужно написать остальной код. Сначала создадим переменные:

string symb_symbol    = "";  // Символ
int    symb_digits    = 0;   // Количество знаков после запятой
int    symb_spread    = 0;   // Разница между ценой ask и bid (спред)
int    symb_stoplevel = 0;   // Ограничительные уровни stop level
double symb_ask       = 0.0; // Цена ask
double symb_bid       = 0.0; // Цена bid

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

symb_symbol    =Symbol();
symb_digits    =(int)SymbolInfoInteger(_Symbol,SYMBOL_DIGITS);
symb_spread    =(int)SymbolInfoInteger(_Symbol,SYMBOL_SPREAD);
symb_stoplevel =(int)SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL);
symb_ask       =SymbolInfoDouble(_Symbol,SYMBOL_ASK);
symb_bid       =SymbolInfoDouble(_Symbol,SYMBOL_BID);
//---

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

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

//---
// Если указано выводить в журнал
   if(printMode==PRINT)
     {
      Print("Symbol: ",symb_symbol,"\n",
            "Digits: ",symb_digits,"\n",
            "Spread: ",symb_spread,"\n",
            "Stops Level: ",symb_stoplevel,"\n",
            "Ask: ",symb_ask,"\n",
            "Bid: ",symb_bid
            );
     }
//---
// Если указано выводить на график
   if(printMode==COMMENT)
     {
      int mb_res=-1; // Переменная с результатом выбора в диалоговом окне
      //---
      Comment("Symbol: ",symb_symbol,"\n",
              "Digits: ",symb_digits,"\n",
              "Spread: ",symb_spread,"\n",
              "Stops Level: ",symb_stoplevel,"\n",
              "Ask: ",symb_ask,"\n",
              "Bid: ",symb_bid
              );
      //---
      // Откроем диалоговое окно
      mb_res=MessageBox("Удалить комментарии на графике?",NULL,MB_YESNO|MB_ICONQUESTION);
      //---
      // Если нажата кнопка "Да" то, очистить комментарии на графике 
      if(mb_res==IDYES) { Comment(""); }
      //---
      return;
     }
//---
// Если указано выводить в алерт
   if(printMode==ALERT)
     {
      Alert("Symbol: "+symb_symbol+"\n",
            "Digits: "+IntegerToString(symb_digits)+"\n",
            "Spread: "+IntegerToString(symb_spread)+"\n",
            "Stops Level: "+IntegerToString(symb_stoplevel)+"\n",
            "Ask: "+DoubleToString(symb_ask,_Digits)+"\n",
            "Bid: "+DoubleToString(symb_bid,_Digits)
            );
     }
//---

Если для внешнего параметра выбран вариант PRINT, то данные будут выводиться в журнал экспертов (окно Инструменты вкладка Эксперты):

Рис. 4. Окно "Инструменты" - вкладка "Эксперты"

Рис. 4. Окно "Инструменты" - вкладка "Эксперты"

Если выбран вариант COMMENT, то данные будут выводиться на график в левый верхний угол. При этом после вывода информации на график, с помощью функции MessageBox() будет открыто диалоговое окно, в котором будет предложено очистить график от комментариев:

Рис. 5. Комментарии на графике в левом верхнем углу

Рис. 5. Комментарии на графике в левом верхнем углу

Если же был выбран вариант ALERT, то после запуска скрипта будет открываться окно алерта, в которое будет выводиться запрошенная информация или просто пользовательские сообщения. При этом, так же как в случае с вариантом PRINT, выводится информация в журнал, плюс проигрывается звуковое оповещение.

Рис. 6. Окно алерта

Рис. 6. Окно алерта

Ниже представлен весь код скрипта:

//+------------------------------------------------------------------+
//|                                                   PrintModes.mq5 |
//|                        Copyright 2012, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright   "Copyright 2012, MetaQuotes Software Corp."
#property link        "http://tol64.blogspot.com"
#property description "email: hello.tol64@gmail.com"
#property version     "1.00"
#property script_show_inputs
//---
//--- ПЕРЕЧИСЛЕНИЕ
enum ENUM_PRINT_MODE
  {
   PRINT   = 0,
   COMMENT = 1,
   ALERT   = 2
  };
//---
// ВХОДНЫЕ ПАРАМЕТРЫ
input ENUM_PRINT_MODE printMode=PRINT; // Режим печати
//---
//+------------------------------------------------------------------+
//| ГЛАВНАЯ ФУНКЦИЯ                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
   PrintSymbolProperties();
  }
//+------------------------------------------------------------------+
//| ВЫВОДИТ НА ПЕЧАТЬ СВОЙСТВА СИМВОЛА                               |
//+------------------------------------------------------------------+
void PrintSymbolProperties()
  {
   string symb_symbol    = "";  // Символ
   int    symb_digits    = 0;   // Количество знаков после запятой
   int    symb_spread    = 0;   // Разница между ценой ask и bid (спред)
   int    symb_stoplevel = 0;   // Ограничительные уровни stop level
   double symb_ask       = 0.0; // Цена ask
   double symb_bid       = 0.0; // Цена bid
//---
   symb_symbol    =Symbol();
   symb_digits    =(int)SymbolInfoInteger(_Symbol,SYMBOL_DIGITS);
   symb_spread    =(int)SymbolInfoInteger(_Symbol,SYMBOL_SPREAD);
   symb_stoplevel =(int)SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL);
   symb_ask       =SymbolInfoDouble(_Symbol,SYMBOL_ASK);
   symb_bid       =SymbolInfoDouble(_Symbol,SYMBOL_BID);
//---
// Если указано выводить в журнал
   if(printMode==PRINT)
     {
      Print("Symbol: ",symb_symbol,"\n",
            "Digits: ",symb_digits,"\n",
            "Spread: ",symb_spread,"\n",
            "Stops Level: ",symb_stoplevel,"\n",
            "Ask: ",symb_ask,"\n",
            "Bid: ",symb_bid
            );
     }
//---
// Если указано выводить на график
   if(printMode==COMMENT)
     {
      int mb_res=-1; // Переменная с результатом выбора в диалоговом окне
      //---
      Comment("Symbol: ",symb_symbol,"\n",
              "Digits: ",symb_digits,"\n",
              "Spread: ",symb_spread,"\n",
              "Stops Level: ",symb_stoplevel,"\n",
              "Ask: ",symb_ask,"\n",
              "Bid: ",symb_bid
              );
      //---
      // Откроем диалоговое окно
      mb_res=MessageBox("Удалить комментарии на графике?",NULL,MB_YESNO|MB_ICONQUESTION);
      //---
      // Если нажата кнопка "Да" то, очистить комментарии на графике 
      if(mb_res==IDYES) { Comment(""); }
      //---
      return;
     }
//---
// Если указано выводить в алерт
   if(printMode==ALERT)
     {
      Alert("Symbol: "+symb_symbol+"\n",
            "Digits: "+IntegerToString(symb_digits)+"\n",
            "Spread: "+IntegerToString(symb_spread)+"\n",
            "Stops Level: "+IntegerToString(symb_stoplevel)+"\n",
            "Ask: "+DoubleToString(symb_ask,_Digits)+"\n",
            "Bid: "+DoubleToString(symb_bid,_Digits)
            );
     }
  }

//+------------------------------------------------------------------+


Заключение

На этом заканчиваем эту статью. Кроме перечисленных способов можно также записывать данные в файл. Это может быть обычный текстовый файл или даже HTML-отчет, красиво отформатированный с помощью CSS. Но эти способы уже сложнее для новичков, вышеперечисленных методов вполне достаточно для начала.