Советник для удаления отложенных ордеров

 

Коллеги, добрый день. Может есть у кого, либо подскажите как сделать простенький советник.

Есть скрипт, который выставляет отложенные ордера по определенной цене. Нужно чтобы советник, после прохождения определенного количества пунктов от цены несработавшего ордера, до текущей цены (2 стопа), удалял несработавший ордер. К примеру сделать переменную DellOrd = и задать количество пунктов, после которого несработавший ордер будет удалятся.  

Вот сам скрипт

extern datetime TimeSet        = D'2020.10.01 00:00:00'; //Время выставления ордеров, если текущее время больше установленного, то выставляются сразу

extern bool     Buy            = false;     //открыть Buy ордер 

extern bool     Sell           = false;     //открыть Sell ордеа 

extern bool     BuyStop        = false;     //открыть BuyStop ордера 

extern bool     BuyLimit       = true;     //открыть BuyLimit ордера 

extern bool     SellStop       = false;     //открыть SellStop ордера 

extern bool     SellLimit      = true;     //открыть SellLimit ордера 

extern string   __             = "";

extern double   FirstBuyStop   = 0;        //цена выставления первого BuyStop ордера, если 0 то первый BuyStop будет выставлен по цене Ask+FirstStop

extern double   FirstSellStop  = 0;        //цена выставления первого SellStop ордера, если 0 то первый SellStop будет выставлен по цене Bid-FirstStop

extern double   FirstBuyLimit  = 0;        //цена выставления первого BuyLimit ордера, если 0 то первый BuyLimit будет выставлен по цене Bid-FirstStop

extern double   FirstSellLimit = 0;        //цена выставления первого SellLimit ордера, если 0 то первый SellLimit будет выставлен по цене Ask+FirstStop

extern int      FirstStop      = 0;      //расстояние (в пунктах) от текущей цены до первого Stop ордера в случае First..Stop=0 

extern int      FirstLimit     = 0;       //расстояние (в пунктах) от текущей цены до первого Limit ордера в случае First..Limit=0

extern int      StepStop       = 0;       //расстояние (в пунктах) между Stop ордерами

extern double   K_StepStop     = 0;        //коэффициент расширения сетки

extern int      StepLimit      = 0;       //расстояние (в пунктах) между Limit ордерами

extern double   K_StepLimit    = 0;        //коэффициент расширения сетки

extern string   _              = "";

extern int      Orders         = 0;        //кол-во ордеров сетки

extern double   LotMarket      = 0;      //объем рыночных ордеров

extern double   LotStop        = 0;      //объем первого Stop ордера

extern double   K_LotStop      = 0;        //умножение лота Stop ордеров 

extern double   Plus_LotStop   = 0;        //добавление лота Stop ордеров 

extern double   LotLimit       = 1;      //объем первого Limit ордера

extern double   K_LotLimit     = 0;        //умножение лота Limit ордеров

extern double   Plus_LotLimit  = 0;        //добавление лота Limit ордеров

extern int      stoploss       = 0;       //уровень выставления SL, если 0, то SL не выставляется

extern int      takeprofit     = 0;      //уровень выставления TP, если 0, то TP не выставляется

extern int      Expiration     = 0;    //Срок истечения отложенного ордера в секундах, если 0, то срок не ограничен (86400 - сутки)

extern int      attempts       = 10;       //кол-во попыток открытия ордера 

extern int      Magic          = 0;        //уникальный номер ордера

extern string   Order_Comment  = "http://cmillion.narod.ru";

//--------------------------------------------------------------------

string txt;

int n,slippage=3,STOPLEVEL;

datetime expiration;

//--------------------------------------------------------------------

int start()

