English 中文 Español Deutsch 日本語 Português
preview
Создавать графические панели в MQL5 стало проще

Создавать графические панели в MQL5 стало проще

MetaTrader 5Трейдинг | 4 октября 2023, 10:41
1 199 0
Mohamed Abdelmaaboud
Mohamed Abdelmaaboud

Введение

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

Статья может послужить хорошим практическим материалом для улучшения навыков программирования начинающего разработчика благодаря созданию приложения с нуля. Кроме того, статью можно рассматривать как простое руководство по разработке инструментов, упрощающих работу трейдеров. Если вы начинающий MQL5-разработчик, его можно использовать как руководство для создания графических панелей в терминале MetaTrader 5.

В статье рассмотрены следующие темы:

Я рекомендую вам ознакомиться с темой объектно-ориентированного программирования на MQL5 для лучшего понимания темы статьи. В частности, вы можете прочитать мою статью "Объектно-ориентированное программирование (ООП) в MQL5".

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


Графическая идентификация панели

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

Мы можем создать пользовательскую панель в зависимости от объектов и задач или характера взаимодействия между пользователем и этой панелью. К объектам относятся в частности:

  • Числа,
  • Строки,
  • Фигуры,
  • Цвета,
  • Кнопки,
  • и т. д.

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


Классы панелей и диалогов

Рассмотрим классы, которые помогут нам легко создать графическую панель. Мы обратимся к классам панелей и диалогов. Более подробную информацию о них можно найти в документации MQL5. В этой статье мы рассмотрим лишь некоторые из них.

Теперь определим классы для создания панелей управления и диалогов. Они представляют собой библиотеку, имеющую готовый код для создания или разработки интерактивных панелей или приложений, включая индикаторы и советники. Его можно найти в папке данных терминала > папка Include > папка Controls. Существуют вспомогательные, базовые, простые и сложные классы, которые можно использовать для различных операций. Примеры таких классов:

Класс Имя файла (папка Controls) Описание
CLabel Label.mqh Простой управляющий класс для создания простых нередактируемых текстовых меток
CButton Button.mqh Простой управляющий класс для создания простых кнопок.
CEdit Edit.mqh Простой управляющий класс, который позволяет пользователю вводить текст
CPanel Panel.mqh Простой управляющий класс, позволяющий объединять элементы управления с другими аналогичными функциями в группе
CCheckBox
CheckBox.mqh Сложный управляющий класс для отображения флажка (true/false)
CSpinEdit
SpinEdit.mqh Сложный управляющий класс, позволяющий редактировать целочисленное значение.
CDialog
Dialog.mqh Сложный управляющий класс, позволяющий объединять элементы управления с другими различными функциями в группе.

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


Простая графическая панель

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

Графическая панель без классов

Следующие шаги описывают создание простой панели ордеров для открытия ордеров на покупку и продажу после определения размера лота без использования классов за исключением класса Trade:

Используем #include для включения файла Trade и создания объекта trade, который будет использоваться для открытых ордеров

#include <Trade\Trade.mqh>
CTrade trade;

Создадим логическую функцию trade, чтобы установить переменную типа ордера ENUM_ORDER_TYPE и переменную double размера лота. Это параметры создаваемой функции. Для тела функции:

  • Создадим переменную double цены
  • Установим условие для определения типа цены (ask или бид) на основе типа ордера, используя условие if:
    • Если тип ордера — покупка (buy), ценой открытия ордера будет Ask.
    • Если тип ордера — продажа (sell), то ценой будет Bid.
  • Результатом будет открытие позиции с текущим символом, типом ордера, размером лота, типом цены, нулевым значением стоп-лосса и тейк-профита и пустым комментарием.
bool openTrade(ENUM_ORDER_TYPE type, double vol)
  {
   double price;
   if(type==ORDER_TYPE_BUY)
   {
      price=SymbolInfoDouble(Symbol(),SYMBOL_ASK);
   }
   else price=SymbolInfoDouble(Symbol(),SYMBOL_BID);

   return trade.PositionOpen(Symbol(),type,vol,price,0,0,"");
  }

Установим местоположение панели путем выбора верхнего левого угла после создания переменной const ENUM_BASE_CORNER PanelLoc.

