Как создать программную кнопку в коде эксперта?

Программирование прибыли: от азов к секретам мастерства. Читайте, спрашивайте, делитесь опытом.
Бонус за сообщение 0.5$
Ответственный Модератор - Haos

Как создать программную кнопку в коде эксперта?

Сообщение Haos » 03 май 2017, 15:45

Создадим три кнопки в коде советника: BUY, SELL, CLOSE. Первые две - для открытия соответствующих позиций, третья - для закрытия позиций.
Прежде всего, в описании внешних переменных советника добавим следующие строки, для возможности пользователем задания цвета фона и текста кнопок:
Код: выделить все
input color    colBtn1Back = clrSkyBlue;   // Цвет фона кнопки BUY
input color    colBtn2Back = clrRed;         // Цвет фона кнопки SELL
input color    colBtn3Back = clrGold;        // Цвет фона кнопки CLOSE
input color    colText     = clrBlack;       // Цвет текста кнопок


Далее, нам нужно определить переменные для "внутреннего пользования" разработчика:

Код: выделить все
// Настройки кнопок:
ENUM_BASE_CORNER  enuCorn  = CORNER_LEFT_UPPER; // Угол графика для привязки
string            strBtn1  = "BUY";       // Имя кнопки 1
string            strBtn2  = "SELL";      // Имя кнопки 2
string            strBtn3  = "CLOSE";     // Имя кнопки 3
string            strFont  = "Arial";     // Шрифт
int               intFSiz  = 12;          // Размер шрифта
int               intDl1   = 15;          // отступ слева для 1-ой кнопки
int               intDh1   = 20;          // отступ сверху для 1-ой кнопки
int               intWi    = 80;          // ширина кнопок
int               intHi    = 30;          // высота кнопок
int   intDl2;  // Отступ слева для 2-ой кнопки
int   intDl3;  // Отступ слева для 3-ой кнопки

Видно, что это угол привязки для кнопок имена кнопок, шрифт и его размер, размеры кнопок и отступ по вертикали и горизонтали для 1-ой кнопки. Поскольку отступ по вертикали для всех кнопок должен быть одинаковым, то для 2 и 3-ей кнопки нужно задать только отступ слева.
Далее, в коде эксперта нужно расположить следующие четыре функции, отвечающие за функционирование создаваемых кнопок:
Код: выделить все
void f_SetButton(string na, int dl, int dh, int wi, int hi, color back)
{
/*
   na - имя кнопки
   dl - оступ слева для кнопки
   dh - отступ сверху для кнопки
   wi - ширина кнопки
   hi - высота кнопки
   back - цвет фона кнопки
*/
   //создадим кнопку
   if(!f_ButtonCreate(0, na, 0, dl, dh, wi, hi, enuCorn, na, strFont, intFSiz,
      colText, back, clrNONE, false, false, false, true, 0))
   {
      return;
   }
   //перерисуем график
   ChartRedraw();
}

//*********************************************************************************************

//+------------------------------------------------------------------+
//| Создает кнопку                                                   |
//+------------------------------------------------------------------+
bool f_ButtonCreate(const long            chart_ID=0,               // ID графика
                  const string            name="Button",            // имя кнопки
                  const int               sub_window=0,             // номер подокна
                  const int               x=0,                      // координата по оси X
                  const int               y=0,                      // координата по оси Y
                  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__,
            ": не удалось создать кнопку! Код ошибки = ",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);
   //--- отобразим на переднем (false) или заднем (true) плане
   ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
   //--- переведем кнопку в заданное состояние
   ObjectSetInteger(chart_ID,name,OBJPROP_STATE,state);
   //--- включим (true) или отключим (false) режим перемещения кнопки мышью
   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
   //--- скроем (true) или отобразим (false) имя графического объекта в списке объектов
   ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
   //--- установим приоритет на получение события нажатия мыши на графике
   ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
   //--- успешное выполнение

return(true);
}
 
//*********************************************************************************************

//+------------------------------------------------------------------+
//| Удаляет кнопку                                                   |
//+------------------------------------------------------------------+
bool f_ButtonDelete(const long   chart_ID=0,    // ID графика
                    const string name="Button") // имя кнопки
{
   //--- сбросим значение ошибки
   ResetLastError();
   //--- удалим кнопку
   if(!ObjectDelete(chart_ID, name))
   {
      Print(__FUNCTION__,
            ": не удалось удалить кнопку! Код ошибки = ",GetLastError());
      return(false);
   }
   //--- успешное выполнение

return(true);
}