{

//===========================================================================================================================================   

//===========================================================================================================================================   

//===========================================================================================================================================   

/*============================================*/if (IsTesting() && OrdersTotal()>0) return(0);/*===============================================*/

//===========================================================================================================================================   

//===========================================================================================================================================   

//===========================================================================================================================================   

   if (Expiration>0) expiration=TimeCurrent()+Expiration; else expiration=0;

   Comment("Запуск скрипта OpenStopOrderNetTime ",TimeToStr(TimeCurrent(),TIME_DATE|TIME_SECONDS));

   STOPLEVEL=MarketInfo(Symbol(),MODE_STOPLEVEL);

   if (Digits==3 || Digits==5) slippage=30;

   while (TimeCurrent()<TimeSet)

   {

      Sleep(1000);

      Comment("Скрипт для выставления отложенных ордеров",

      TimeToStr(TimeCurrent(),TIME_SECONDS)," До выставления отложенного ордера осталось ",TimeToStr(TimeSet-TimeCurrent(),TIME_SECONDS));

      RefreshRates();

   }

   double PriceBS,PriceBL,PriceSS,PriceSL;

   double LOTs=LotStop;

   double LOTl=LotLimit;

   if (FirstBuyStop==0) PriceBS = NormalizeDouble(Ask+FirstStop*Point,Digits);

   else PriceBS = NormalizeDouble(FirstBuyStop,Digits);

   if ((PriceBS-Ask)/Point<STOPLEVEL) {Alert("Первый ордер BuyStop не может быть установлен ближе чем ",STOPLEVEL," п");return(0);}

   

   if (FirstSellStop==0) PriceSS = NormalizeDouble(Bid-FirstStop*Point,Digits);

   else PriceSS = NormalizeDouble(FirstSellStop,Digits);

   if ((Bid-PriceSS)/Point<STOPLEVEL) {Alert("Первый ордер SellStop не может быть установлен ближе чем ",STOPLEVEL," п");return(0);}

   

   if (FirstBuyLimit==0) PriceBL = NormalizeDouble(Bid-FirstLimit*Point,Digits);

   else PriceBL = NormalizeDouble(FirstBuyLimit,Digits);

   if ((Bid-PriceBL)/Point<STOPLEVEL) {Alert("Первый ордер BuyLimit не может быть установлен ближе чем ",STOPLEVEL," п");return(0);}

   

   if (FirstSellLimit==0) PriceSL = NormalizeDouble(Ask+FirstLimit*Point,Digits);

   else PriceSL = NormalizeDouble(FirstSellLimit,Digits);

   if ((PriceSL-Ask)/Point<STOPLEVEL) {Alert("Первый ордер SellLimit не может быть установлен ближе чем ",STOPLEVEL," п");return(0);}

   

   double Step_Stop=StepStop;

   double Step_Limit=StepLimit;

   if (Buy) OPENORDER (OP_BUY,Ask,LotMarket,0);

   if (Sell) OPENORDER (OP_SELL,Bid,LotMarket,0);

   for (int i=1; i<=Orders; i++)

   {

      if (BuyStop||SellStop)

      {

         Step_Stop=Step_Stop*K_StepStop;

         if (BuyStop)

         {

            OPENORDER (OP_BUYSTOP,PriceBS,LOTs,i);

            PriceBS = NormalizeDouble(PriceBS+Step_Stop*Point,Digits);

         }

         if (SellStop)

         {  

            OPENORDER (OP_SELLSTOP,PriceSS,LOTs,i);

            PriceSS = NormalizeDouble(PriceSS-Step_Stop*Point,Digits);

         }

      }

      LOTs=LOTs*K_LotStop+Plus_LotStop;

      if (BuyLimit||SellLimit)

      {

         Step_Limit=Step_Limit*K_StepLimit;

         if (BuyLimit)

         {

            OPENORDER (OP_BUYLIMIT,PriceBL,LOTl,i);

            PriceBL = NormalizeDouble(PriceBL-Step_Limit*Point,Digits);

         }

         if (SellLimit)

         {  

            OPENORDER (OP_SELLLIMIT,PriceSL,LOTl,i);

            PriceSL = NormalizeDouble(PriceSL+Step_Limit*Point,Digits);

         }

      }

      LOTl=LOTl*K_LotLimit+Plus_LotLimit;

   }

   Comment("Скрипт закончил свою работу, выставлено ",n," ордеров  ",TimeToStr(TimeCurrent(),TIME_DATE|TIME_SECONDS));

return(0);

}

//--------------------------------------------------------------------

void OPENORDER(int ord,double Price,double LOT,int i)