const ENUM_BASE_CORNER panelLoc=CORNER_LEFT_UPPER;

Установим xMargin и yMargin после создания константных целочисленных переменных x и y

const int xMargin=20;
const int yMargin=20;

Установим пространство между элементами для x и y после создания еще одной константной целочисленной переменной.

const int xSpace=10;
const int ySpace=10;

Установим размер элементов, которые являются кнопками и текстом после создания четырех константных целочисленных переменных btnWidth для ширины кнопки, btnHeight для высоты кнопки, txtWidth для ширины текста и txtHeight для высоты текста

const int btnWidth=50;
const int btnHeight=20;
const int txtWidth=(btnWidth*2)+xSpace;
const int txtHeight=20;

Установим расположение текста и кнопок, у нас есть text x, text y, buy button x, buy button y, sell button x и sell y. Объявим константные целочисленные переменные для всех и присвоим значения каждой из них.

const int txtX=3;
const int txtY=yMargin+txtHeight;
const int buyX=3;
const int buyY=txtY+ySpace+btnHeight;
const int sellX=buyX+xSpace+btnWidth;
const int sellY=txtY+ySpace+btnHeight;

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

const string txtName="txttVol";
const string buyName="buyBtn";
const string sellName="sellBtn";

Создадим переменную double размера лота с начальным значением

double lotSize=0.01;

В части OnInit() вызовем функцию createPanel(), которую создадим позже.

   createPanel();

В части OnDeinit мы будем удалять объекты по их именам

   ObjectDelete(0,txtName);
   ObjectDelete(0,buyName);
   ObjectDelete(0,sellName);

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

Используем функцию OnChartEven и ее параметры:

  • const int id - для идентификатора события
  • const long &lparam - для параметра события long
  • const double &dparam - для параметра события типа double
  • const string &sparam - для параметра события string

Установим условия взаимодействия с текстом объектов (размером лота), кнопкой покупки и продажи.

//+------------------------------------------------------------------+
//| Interaction function                                             |
//+------------------------------------------------------------------+
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
  {
//--- If the event id is equal to the end of text editing in the panel and the string type event is equal to the text name
   if(id==CHARTEVENT_OBJECT_ENDEDIT && sparam==txtName)
     {
      //--- lotTxt string variable will be equal to the returned property value by using the ObjectGetString function
      string lotTxt=ObjectGetString(0, txtName, OBJPROP_TEXT);
      //--- call setLot function that we will create later with the lotTxt value
      setLot(lotTxt);
      //Setting the property value by using the ObjectSetString
      ObjectSetString(0, txtName, OBJPROP_TEXT, string(lotSize));
      //--- Use return
      return;
     }
//--- If the event id is equal to the object click to check if we click the buy button
   else
      if(id==CHARTEVENT_OBJECT_CLICK)
        {
         //We will check if the string param is equal to buyname
         if(sparam==buyName)
           {
            //--- Setting the value of the property by using the ObjectSetInteger
            ObjectSetInteger(0, buyName, OBJPROP_STATE, false);
            //Calling the created openTrade to open a buy order.
            openTrade(ORDER_TYPE_BUY, lotSize);
            //--- Use return
            return;
           }
         //--- If the event id is equal to the object click to check if we click the sell button
         //--- We will check if the string param is equal to sellname
         else
            if(sparam==sellName)
              {
               //--- Setting the value of the property by using the ObjectSetInteger
               ObjectSetInteger(0, sellName, OBJPROP_STATE, false);
               //Calling the created openTrade to open a sell order
               openTrade(ORDER_TYPE_SELL, lotSize);
               //--- Use return
               return;
              }
        }
  }

Создайте функцию void createPanel, которую мы вызывали ранее в части OnInit(), выполнив следующие шаги:

  • Удалим объекты txtName, buyName и SellName.
  • Вызовем функцию EditCreate.
  • Вызовем функцию ButtonCreate для кнопки покупки.
  • Вызовем функцию ButtonCreate для кнопки продажи.