//*********************************************************************************************

bool f_ButtonPressured(string na)
{
/*
   Функция определяет находится ли указанная кнопка в нажатом состоянии
   na - имя кнопки
*/
   bool bol_Y = ObjectGetInteger(0, na, OBJPROP_STATE, true);
   if(bol_Y) return(true);

return(false);
}

Первая ф-ия f_SetButton() - устанавливает параметры кнопки; вторая функция f_ButtonCreate() - создает саму кнопку; третья - f_ButtonDelete() - отвечает за удаление кнопки (это необходимо при выгрузке советника); четвертая функция - f_ButtonPressured() - определяет действия при нажатии пользователем на кнопку.
Поскольку создание кнопок должно происходить при запуске эксперта, соответствующие вызовы функции f_SetButton() прописывается в коде стандартной функции эксперта OnInit():
Код: выделить все
int OnInit()
{
   f_SetButton(strBtn1, intDl1, intDh1, intWi, intHi, colBtn1Back);
   intDl2 = intDl1 + intWi +1;
   f_SetButton(strBtn2, intDl2, intDh1, intWi, intHi, colBtn2Back);
   intDl3 = intDl2 + intWi +1;
   f_SetButton(strBtn3, intDl3, intDh1, intWi, intHi, colBtn3Back);
   
return(INIT_SUCCEEDED);
}

Также в этом месте нужно задать координаты расположения всех кнопок (переменные intDl2, intDl3).
Итак, кнопки созданы и теперь готовы к применению в коде эксперта.
Далее рассмотрим как же использовать их непосредственно в самом коде.
Аватар пользователя
Haos
Специалист MQL
 
Сообщений: 24699
Зарегистрирован: 29 мар 2014, 16:07
Средств на руках: 193.70 Доллар
Группа: Главные модераторы
Благодарил (а): 3379 раз.
Поблагодарили: 8200 раз.

Re: Как создать программную кнопку в коде эксперта?

Сообщение Haos » 03 май 2017, 15:53

События, программируемые при работе с кнопками осуществляются в стандартной функции эксперта OnTick().

Код: выделить все
void OnTick()
{
   bool bolBtn1 = f_ButtonPressured(strBtn1); // нажата ли кнопа BUY
   bool bolBtn2 = f_ButtonPressured(strBtn2); // нажата ли кнопа SELL
   bool bolBtn3 = f_ButtonPressured(strBtn3); // нажата ли кнопа CLOSE
   if(bolBtn1) // если нажата кнопка BUY
   {
     /*
      Здесь располагается код, отвечающий за торговые действия после нажатия кнопки BUY
     */
         //--- переведем кнопку в ненажатое состояние
         ObjectSetInteger(0, strBtn1, OBJPROP_STATE, false);
         //--- перерисуем график
         ChartRedraw();             
      }
   }
   else if(bolBtn2) // /если нажата кнопа SELL
   {
      /*
      Здесь располагается код, отвечающий за торговые действия после нажатия кнопки SELL
     */
         //--- переведем кнопку в ненажатое состояние
         ObjectSetInteger(0, strBtn2, OBJPROP_STATE, false);
         //--- перерисуем график
         ChartRedraw();             
      }
   }
   else if(bolBtn3) // если нажата кнопа CLOSE
   {
      /*
      Здесь располагается код, отвечающий за торговые действия после нажатия кнопки CLOSE
     */
      //--- переведем кнопку в ненажатое состояние
      ObjectSetInteger(0, strBtn3, OBJPROP_STATE, false);
      //--- перерисуем график
      ChartRedraw();       
   }
}

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

Код: выделить все
void OnDeinit(const int reason)
{
   //--- удалим кнопки
   f_ButtonDelete(0, strBtn1);
   f_ButtonDelete(0, strBtn2);
   f_ButtonDelete(0, strBtn3);
}
Аватар пользователя
Haos
Специалист MQL
 
Сообщений: 24699
Зарегистрирован: 29 мар 2014, 16:07
Средств на руках: 193.70 Доллар
Группа: Главные модераторы
Благодарил (а): 3379 раз.
Поблагодарили: 8200 раз.

Re: Как создать программную кнопку в коде эксперта?