{

   int error,err;

   double SL,TP;

   while (true)

   {  error=true;

      if (ord==OP_BUY) 

      {

         if (takeprofit!=0) TP  = NormalizeDouble(Price + takeprofit*Point,Digits); else TP=0;

         if (stoploss!=0)   SL  = NormalizeDouble(Price - stoploss*Point,Digits); else SL=0;     

         error=OrderSend(Symbol(),ord, LOT,Price,slippage,SL,TP,Order_Comment,Magic,expiration,Blue);

      }

      if (ord==OP_SELL) 

      {

         if (takeprofit!=0) TP = NormalizeDouble(Price - takeprofit*Point,Digits); else TP=0;

         if (stoploss!=0)   SL = NormalizeDouble(Price + stoploss*Point,Digits);  else SL=0;              

         error=OrderSend(Symbol(),ord,LOT,Price,slippage,SL,TP,Order_Comment,Magic,expiration,Red);

      }

      if (ord==OP_BUYSTOP) 

      {

         if (takeprofit!=0) TP  = NormalizeDouble(Price + takeprofit*Point,Digits); else TP=0;

         if (stoploss!=0)   SL  = NormalizeDouble(Price - stoploss*Point,Digits); else SL=0;     

         error=OrderSend(Symbol(),ord, LOT,Price,slippage,SL,TP,Order_Comment,Magic,expiration,Blue);

      }

      if (ord==OP_SELLSTOP) 

      {

         if (takeprofit!=0) TP = NormalizeDouble(Price - takeprofit*Point,Digits); else TP=0;

         if (stoploss!=0)   SL = NormalizeDouble(Price + stoploss*Point,Digits);  else SL=0;              

         error=OrderSend(Symbol(),ord,LOT,Price,slippage,SL,TP,Order_Comment,Magic,expiration,Red);

      }

      if (ord==OP_SELLLIMIT) 

      {

         if (takeprofit!=0) TP = NormalizeDouble(Price - takeprofit*Point,Digits); else TP=0;

         if (stoploss!=0)   SL = NormalizeDouble(Price + stoploss*Point,Digits);  else SL=0;              

         error=OrderSend(Symbol(),ord, LOT,Price,slippage,SL,TP,Order_Comment,Magic,expiration,Blue);

      }

      if (ord==OP_BUYLIMIT) 

      {

         if (takeprofit!=0) TP  = NormalizeDouble(Price + takeprofit*Point,Digits); else TP=0;

         if (stoploss!=0)   SL  = NormalizeDouble(Price - stoploss*Point,Digits); else SL=0;     

         error=OrderSend(Symbol(),ord,LOT,Price,slippage,SL,TP,Order_Comment,Magic,expiration,Red);

      }

      if (error==-1)

      {  

         txt=StringConcatenate(txt,"\nError ",GetLastError());

         if (ord==OP_BUY)   txt = StringConcatenate(txt,"  OPENORDER BUY  Price =",DoubleToStr(Price,Digits),")  SL =",DoubleToStr(SL,Digits)," (",NormalizeDouble((Price-SL)/Point,0),")  TP=",DoubleToStr(TP,Digits)," (",NormalizeDouble((TP-Price)/Point,0),")  STOPLEVEL=",STOPLEVEL);

         if (ord==OP_SELL)  txt = StringConcatenate(txt,"  OPENORDER SELL  Price =",DoubleToStr(Price,Digits),")  SL =",DoubleToStr(SL,Digits)," (",NormalizeDouble((SL-Price)/Point,0),")  TP=",DoubleToStr(TP,Digits)," (",NormalizeDouble((Price-TP)/Point,0),")  STOPLEVEL=",STOPLEVEL);

         if (ord==OP_BUYSTOP)   txt = StringConcatenate(txt,"  OPENORDER BUYSTOP ",  i,"   Ask =",DoubleToStr(Ask,Digits),"   Price =",DoubleToStr(Price,Digits)," (",NormalizeDouble((Price-Ask)/Point,0),")  SL =",DoubleToStr(SL,Digits)," (",NormalizeDouble((Price-SL)/Point,0),")  TP=",DoubleToStr(TP,Digits)," (",NormalizeDouble((TP-Price)/Point,0),")  STOPLEVEL=",STOPLEVEL);

         if (ord==OP_SELLSTOP)  txt = StringConcatenate(txt,"  OPENORDER SELLSTOP ", i,"   Bid =",DoubleToStr(Bid,Digits),"   Price =",DoubleToStr(Price,Digits)," (",NormalizeDouble((Bid-Price)/Point,0),")  SL =",DoubleToStr(SL,Digits)," (",NormalizeDouble((SL-Price)/Point,0),")  TP=",DoubleToStr(TP,Digits)," (",NormalizeDouble((Price-TP)/Point,0),")  STOPLEVEL=",STOPLEVEL);

         if (ord==OP_SELLLIMIT) txt = StringConcatenate(txt,"  OPENORDER SELLLIMIT ",i,"   Ask =",DoubleToStr(Ask,Digits),"   Price =",DoubleToStr(Price,Digits)," (",NormalizeDouble((Price-Ask)/Point,0),")  SL =",DoubleToStr(SL,Digits)," (",NormalizeDouble((Price-SL)/Point,0),")  TP=",DoubleToStr(TP,Digits)," (",NormalizeDouble((TP-Price)/Point,0),")  STOPLEVEL=",STOPLEVEL);

         if (ord==OP_BUYLIMIT)  txt = StringConcatenate(txt,"  OPENORDER BUYLIMIT ", i,"   Bid =",DoubleToStr(Bid,Digits),"   Price =",DoubleToStr(Price,Digits)," (",NormalizeDouble((Bid-Price)/Point,0),")  SL =",DoubleToStr(SL,Digits)," (",NormalizeDouble((SL-Price)/Point,0),")  TP=",DoubleToStr(TP,Digits)," (",NormalizeDouble((Price-TP)/Point,0),")  STOPLEVEL=",STOPLEVEL);

         Print(txt);

         Comment(txt,"  ",TimeToStr(TimeCurrent(),TIME_DATE|TIME_SECONDS));

         err++;Sleep(1000);RefreshRates();

      }

      else 

      {

         Comment("Ордер ",error," успешно выставлен ",TimeToStr(TimeCurrent(),TIME_DATE|TIME_SECONDS));

         n++;

         return;

      }

      if (err>attempts) return;

   }

return;

}                  