//+------------------------------------------------------------------+
//|createPanel function                                              |
//+------------------------------------------------------------------+
void createPanel()
  {
//--- Delete objects of txtName, buyName, and sellName
   ObjectDelete(0, txtName);
   ObjectDelete(0, buyName);
   ObjectDelete(0, sellName);
//--- calling the EditCreate function
   EditCreate(             // Parameters:
      0,                   // const long (chart_ID): to specify the chart's ID, we will use (0).
      txtName,             // const string (name): to specify the button name,  we will use (txtName)
      0,                   // const int (sub_window): to specify the subwindow index, we will use (0) for the main window
      txtX,                // const int (x): to specify the X coordinate, we will use (txtX)
      txtY,                // const int (y): to specify the Y coordinate, we will use (txtY)
      txtWidth,            // const int (width):to specify the button width, we will use (txtWidth)
      txtHeight,           // const int (height): to specify the button height, we will use (txtHeight)
      string(lotSize),     // const string (text): to specify the text, we will use (lotSize)
      "Arial",             // const string (font): to specify the font, we will use "Arial"
      10,                  // const int (font_size): to specify the font size, we will use (10)
      ALIGN_LEFT,          // const ENUM_ALIGN_MODE (align_mode): to specify the position of text, we will use (ALIGN_LEFT)
      false,               // const bool (read_only=false): to specify the ability to edit, we will be (false)
      panelLoc,            // const ENUM_BASE_CORNER (corner): to specify the chart corner for anchoring, we will call panelLoc function
      clrBlack,            // const color (clr): to specify the text color, we will specify clrBlack
      clrWhite,            // const color (back_clr): to specify the background color, we will specify clrWhite
      clrBlack,            // const color (border_clr): to specify the border color, we will specify clrBlack
      false,               // const bool (back=false): in the background, we will set false
      false,               // const bool (selection=false): highlight to move, we will set false
      false,               // const bool (hidden): hidden in the object list, we will set false
      0);                  // const long (z_order=0): priority for a mouse click, we will use (0)
//--- calling the ButtonCreate function for the buy
   ButtonCreate(           // Parameters:
      0,                   // const long (chart_ID): to specify the chart's ID, we will use (0)
      buyName,             // const string (name): to specify the button name, we will use (buyName) for the buy button
      0,                   // const int (sub_window): to specify the subwindow index, we will use (0) for the main window
      buyX,                // const int (x): to specify the X coordinate, we will use (buyX) for buy
      buyY,                // const int (y): to specify the Y coordinate, we will use (buyY) for buy
      btnWidth,            // const int (width): to specify the button width, we will use (btnWidth) for buy
      btnHeight,           // const int (height): to specify the button height, we will use (btnHeight) for buy
      panelLoc,            // const ENUM_BASE_CORNER (corner): to specify the chart corner for anchoring, we will call panelLoc function for buy button
      "Buy",               // const string (text): to specify the text, we will use ("Buy") for the buy button
      "Arial",             // const string (font): to specify the font, we will use "Arial"
      10,                  // const int (font_size): to specify the font size, we will use (10)
      clrBlack,            // const color (clr): to specify the text color, we will specify clrBlack
      clrGreen,            // const color (back_clr): to specify the background color, we will specify clrGreen for the buy button
      clrBlack,            // const color (border_clr): to specify the border color, we will specify clrBlack
      false,               // const bool (state): to specify if the object is pressed or released, we will specify false
      false,               // const bool (back=false): in the background, we will set false
      false,               // const bool (selection=false): highlight to move, we will set false
      false,               // const bool (hidden): hidden in the object list, we will set false
      0);                  // const long (z_order=0): priority for mouse click, we will use (0) for buy button
//--- calling the ButtonCreate function for the sell
   ButtonCreate(          //Parameters:
      0,                   //const long (chart_ID): to specify the chart's ID, we will use (0)
      sellName,            //const string (name): to specify the button name, we will use (sellName) for the sell button
      0,                   //const int (sub_window): to specify the subwindow index, we will use (0) for the main window
      sellX,               //const int (x): to specify the X coordinate, we will use (sellX) for sell
      sellY,               //const int (y): to specify the Y coordinate, we will use (sellY)
      btnWidth,            //const int (width): to specify the button width, we will use (btnWidth) for sell
      btnHeight,           //const int (height): to specify the button height, we will use (btnHeight) for sell
      panelLoc,            //const ENUM_BASE_CORNER (corner): to specify the chart corner for anchoring, we will call panelLoc function for sell button
      "Sell",              //const string (text): to specify the text, we will use ("Sell") for the sell button
      "Arial",             //const string (font): to specify the font, we will use "Arial"
      10,                  //const int (font_size): to specify the font size, we will use (10)
      clrBlack,            //const color (clr): to specify the text color, we will specify clrBlack
      clrRed,              //const color (back_clr): to specify the background color, we will specify clrRed for the sell button
      clrBlack,            //const color (border_clr): to specify the border color, we will specify clrBlack
      false,               //const bool (state): to specify if the object is pressed or released, we will specify false
      false,               //const bool (back=false): in the background, we will set false
      false,               //const bool (selection=false): highlight to move, we will set false
      false,               //const bool (hidden): hidden in the object list, we will set false
      0);                  //const long (z_order=0): priority for mouse click, we will use (0) for sell button
  }

    Создадим функцию void setLot с одним параметром — lotTxt, который используется для lotSize. Тело функции показано ниже:

    • Создадим double-переменную newLot и присвоим ее lotTxt после преобразования ее в double из string с помощью функции StringToDouble.
    • Убедимся, что значение переменной newLot меньше 0. Напечатаем сообщение "Invalid Volume Specified" (указан недопустимый объем), а затем используем return.
    • Вернем значение newLot, совпадающее с lotSize
    void setLot(string lotTxt)
      {
       double newLot=StringToDouble(lotTxt);
       if(newLot<0)
         {
          Print("Invaid Volume Specified");
          return;
         }
       lotSize=newLot;
      }

    Создание функции EditCreate состоит из следующих шагов:

    //+------------------------------------------------------------------+
    //|EditCreate function                                               |
    //+------------------------------------------------------------------+
    bool EditCreate(const long             chart_ID=0,
                    const string           name="Edit",
                    const int              sub_window=0,
                    const int              x=0,
                    const int              y=0,
                    const int              width=50,
                    const int              height=18,
                    const string           text="Text",
                    const string           font="Arial",
                    const int              font_size=10,
                    const ENUM_ALIGN_MODE  align=ALIGN_CENTER,
                    const bool             read_only=false,
                    const ENUM_BASE_CORNER corner=CORNER_LEFT_UPPER,
                    const color            clr=clrBlack,
                    const color            back_clr=clrWhite,
                    const color            border_clr=clrNONE,
                    const bool             back=false,
                    const bool             selection=false,
                    const bool             hidden=true,
                    const long             z_order=0)
      {
    //--- Reset the error value by using ResetLastError()
       ResetLastError();
    //--- Create an edit field
       if(!ObjectCreate(chart_ID, name, OBJ_EDIT, sub_window, 0, 0))
         {
          Print(__FUNCTION__,
                ": failed to create \"Edit\" object! Error code = ", GetLastError());
          return(false);
         }
    //--- Setting the object coordinates x and y by using the ObjectSetInteger
       ObjectSetInteger(chart_ID, name, OBJPROP_XDISTANCE, x);
       ObjectSetInteger(chart_ID, name, OBJPROP_YDISTANCE, y);
    //--- Setting the object size by using the ObjectSetInteger function also
       ObjectSetInteger(chart_ID, name, OBJPROP_XSIZE, width);
       ObjectSetInteger(chart_ID, name, OBJPROP_YSIZE, height);
    //--- Setting the text by using ObjectSetString function
       ObjectSetString(chart_ID, name, OBJPROP_TEXT, text);
    //--- Setting the text font by using the ObjectSetString function also
       ObjectSetString(chart_ID, name, OBJPROP_FONT, font);
    //--- Setting the font size by using the ObjectSetInteger function
       ObjectSetInteger(chart_ID, name, OBJPROP_FONTSIZE, font_size);
    //--- Setting the type of text alignment in the object
       ObjectSetInteger(chart_ID, name, OBJPROP_ALIGN, align);
    //--- Setting the ability to edit, enable if it is (true) or cancel (false) if you need a read-only mode
       ObjectSetInteger(chart_ID, name, OBJPROP_READONLY, read_only);
    //--- Setting the chart's corner, relative to which object coordinates are defined to set the location of the object.
       ObjectSetInteger(chart_ID, name, OBJPROP_CORNER, corner);
    //--- Setting the text color
       ObjectSetInteger(chart_ID, name, OBJPROP_COLOR, clr);
    //--- Setting the background color
       ObjectSetInteger(chart_ID, name, OBJPROP_BGCOLOR, back_clr);
    //--- Setting the border color of the object
       ObjectSetInteger(chart_ID, name, OBJPROP_BORDER_COLOR, border_clr);
    //--- Displaying in the foreground by (false) or in the background by (true)
       ObjectSetInteger(chart_ID, name, OBJPROP_BACK, back);
    //--- Setting (true) to enable or (false) to disable the mode of moving the label by mouse
       ObjectSetInteger(chart_ID, name, OBJPROP_SELECTABLE, selection);
       ObjectSetInteger(chart_ID, name, OBJPROP_SELECTED, selection);
    //--- Setting (true) if you need hiding or (false) if you need the display of graphical object name in the object list
       ObjectSetInteger(chart_ID, name, OBJPROP_HIDDEN, hidden);
    //--- Setting the priority for receiving the event of a mouse click in the chart
       ObjectSetInteger(chart_ID, name, OBJPROP_ZORDER, z_order);
    //--- Returning (true) if successful execution
       return(true);
      }

    Создадим функцию ButtonCreate аналогично предыдущим параметрам функции EditCreate с небольшим отличием:

    bool ButtonCreate(const long              chart_ID=0,               
                      const string            name="Button",            
                      const int               sub_window=0,             
                      const int               x=0,                      
                      const int               y=0,                      
                      const int               width=50,                 
                      const int               height=18,                
                      const ENUM_BASE_CORNER  corner=CORNER_LEFT_UPPER, 
                      const string            text="Button",            
                      const string            font="Arial",             
                      const int               font_size=10,             
                      const color             clr=clrBlack,             
                      const color             back_clr=C'236,233,216',  
                      const color             border_clr=clrNONE,       
                      const bool              state=false,              
                      const bool              back=false,               
                      const bool              selection=false,          
                      const bool              hidden=true,              
                      const long              z_order=0)                
      {
       ResetLastError();
       if(!ObjectCreate(chart_ID,name,OBJ_BUTTON,sub_window,0,0))
         {
          Print(__FUNCTION__,
                ": failed to create the button! Error code = ",GetLastError());
          return(false);
         }
       ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x);
       ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y);
       ObjectSetInteger(chart_ID,name,OBJPROP_XSIZE,width);
       ObjectSetInteger(chart_ID,name,OBJPROP_YSIZE,height);
       ObjectSetInteger(chart_ID,name,OBJPROP_CORNER,corner);
       ObjectSetString(chart_ID,name,OBJPROP_TEXT,text);
       ObjectSetString(chart_ID,name,OBJPROP_FONT,font);
       ObjectSetInteger(chart_ID,name,OBJPROP_FONTSIZE,font_size);
       ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
       ObjectSetInteger(chart_ID,name,OBJPROP_BGCOLOR,back_clr);
       ObjectSetInteger(chart_ID,name,OBJPROP_BORDER_COLOR,border_clr);
       ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
       ObjectSetInteger(chart_ID,name,OBJPROP_STATE,state);
       ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
       ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
       ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
       ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
       return(true);
      }

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

    simpleOrderPanelWithoutClass

    Как видим, в верхнем левом углу у нас есть панель с размером лота и двумя кнопками Buy и Sell и мы можем указать размер лота, который нам нужен, и разместить ордер, нажав кнопку Buy или Sell. Теперь для сравнения создадим ту же панель, используя классы Panels и Dialogs.


    Графическая панель с использованием классов

    Выполним следующие шаги для создания панели.

    Включите необходимые файлы, или классы: Dialog, Button, Edit и Trade. Как мы знаем, это можно сделать с помощью команды #include.

    #include <Controls\Dialog.mqh>
    #include <Controls\Button.mqh>
    #include <Controls\Edit.mqh>
    #include <Trade\Trade.mqh>

    Используем макроподстановку #define, которая является директивой препроцессора для присвоения константам мнемонических имен:

    • PANEL_NAME "Order Panel"
    • PANEL_WIDTH 116
    • PANEL_HIEIGHT 100
    • ROW_HEIGHT 20
    • BUY_BTN_NAME "Buy BTN"
    • SELL_BTN_NAME "Sell BTN"
    • CLOSE_BTN_NAME "Close BTN"
    • EDIT_NAME "Lot Size"
    #define PANEL_NAME "Order Panel"
    #define PANEL_WIDTH 116
    #define PANEL_HIEIGHT 100
    #define ROW_HEIGHT 20
    #define BUY_BTN_NAME "Buy BTN"
    #define SELL_BTN_NAME "Sell BTN"
    #define CLOSE_BTN_NAME "Close BTN"
    #define EDIT_NAME "Lot Size"

    Создадим объекты из классов

    CAppDialog panel;
    CButton buyBtn;
    CButton sellBtn;
    CButton closeBtn;
    CEdit lotSize;
    CTrade trade;

    В части OnInit() нам нужно создать объект панели, используя созданный нами объект Panel.Create и его параметры:

    • const long chart - установим 0, чтобы панель отображалась на основном графике.
    • const string name - установим PANEL_NAME
    • const int subwin - установим 0
    • const int x1 - установим 10
    • const int y1 - установим 20
    • const int x2 - используем 10+PANEL_WIDTH+8
    • const int y2 - используем 20+PANEL_HIEIGHT
    panel.Create(0,PANEL_NAME,0,10,20,10+PANEL_WIDTH+8,20+PANEL_HIEIGHT);

    Создадим и настроим кнопки покупки и продажи:

    • Создадим объекты, используя object.Create.
    • Настроим ширину объектов buy и sell с помощью object.Width.
    • Настроим высоту покупки и продажи объектовиспользуя object.Height.
    • Настроим цвет фона объектовиспользуя object.ColorBackground.
    • Настроим текст объектов с помощью object.Text.
    • Настроим шрифт объектов с помощью object.Font.
    • Настроим размер шрифта объектов с помощью object.FontSize.
    • Настроим цвет объектов с помощью object.Color.
    • Установим цветовую границу объектов с помощью object.ColorBorder.
    • Разместим объект объектов на панели.
    • Запустим панель
    int OnInit()
      {
       //buy button
       panel.Create(0,PANEL_NAME,0,10,20,10+PANEL_WIDTH+8,20+PANEL_HIEIGHT);
       buyBtn.Create(0,BUY_BTN_NAME,0,3,40,0,0);
       buyBtn.Width(50);
       buyBtn.Height(ROW_HEIGHT);
       buyBtn.ColorBackground(clrGreen);
       buyBtn.Text("Buy");
       buyBtn.Font("Arial");
       buyBtn.FontSize(10);
       buyBtn.Color(clrBlack);
       buyBtn.ColorBorder(clrBlack);   
       panel.Add(buyBtn);
       //sell button
       sellBtn.Create(0,SELL_BTN_NAME,0,63,40,0,0);
       sellBtn.Width(50);
       sellBtn.Height(ROW_HEIGHT);
       sellBtn.ColorBackground(clrRed);
       sellBtn.Text("Sell");
       sellBtn.Font("Arial");
       sellBtn.FontSize(10);
       sellBtn.Color(clrBlack);
       sellBtn.ColorBorder(clrBlack);
       panel.Add(sellBtn);
       //lotSize
       lotSize.Create(0,EDIT_NAME,0,4,10,0,0);
       lotSize.Width(108);
       lotSize.Height(ROW_HEIGHT);
       lotSize.Text("0.01");
       lotSize.Font("Arial");
       lotSize.FontSize(10);
       lotSize.ColorBackground(clrWhite);
       lotSize.Color(clrBlack);
       lotSize.ColorBorder(clrBlack);
       panel.Add(lotSize);
       //run the panel
       panel.Run();
       return(INIT_SUCCEEDED);
      }

    В части OnDeinit(const int Reason) мы используем Destroy в качестве функции деинициализации, как показано ниже.

    void OnDeinit(const int reason)
      {
       panel.Destroy();
      }

    Включим взаимодействие с панелью с помощью функции OnChartEvent и установим условия поведения кнопок покупки и продажи:

    • Создадим функцию OnChartEvent
    • Тело функции
      • Используем object.ChartEvent с параметрами id для события, lparam для типа события long, dparam для типа double и sparam для типа string.
      • Проверим, равен ли идентификатор клику по графику (Chart Click).
      • Проверим равенство sparam именам buyBtn или SellBtn.
      • Создадим double-переменную лота и присвоим ее StringToDouble (размер лота).
      • Откроем ордер на покупку или продажу в зависимости от типа события, используя значение лота.
    void  OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
      {
       panel.ChartEvent(id,lparam,dparam,sparam);
       if(id==CHARTEVENT_OBJECT_CLICK)
         {
          if(sparam==buyBtn.Name())
            {
             double lot=StringToDouble(lotSize.Text());
             trade.Buy(lot);
            }
          else
             if(sparam==sellBtn.Name())
               {
                double lot=StringToDouble(lotSize.Text());
                trade.Sell(lot);
               }
         }
      }

    После компиляции и запуска кода мы увидим панель на графике:

    simpleOrderPanelWithClass

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

    После проделанной работы мы видим, что создавать панель с использованием классов проще и удобнее. Итак, классы очень полезны и экономят нам много времени. Однако если вы начинающий программист, постарайтесь изучить и понять, как они создаются. Это очень хороший способ улучшить ваши навыки программирования.

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


    Заключение

    Классы — ценный и полезный инструмент в целом и, в частности, при создании панелей, которые можно использовать в MetaTrader 5. Это позволяет трейдерам больше сосредоточиться на торговле. Мы узнали, что такое панели и рассмотрели их типы, а также создали простую панель двумя способами, убедившись, насколько использование классов Panels и Dialog, ускоряет и упрощает работу.

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

    Чтобы узнать больше о классах и объектах, рекомендую прочитать одну из моих прошлых статей "Объектно-ориентированное программирование (ООП) в MQL5". Если статья вам понравилась и вы считаете ее полезной, почитайте мои предыдущие статьи, чтобы узнать, как разрабатывать торговые системы на основе различных популярных технических индикаторов.

    Перевод с английского произведен MetaQuotes Ltd.
    Оригинальная статья: https://www.mql5.com/en/articles/12903

    Прикрепленные файлы |
    Вспоминаем старую трендовую стратегию: два стохастических осциллятора, MA и Фибоначчи Вспоминаем старую трендовую стратегию: два стохастических осциллятора, MA и Фибоначчи
    Старые торговые стратегии. В этой статье представлена стратегия отслеживания тренда. Стратегия исключительно техническая и использует несколько индикаторов и инструментов для подачи сигналов и определения целевых уровней. Компоненты стратегии включают в себя: 14-периодный стохастический осциллятор, пятипериодный стохастический осциллятор, скользящую среднюю с периодом 200 и проекцию Фибоначчи (для установки целевых уровней).
    Разработка системы репликации - Моделирование рынка (Часть 16): Новая система классов Разработка системы репликации - Моделирование рынка (Часть 16): Новая система классов
    Нам нужно лучше организовать свою работу. Код растёт, и если этого не сделать сейчас, потом это станет невозможным. Давайте разделять и властвовать. То, что MQL5 позволяет нам использовать классы, поможет нам в этой задаче, но для этого нам нужно иметь некоторые знания о некоторых моментах, связанных с классами. Наверное, новичков больше всего смущает наследование. В этой статье мы рассмотрим практичным и простым способом, как использовать данные механизмы.
    Теория категорий в MQL5 (Часть 13): События календаря со схемами баз данных Теория категорий в MQL5 (Часть 13): События календаря со схемами баз данных
    В статье рассматривается, как схемы баз данных могут быть включены для классификации в MQL5. Мы кратко рассмотрим, как концепции схемы базы данных могут сочетаться с теорией категорий при идентификации текстовой (строковой) информации, имеющей отношение к торговле. В центре внимания будут находиться события календаря.
    Может ли Heiken Ashi давать хорошие сигналы в сочетании со скользящими средними? Может ли Heiken Ashi давать хорошие сигналы в сочетании со скользящими средними?
    Комбинации стратегий могут повысить эффективность торговли. Мы можем комбинировать индикаторы и паттерны, чтобы получать дополнительные подтверждения. Скользящие средние помогают нам подтвердить тренд и следовать ему. Это самые известный технический индикатор, что объясняется его простотой и доказанной эффективностью анализа.