Сообщение Haos » 03 май 2017, 16:02

Данный код использован в том числе при создании эксперта Колобок и при запуске эксперта три кнопки с соответствующими настройками выглядят так:
Вложения
KO-08.png
Аватар пользователя
Haos
Специалист MQL
 
Сообщений: 24699
Зарегистрирован: 29 мар 2014, 16:07
Средств на руках: 193.70 Доллар
Группа: Главные модераторы
Благодарил (а): 3379 раз.
Поблагодарили: 8200 раз.

Re: Как создать программную кнопку в коде эксперта?

Сообщение Haos » 12 май 2017, 13:40

Рассмотрим код, который нужно выполнить при нажатии кнопки CLOSE, т.е. для закрытия позиций (и удаления ордеров).
Код: выделить все
else if(bolBtn3) // если нажата кнопа CLOSE
{
      /*
      Здесь располагается код, отвечающий за торговые действия после нажатия кнопки CLOSE
     */
      //--- переведем кнопку в ненажатое состояние
      ObjectSetInteger(0, strBtn3, OBJPROP_STATE, false);
      //--- перерисуем график
      ChartRedraw();       
}

Вначале нужно проверить есть ли открытые позиции. Это происходит в операторе if-else переменная intPosi в коде эксперта отвечает за количество открытых позиций. Значение ей присвоено ранее в коде. Здесь можно ознакомиться со статью, посвященной определению количества открытых позиций. Далее вызывается функция f__ClosePositions(). Далее аналогично в операторе if-else проверяется есть ли установленные ордера и если они есть, то вызывается функция f_DeleteOrders() для удаления ордеров.

Код: выделить все
if(intPosi > 0) f__ClosePositions("0", -1, intMagic, intSI);
if(intOrds > 0) f_DeleteOrders("0", -1, intMagic);

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

Функция удаления ордеров:
Код: выделить все
void f_DeleteOrders(string sy = "", int op = -1, int mn = -1)
{
/*
   28/10/2015
   Описание : Удаление ордеров                                               
   Параметры:                                                               
   sy - наименование инструмента   (""  - любой символ,                   
                                    "0" - текущий символ)                 
   op - тип ордера на удаление     (-1   - любой ордер)                   
   mn - MagicNumber                (-1   - любой магик)                   
*/
   int      int_Try     = 5;              // Количество торговых попыток
   bool     bol_Sou     = false;           // Использовать звуковой сигнал
   string   str_Suc     = "ok.wav";       // Звук успеха
   string   str_Err     = "timeout.wav";  // Звук ошибки
   bool     bol_Sin     = false;          // Использовать значок удаления ордера?   
   color    clr_Del     = clrNONE;
   bool     bol_Del;                      // Сработала ли ф-ия OrderDelete

   int k = OrdersTotal(),
   ot;
   if (sy == "0") sy = Symbol();
   if(k == 0) return;               // нет ордеров вообще никаких
   
   if(bol_Sin) clr_Del = Yellow;  // Цвет значка удаления ордера
   for(int i = k - 1; i >= 0; i--)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         ot = OrderType();
         if(ot > 1 && ot < 6)
         {
            if((OrderSymbol() == sy || sy == "") && (op < 0 || ot == op))
            {
               if(mn < 0 || OrderMagicNumber() == mn)
               {
                  for(int j = 1; j <= int_Try; j++)
                  {
                     if(!IsTesting() && (!IsExpertEnabled() || IsStopped())) break;
                     while(!IsTradeAllowed()) Sleep(5000);
                     bol_Del = OrderDelete(OrderTicket(), clr_Del);
                     if(bol_Del)
                     {
                        if(bol_Sou) PlaySound(str_Suc); break;
                     }
                     else
                     {
                        if(bol_Sou) PlaySound(str_Err);
                        Print("Error(", GetLastError(),") delete order ", ot, " : try ", j);
                        Sleep(1000 * 5);
                     }
                  }
               }
            }
         }
      }
   }
}