//--------------------------------------------------------------------

 

вот скрипт удаляет все отложенные ордера 

//+------------------------------------------------------------------+
//|                                                      DellOrd.mq4 |
//|                        Copyright 2021, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#include <stdlib.mqh>
//---
bool   CloseOpenOrders  = true;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   CloseAllOrders();
  }
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
void CloseAllOrders(void)
  {
   int iOrders=OrdersTotal()-1, i;
   if(CloseOpenOrders)
     {
      for(i=iOrders; i>=0; i--)
        {
         if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
           {
            if(OrderDelete(OrderTicket()))
               Print(OrderError());
           }
        }
     }
  }
//+------------------------------------------------------------------+
//| Function..: OrderError                                           |
//+------------------------------------------------------------------+
string OrderError(void)
  {
   int iError=GetLastError();
   return(StringConcatenate("Order:",OrderTicket()," GetLastError()=",iError," ",ErrorDescription(iError)));
  }
//+------------------------------------------------------------------+
Документация по MQL5: Константы, перечисления и структуры / Торговые константы / Свойства ордеров
Документация по MQL5: Константы, перечисления и структуры / Торговые константы / Свойства ордеров
  • www.mql5.com
Свойства ордеров - Торговые константы - Константы, перечисления и структуры - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
Интересует чтобы советник, после прохождения определенного количества пунктов от цены несработавшего ордера, удалял несработанные ордера
 
Evgenii Kasimov:
Интересует чтобы советник, после прохождения определенного количества пунктов от цены несработавшего ордера, удалял несработанные ордера

Проверьте разницу между текущей ценой и ценой ордера. Если ордеров больше одного проверьте в цикле.

Если сами не можете сделать вам в фриланс.

https://www.mql5.com/ru/job

Торговые приложения для MetaTrader 5 на заказ
Торговые приложения для MetaTrader 5 на заказ
  • 2021.02.26
  • www.mql5.com
Самый большой фриланс c разработчиками программ на MQL5
 
Evgenii Kasimov:
Интересует чтобы советник, после прохождения определенного количества пунктов от цены несработавшего ордера, удалял несработанные ордера

для мт5 можно просмотреть код https://www.mql5.com/ru/code/26286- как это реализовано. - думаю и для мт4 есть типа такого кода.

- Если есть желание, то всё можно найти в кодобазе.

Opening Day Two Pending Orders
Opening Day Two Pending Orders
  • www.mql5.com
В начале дня выставляются два противоположных отложенных ордера (или два stop или два limit)
 
Благодарю коллеги, буду искать
 
SanAlex:

вот скрипт удаляет все отложенные ордера 

так корректнее

if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) && OrderType()>1)
 
Renat Akhtyamov:

так корректнее

а так вообще нельзя...за такое бьют и лишают премий :-)

 
Maxim Kuznetsov:

а так вообще нельзя...за такое бьют и лишают премий :-)

у него там на удаление все подряд

такую автоторговлю ДЦ и забанить может

;)

лично у меня работает годами без проблем то, как я написал

просто вдруг откуда не возьмись, бац и отложка

нежданно негаданно

а я ими вообще не работаю

;)))

 
Renat Akhtyamov:

так корректнее

Обычно я проверяю на демо счёте - если функция, своё предназначение делает, значит функция рабочая!  

для мт5 закрытие всех Отложенных ордеров - Такой код для себя нашёл в кодобазе - работает отлично!

