Открытие позиции (отдельная функция)

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

Открытие позиции (отдельная функция)

Сообщение Haos » 20 янв 2022, 19:23

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

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

Поэтому мы должны проверить возможность торговли и если условия не изменились, то сделать паузу и еще раз попробовать открыть сделку:
Код: выделить все
while(!IsTradeAllowed()) Sleep(5000);

Само-собой, котировки нужно будет обновить, т.к. цена за это время может измениться:
Код: выделить все
RefreshRates();

Далее. Мы должны иметь возможность управлять следующими параметрами при открытии сделки, а именно:
- использовать ли звук при открытии или нет;
- установить звук открытия сделки и ошибки, если всё же звук должен быть;
- использовать ли значок открытия сделки;
- если да, то задать цвет значка для покупки и продажи.

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

И после того, как мы вызвали зарезервированную функцию OrderSend мы должны проанализировать результат её работы, т.е. была ли сделка открыта или возникла ошибка? Какая возникла ошибка? Может ли она быть устранена? Но, хотя бы, должна быть пользователю сообщена информация о том, что сделка открыта или произошла ошибка.

Итак, вот такие минимальные требования к функции для открытия позиции должны быть запрограммированы.
Код функции для открытия позиции с названием f_OpenPosition() расположен ниже:
Код: выделить все
void f_OpenPosition(string sy, int op, double ll, double sl, double tp, int mn, int si, string co)
{
/*
   Версия   : 13.09.2015                                                     
   Описание : Открывает позицию по рыночной цене   
   Сторонних ресурсов не использует!!!                       
   Параметры:                                                               
   sy - наименование инструмента   ("0" - текущий символ)         
   op - операция {OP_BUY; OP_SELL}                                                           
   ll - лот                                                               
   sl - уровень стоп (0)                                                     
   tp - уровень тейк  (0)                                                   
   mn - MagicNumber
   si - проскальзывание (slippage) (пнт.)                                                       
   co - комментарий ("" - нет комментария)                                                       
*/
   double   pp;
   int      int_Tic     = 0;
   int      int_Try     = 5;              // Количество торговых попыток
   bool     bol_Sou     = true;           // Использовать звуковой сигнал
   string   str_Suc     = "ok.wav";       // Звук успеха
   string   str_Err     = "timeout.wav";  // Звук ошибки
   bool     bol_Sin     = false;           // Использовать значок открытия сделки?
   color    clOpen      = clrNONE,
            clOpenBuy   = LightBlue,      // Цвет значка открытия покупки
            clOpenSell  = LightCoral;     // Цвет значка открытия продажи
   double   dbl_Ask,
            dbl_Bid;
   
   if(sy == "0") sy = Symbol();   
   int int_Dig  = (int) MarketInfo(sy, MODE_DIGITS);
   
   for(int i = 1; i <= int_Try; i++)
   {
      if(!IsTesting() && (!IsExpertEnabled() || IsStopped()))
      {
         Print("OpenPosition(): Остановка работы функции");
         break;
      }
      while(!IsTradeAllowed()) Sleep(5000);
      RefreshRates();
      if(op == OP_BUY)
      {
         dbl_Ask  = MarketInfo(sy, MODE_ASK);
         pp = dbl_Ask;
         if(bol_Sin) clOpen = clOpenBuy;
      }
      else if(op == OP_SELL)
      {
         dbl_Bid  = MarketInfo(sy, MODE_BID);
         pp = dbl_Bid;
         if(bol_Sin) clOpen = clOpenSell;
      }
      pp = NormalizeDouble(pp, int_Dig);
      int_Tic = OrderSend(sy, op, ll, pp, si, sl, tp, co, mn, 0, clOpen);
      if(int_Tic > 0)
      {
         if(bol_Sou) PlaySound(str_Suc);
         Print("Функция OrderSend успешно выполнена");
         break;
      }
      else if(int_Tic < 0)
      {
         if(bol_Sou) PlaySound(str_Err);
         Print("OrderSend завершилась с ошибкой #", GetLastError());
      }
   }
}

Рассмотрим алгоритм этой функции подробнее. Данная функция имеет тип void, т.е. аналог процедуры, не возвращается никаких значений.
В функцию f_OpenPosition передаются следующие параметры:
sy - наименование инструмента ("0" - текущий символ), функция должна уметь открывать позицию по любому инструменту;
op - операция {OP_BUY; OP_SELL}
ll - лот
sl - уровень стоп (0)
tp - уровень тейк (0)
mn - MagicNumber (этот параметр обязателен для советников);
si - проскальзывание (slippage) (пнт.)
co - комментарий ("" - нет комментария), функция должна иметь возможность вставки комментерия при открытии позиции.

Вначале мы фиксируем в переменных имя торгового инструмента, количество цифр в его котировках после точки.
Далее организуется цикл торговых попыток. В зависимости от типа сделки (покупка или продажа) мы получаем рыночные цены и определяемся с тем, нужно ли отображать будет значок сделки. Результат выполнения функции OrderSend() запоминаем в переменной int_Tic (тикет). При успешности открытия сделки сопровождаем звуковым сигналом (если выбран), а также сообщением об успешности открытия сделки. В случае ошибки при открытии сделки, выводим сообщение о том, что попытка отрыть сделку вызвала ошибку. Возвращаем код ошибки для анализа последующего. На этом цикл попыток открытия позиции заканчивается. Количество попыток определяет разработчик. Обычно, пользователю это не нужно знать.

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

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

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

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

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

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

cron