Функция закрытия позиций по рыночной цене:
Код: выделить все
void f__ClosePositions(string sy, int op, int mn, int si)
{
/*
   Описание : Закрытие позиций по рыночной цене
   Используется функция: f__CloseOrder()   
   Параметры:                                                               
   sy - наименование инструмента   ("0" - текущий символ)                 
   op - операция                   (-1   - любая позиция)                 
   mn - MagicNumber                (-1   - любой магик)
   si - проскальзывание (slippage) (пнт.)               
*/
   if(sy == "0") sy = Symbol(); 
   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == false) break;
      if((OrderSymbol() == sy) && (op < 0 || OrderType() == op))
      {
         if(OrderType() == OP_BUY || OrderType() == OP_SELL)
         
            if(mn < 0 || OrderMagicNumber() == mn)   
            {
               RefreshRates();
               f__CloseOrder(sy, OrderTicket(), OrderLots(), si);
            }
         
      }
   }
}

//*********************************************************************************************

bool f__CloseOrder(string sy, int ti, double lo, int si)
{
/*
   Описание: 
   Используется функция: f__ProcessError()
   Параметры:                                                               
   sy - наименование инструмента ("0" - текущий символ)                 
   ti - OrderTicket()
   lo - OrderLots()
   si - проскальзывание (slippage) (пнт.)               
*/
   int int_Try = 5; // Количество торговых попыток

   if(lo < MarketInfo(sy, MODE_MINLOT)) return(false);
   if(OrderSelect(ti, SELECT_BY_TICKET) == true)
   {
      int i = 0;
      GetLastError();
      while(i < int_Try)
      {
         RefreshRates();
         double dbl_Pri = MarketInfo(sy, MODE_BID);
         if(OrderType() == OP_SELL) dbl_Pri = MarketInfo(sy, MODE_ASK);
         if(OrderClose(ti, lo, dbl_Pri, si))return(true);
         else
         {
            i++;
            if(!f__ProcessError(GetLastError())) return(false);
         }
      }
   }

return(false);
}

//*********************************************************************************************

bool f__ProcessError(int err)
{
/*
   Описание : Обработка ошибок
   Используется функция: f__PrintError()
   Параметры:                                                               
   err - номер ошибки           
*/
   int iteration;

   if(err > 1) f__PrintError(err);
   switch(err)
   {
   // Некритические ошибки
   case 0:     // ERR_NO_ERROR
   case 135:   // ERR_PRICE_CHANGED
   case 138:   // ERR_REQUOTE
      return(true);
   // Некритические ошибки, требующие таймаута
   case 4:     // ERR_SERVER_BUSY
   case 128:   // ERR_TRADE_TIMEOUT
      Sleep(1000 * 60);
      return(true);   
   case 129:   // ERR_INVALID_PRICE
   case 130:   // ERR_INVALID_STOPS
      //if (WorkMode==ModeManual && ShowConfirm) MessageBox("Неправильные стопы", VISITCARD, MB_OK);
      return(false);
   case 136:   // ERR_OFF_QUOTES
      Sleep(1000 * 5);
      return(true);   
   case 137:   // ERR_BROKER_BUSY
   case 145:   // ERR_TRADE_MODIFY_DENIED
      Sleep(1000 * 15);
      return(true);   
   // Нет связи с сервером. Пытаемся восстановить связь
   case 6:     // ERR_NO_CONNECTION
   {
      bool connect = false;
      iteration = 0;
      while((!connect) || (iteration < 60)) // в течение 5 минут пытаемся подконнектиться к серверу
      {
         Sleep(1000 * 5);
         connect = IsConnected();
         if(connect)
         {
            Print("Связь восстановлена");
            return(true);
         }
         iteration++;
         Print("Связь не восстановлена, прошло ", iteration * 5, " секунд.");
      }
      Print("Соединение в течение ", iteration * 5, " секунд восстановить не удалось.");
      return(false);
   }
   // Подсистема торговли занята. Ждем, пока освободится
   case 146:   // ERR_TRADE_CONTEXT_BUSY
   {
      bool tradecontextbusy = true;
      iteration = 0;
      while((tradecontextbusy) || (iteration < 60)) // в течение 5 минут ждем освобождения подсистемы торговли
      {
         Sleep(1000 * 5);
         tradecontextbusy = IsTradeContextBusy();
         if(!tradecontextbusy)
         {
            Print("Подсистема торговли освободилась.");
            return(true);
         }
         iteration++;
         Print("Подсистема торговли все еще занята, прошло ", iteration * 5, " секунд.");
      }
      Print("Подсистема торговли в течение ", iteration * 5, " секунд не освободилась.");
      return(false);
   }
   // Критические ошибки. Прекращаем попытки открытия ордера
   case 1:     // ERR_NO_RESULT
   case 2:     // ERR_COMMON_ERROR
   case 3:     // ERR_INVALID_TRADE_PARAMETERS
   case 5:     // ERR_OLD_VERSION
   case 7:     // ERR_NOT_ENOUGH_RIGHTS
   case 8:     // ERR_TOO_FREQUENT_REQUESTS
   case 9:     // ERR_MALFUNCTIONAL_TRADE
   case 64:    // ERR_ACCOUNT_DISABLED
   case 65:    // ERR_INVALID_ACCOUNT
   case 131:   // ERR_INVALID_TRADE_VOLUME
   case 132:   // ERR_MARKET_CLOSED
   case 133:   // ERR_TRADE_DISABLED
   case 134:   // ERR_NOT_ENOUGH_MONEY
   case 139:   // ERR_ORDER_LOCKED
   case 140:   // ERR_LONG_POSITIONS_ONLY_ALLOWED
   case 141:   // ERR_TOO_MANY_REQUESTS
   case 142:
   case 143:
   case 144:
   case 147:   // ERR_TRADE_EXPIRATION_DENIED
   case 148:   // ERR_TRADE_TOO_MANY_ORDERS
   case 4110:  // ERR_LONGS_NOT_ALLOWED
   case 4111:  // ERR_SHORTS_NOT_ALLOWED
      return(false);
   case 4109:  // ERR_TRADE_NOT_ALLOWED
      //MessageBox("Для совершения операций необходимо поставить галочку \"Разрешить советнику торговать\" в настройках терминала", VISITCARD, MB_OK);
      return(false);
   }
   return(false);
}