//+------------------------------------------------------------------+
//|                                                DeletePending.mq5 |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#include <Trade\Trade.mqh>
CTrade m_trade; // trading object
//---
uint SLEEPTIME=1;   // Время паузы между повторами в секундах
uint RTOTAL=4;      // Число повторов при неудачных сделках
uint Deviation_=10; // Отклонение цены
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   DeletePending();
  }
//+------------------------------------------------------------------+
//| start function                                                   |
//+------------------------------------------------------------------+
void DeletePending(void)
  {
   Print("Сработала функция закрываем все выставленные ордера");
//----
   for(uint count=0; count<=RTOTAL && !IsStopped(); count++)
     {
      //---- закрываем все выставленные ордера по текущему символу
      int total=OrdersTotal();
      if(!total)
         return; // все ордера закрыты
      for(int pos=total-1; pos>=0; pos--)
        {
         ulong ticket=ulong(OrderGetTicket(pos));
         if(!OrderSelect(ticket))
            continue;
         string symbol=OrderGetString(ORDER_SYMBOL);
         bool _Close=true;
         OrderCloseByTicket(_Close,symbol,ticket,Deviation_);
        }
      if(!OrdersTotal())
         break;
      Sleep(SLEEPTIME*1000);
     }
//----
  }
//+------------------------------------------------------------------+
//| Закрываем длинную позицию                                        |
//+------------------------------------------------------------------+
bool OrderCloseByTicket
(
   bool &Signal,         // флаг разрешения на сделку
   const string symbol,  // торговая пара сделки
   ulong ticket,         // тикет
   uint deviation        // слиппаж
)
  {
//----
   if(!Signal)
      return(true);
//---- Объявление структур торгового запроса и результата торгового запроса
   MqlTradeRequest request;
   MqlTradeResult result;
//---- Объявление структуры результата проверки торгового запроса
   MqlTradeCheckResult check;
//---- обнуление структур
   ZeroMemory(request);
   ZeroMemory(result);
   ZeroMemory(check);
//---- Инициализация структуры торгового запроса MqlTradeRequest для удаления отложенного ордера
   request.action=TRADE_ACTION_REMOVE;
   request.deviation=deviation;
   request.order=ticket;
//----
   string comment="";
   string ordertype=EnumToString(ENUM_ORDER_TYPE(OrderGetInteger(ORDER_TYPE)));
   StringConcatenate(comment,"<<< ============ ",__FUNCTION__,"(): Удаляем отложенный ",ordertype," ордер по ",symbol," с тикетом ",string(ticket)," ============ >>>");
   Print(comment);
//---- Отправка приказа на закрывание позиции на торговый сервер
   if(!OrderSend(request,result) || result.retcode!=TRADE_RETCODE_DONE)
     {
      Print(__FUNCTION__,"(): Невозможно удалить ",ordertype," ордер с тикетом ",string(ticket),"!");
      Print(__FUNCTION__,"(): OrderSend(): ",m_trade.ResultComment());
      return(false);
     }
   else
      if(result.retcode==TRADE_RETCODE_DONE)
        {
         Signal=false;
         comment="";
         StringConcatenate(comment,"<<< ============ ",__FUNCTION__,"(): Отложенный ",ordertype," ордер по ",symbol," с тикетом ",string(ticket)," удалён ============ >>>");
         Print(comment);
         PlaySound("ok.wav");
        }
      else
        {
         Print(__FUNCTION__,"(): Невозможно удалить ",ordertype," ордер с тикетом ",string(ticket),"!");
         Print(__FUNCTION__,"(): OrderSend(): ",m_trade.ResultComment());
         return(false);
        }
//----
   return(true);
  }
//+------------------------------------------------------------------+
 
SanAlex:

вот скрипт удаляет все отложенные ордера 

Для MQL4 правильнее будет
   switch(OrderType())
   {
      case ORDER_TYPE_BUY_LIMIT:
      case ORDER_TYPE_BUY_STOP:
      case ORDER_TYPE_SELL_LIMIT:
      case ORDER_TYPE_SELL_STOP:
         // что-то делаем
         break;
   }

Для MQL5 немного отличается.

   switch((int)OrderGetInteger(ORDER_TYPE))
   {
      case ORDER_TYPE_BUY_LIMIT:
      case ORDER_TYPE_BUY_STOP:
      case ORDER_TYPE_BUY_STOP_LIMIT:
      case ORDER_TYPE_SELL_LIMIT:
      case ORDER_TYPE_SELL_STOP:
      case ORDER_TYPE_SELL_STOP_LIMIT:
         // что-то делаем
         break;
   }
Причина обращения: