Закрываем открытые ордера с помощью функции OrderClose

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

При программировании советника мы всегда должны защищать свой торговый счет от больших потерь. Управление рисками является основой работы любого советника. Необходимо установить правила, чтобы ваш советник мог закрыть все ордера, если выполняется какое-либо условие. К примеру:

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

Это только некоторые ситуации, которые могут подтолкнуть вас к немедленному закрытию всех открытых ордеров.

Давайте рассмотрим, как можно закрывать ордера с помощью функции OrderClose(). OrderClose() – это функция MQL4, которая позволяет полностью или частично закрывать открытые рыночные ордера. Эта функция требует следующие параметры:

bool  OrderClose(
   int        ticket,      // номер ордера
   double     lots,        // количество лотов
   double     price,       // цена закрытия
   int        slippage,    // максимальное проскальзывание
   color      arrow_color  // цвет
   );
  • ticket – номера тикета, чтобы определить, какой ордер нужно закрыть.
  • lots – это размер лота, который нужно закрыть. Например, если ордер является ордером BUY с 1 лотом, вы можете закрыть всю позицию, указав 1 лот, или закрыть ее частично, например, 0,6 лота, остальные 0,4 останутся открытыми.
  • price – цена закрытия ордера.
  • slippage – проскальзывание или допустимая разница между запрашиваемой ценой закрытия и ценой, которую предоставляет брокер в данный момент времени.
  • arrow_color – цвет стрелки на графике (необязательный параметр).

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

Закроем рыночный ордер на покупку:

OrderSelect(CloseTicket,SELECT_BY_TICKET);

if(OrderCloseTime() == 0 && OrderType() == OP_BUY)
      {
        double CloseLots = OrderLots();
        double ClosePrice = Bid;
        bool Closed = OrderClose(CloseTicket,CloseLots,ClosePrice,UseSlippage,Red);
      }

Переменная CloseTicket – это номер тикета ордера, который мы хотим закрыть. Функция OrderSelect() выбирает ордер и позволяет нам получить информацию о нем. Мы используем OrderCloseTime(), чтобы проверить время закрытия ордера, чтобы увидеть, был ли ордер уже закрыт. Если OrderCloseTime() возвращает 0, тогда мы знаем, что ордер еще не закрыт.

Нам также необходимо проверить тип ордера, так как тип ордера определяет цену его закрытия. Функция OrderType() возвращает целое число, указывающее на тип ордера. Если это рыночный ордер на покупку, обозначенный OP_BUY, мы продолжим закрывать ордер.

Затем мы получаем размер лота ордера с помощью OrderLots() и сохраняем это значение в переменную CloseLots. Мы назначаем текущую цену Bid для ClosePrice. Затем мы вызываем функцию OrderClose(), чтобы закрыть наш ордер.

Мы задаем наш параметр Slippage с помощью UseSlippage и указываем красную стрелку, которая будет напечатана на графике. Возвращаемое значение сохраняется в переменной Closed. Если ордер был успешно закрыт, значение Closed будет true, в противном случае – false.

Чтобы закрыть ордер на продажу, все, что вам нужно сделать, это изменить тип ордера на OP_SELL и назначить текущую цену Ask для ClosePrice:

if (OrderCloseTime () == 0 && OrderType () == OP_SELL) {
        double CloseLots = OrderLots (); 
        double ClosePrice = Ask;
        bool Closed = OrderClose (CloseTicket, CloseLots, ClosePrice, UseSlippage, Red);
      }

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

void CloseOrders(){
   
   //Обновляем значения цен перед закрытием ордеров
   RefreshRates();
      //Выводим в терминал общее количество открытых и отложенных ордеров.
      Print(OrdersTotal());
      
   //Создаем цикл, который перебирает все ордера. Цикл начинает работать с последнего ордера, чтобы ни один ордер не был пропущен.
   for(int i=(OrdersTotal()-1);i>=0;i--){
      
      //Если ордер не может быть выбран, выводим ошибку.
     if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false){
         Print("Ошибка. Нельзя выбрать ордер - ",GetLastError());
         break;
      } 

      //Создаем переменную результата, чтобы проверить, успешна ли прошла операция.
      bool res=false;
      
      //Проскальзывание, которое представляет собой разницу между текущей ценой и ценой закрытия.
      int Slippage=0;
      
      //Цены Bid и Ask для ордера.
      double BidPrice=MarketInfo(OrderSymbol(),MODE_BID);
      double AskPrice=MarketInfo(OrderSymbol(),MODE_ASK);

      //Закрытие ордера по его текущей цене в зависимости от типа ордера.
      if(OrderType()==OP_BUY){
         res=OrderClose(OrderTicket(),OrderLots(),BidPrice,Slippage);
      }
      if(OrderType()==OP_SELL){
         res=OrderClose(OrderTicket(),OrderLots(),AskPrice,Slippage);
      }
      
      //Если была ошибка, выводим ее в журнал ошибок.
      if(res==false) Print("Ошибка. Нельзя закрыть ордер - ",OrderTicket()," - ",GetLastError());
   }
}

В данной функции мы:

  1. Обновляем текущие цены.
  2. C помощью цикла перебираем все открытые ордера.
  3. Если ордер открыт, получаем его детали.
  4. Закрываем ордер по его текущей цене.
  5. Проверяем, была ли операция успешной для каждого ордера. Если нет, выводим ошибку.

Функция не очень сложна и может быть улучшена с помощью дополнительных фильтров. Например, вы можете создать некоторые из следующих фильтров:

  • Закрыть только прибыльные ордера.
  • Закрыть только убыточные ордера.
  • Закрыть только ордера для конкретной валютной пары.
  • Закрыть только ордера с определенным магическим номером.
Лучшие, на мой взгляд, брокеры:
Загрузить еще

Добавить комментарий

Ваш e-mail не будет опубликован.