//*********************************************************************************************

int f__PrintError(int err)
{
   Print("ERROR ", err, ":  ", f__Err2str(err));
   return(0);
}

//*********************************************************************************************

//+------------------------------------------------------------------+
//| Получение описания ошибки по ее номеру                           |
//+------------------------------------------------------------------+
string f__Err2str(int err)
{
   switch(err)
   {
   case 0:
      return("Нет ошибки");
   case 1:
      return("Функция модификации ордера пытается изменить уже установленные значения такими же значениями");
   case 2:
      return("Общая ошибка");
   case 3:
      return("В торговую функцию переданы неправильные параметры");
   case 4:
      return("Торговый сервер занят");
   case 5:
      return("Старая версия клиентского терминала");
   case 6:
      return("Нет связи с торговым сервером");
   case 7:
      return("Недостаточно прав");
   case 8:
      return("Слишком частые запросы");
   case 9:
      return("Недопустимая операция нарушающая функционирование сервера");
   case 64:
      return("Счет заблокирован");
   case 65:
      return("Неправильный номер счета");
   case 128:
      return("Истек срок ожидания совершения сделки");
   case 129:
      return("Неправильная цена");
   case 130:
      return("Неправильные стопы");
   case 131:
      return("Неправильный объем сделки");
   case 132:
      return("Рынок закрыт");
   case 133:
      return("Торговля запрещена");
   case 134:
      return("Недостаточно денег для совершения операции");
   case 135:
      return("Цена изменилась");
   case 136:
      return("Нет цен");
   case 137:
      return("Брокер занят");
   case 138:
      return("Реквот! Новые цены");
   case 139:
      return("Ордер заблокирован и уже обрабатывается");
   case 140:
      return("Разрешена только покупка");
   case 141:
      return("Слишком много запросов");
   case 142:
      return("Ордер поставлен в очередь");
   case 143:
      return("Ордер принят дилером к исполнению");
   case 144:
      return("Ордер аннулирован самим клиентом при ручном подтверждении сделки");
   case 145:
      return("Модификация запрещена, так как ордер слишком близок к рынку");
   case 146:
      return("Подсистема торговли занята");
   case 147:
      return("Использование даты истечения ордера запрещено брокером");
   case 148:
      return("Количество открытых и отложенных ордеров достигло предела, установленного брокером");
   case 4109:
      return("Торговля не разрешена. Необходимо включить опцию \"Разрешить советнику торговать\" в свойствах эксперта");
   case 4110:
      return("Длинные позиции не разрешены");
   case 4111:
      return("Короткие позиции не разрешены");
   }
   return("Описание ошибки не известно");
}

Данную функции сопутствуют несколько функций, служащих вспомогательными для обработки ошибок при закрытии позиций, поэтому они также приводятся.
Аватар пользователя
Haos
Специалист MQL
 
Сообщений: 24699
Зарегистрирован: 29 мар 2014, 16:07
Средств на руках: 193.70 Доллар
Группа: Главные модераторы
Благодарил (а): 3379 раз.
Поблагодарили: 8200 раз.

Как создать программную кнопку в коде эксперта?

Сообщение ВЯЧЕСЛАВПЕТРОВ » 10 июл 2017, 09:02

Тема интересная спасибо. начал потихонечку присоединять кнопки к советнику. Возник сразу вопрос можно перенести кнопки в нижний угол экрана . В верхнем информация выводиться или как вариант сделать подвижное окно которое можно перемешать по экрану.
Аватар пользователя
ВЯЧЕСЛАВПЕТРОВ
 
Сообщений: 1522
Зарегистрирован: 06 сен 2016, 21:28
Средств на руках: 90.40 Доллар
Награды: 2
Ветеран I (1) Медаль за эрудицию (1)
Группа: Базовая
Благодарил (а): 3574 раз.
Поблагодарили: 434 раз.
Автор Вячеслав Петров. Возьму капитал или счет в управление. В лс.
Мониторинг трех счетной системы. Первый.Второй. Третий.
Четвертый.

Re: Как создать программную кнопку в коде эксперта?

Сообщение Рэндом » 10 июл 2017, 09:09

Да, можно. Нужно задать привязку к нужному углу окна. Как это сделать я точно не помну. Посмотрите справку.
Аватар пользователя
Рэндом
Специалист MQL
 
Сообщений: 13700
Зарегистрирован: 18 июл 2013, 08:05
Средств на руках: 31.45 Доллар
Группа: Администраторы
Благодарил (а): 1131 раз.
Поблагодарили: 3174 раз.
Каждый заблуждается в меру своих возможностей.

Re: Как создать программную кнопку в коде эксперта?

Сообщение Рэндом » 10 июл 2017, 10:29

Функция ObjectSet

Изменяет значение указанного свойства объекта.



bool ObjectSet(
string object_name, // имя объекта
int index, // идентификатор свойства
double value // значение
);

Объект предварительно надо создать.

OBJPROP_CORNER

Угол графика для привязки графического объекта
Это переменная index.

ENUM_BASE_CORNER



Идентификатор

Описание


CORNER_LEFT_UPPER

Центр координат в левом верхнем углу графика


CORNER_LEFT_LOWER

Центр координат в левом нижнем углу графика


CORNER_RIGHT_LOWER

Центр координат в правом нижнем углу графика


CORNER_RIGHT_UPPER

Центр координат в правом верхнем углу графика

это значение.
Аватар пользователя
Рэндом
Специалист MQL
 
Сообщений: 13700
Зарегистрирован: 18 июл 2013, 08:05
Средств на руках: 31.45 Доллар
Группа: Администраторы
Благодарил (а): 1131 раз.
Поблагодарили: 3174 раз.
Каждый заблуждается в меру своих возможностей.

Re: Как создать программную кнопку в коде эксперта?

Сообщение Haos » 10 июл 2017, 10:53

ВЯЧЕСЛАВПЕТРОВ писал(а):Тема интересная спасибо. начал потихонечку присоединять кнопки к советнику. Возник сразу вопрос можно перенести кнопки в нижний угол экрана . В верхнем информация выводиться или как вариант сделать подвижное окно которое можно перемешать по экрану.

Вы первое сообщение темы внимательно читали?
Код: выделить все
ENUM_BASE_CORNER  enuCorn  = CORNER_LEFT_UPPER; // Угол графика для привязки

Рэндом писал(а):Функция ObjectSet
Изменяет значение указанного свойства объекта.....

Это ничего не нужно. В коде, приведенном в начале темы, всё уже запрограммировано. Нужно только изучающему внимательно изучать.
Аватар пользователя
Haos
Специалист MQL
 
Сообщений: 24699
Зарегистрирован: 29 мар 2014, 16:07
Средств на руках: 193.70 Доллар
Группа: Главные модераторы
Благодарил (а): 3379 раз.
Поблагодарили: 8200 раз.


Вернуться в MQL – теория и практика

Кто сейчас на форуме?

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 63

Права доступа к форуму

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

cron