Скачать MetaTrader 5

CloseAllOrders()

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
kernel
334
kernel  

Подскажите как реализовать эту функцию из четверки

void CloseAllOrders()
{
   for(int cnt=OrdersTotal()-1;cnt>=0;cnt--)
   {
      if( !OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES) )
      {
         Print("OrderSelect() failed");
         continue;
      }
      if( OrderSymbol()==Symbol() )
      {
         if(OrderType()==OP_SELL )
         {
            if( ClosePosBySelect() )
               Print("CLosing order FAILED, Error = ", ErrorDescription(GetLastError()));
         }else if(OrderType()==OP_BUY )
         {
            if( ClosePosBySelect() )
               Print("CLosing order FAILED, Error = ", ErrorDescription(GetLastError()));
         }
      }
   }
}

Я сделал так, но что-то не работает...

void CloseAllOrders()
{
   MqlTick last_tick;
   SymbolInfoTick(_Symbol,last_tick);
   HistorySelect(0,TimeCurrent());
   uint total=OrdersTotal();
   int ticket;
   Print(__FUNCTION__,": ", "Total orders: ", total);
   for(uint i=0;i<total;i++)
   {
      if(ticket=OrderGetTicket(i))
      {
         if( OrderSelect(ticket) )
         {
            long type = OrderGetInteger(ORDER_TYPE);
            Print(__FUNCTION__,": ", "CLOSING ORDER: ", ticket);
            MqlTradeResult result;
            MqlTradeRequest request;
            request.order = ticket;
            request.action = TRADE_ACTION_DEAL;
            request.symbol = Symbol();
            request.volume = 0.1;
            if( type == ORDER_TYPE_BUY)
            {
               request.type = ORDER_TYPE_SELL;
               request.price = last_tick.bid;
            }else if( type == ORDER_TYPE_SELL)
            {
               request.type = ORDER_TYPE_BUY;
               request.price = last_tick.ask;
            }
            request.type_filling=ORDER_FILLING_AON;
            request.deviation = 100;
            OrderSend(request, result);
            Print(__FUNCTION__,": ",result.comment,"код ответа ",result.retcode);
         }else
         {
            Print(__FUNCTION__,": OrderSelect failed !!!");
         }
      }else
      {
         Print(__FUNCTION__,": OrderGetTicket failed !!!");
      }
   }
}
StrikeR
88
StrikeR  

#include <Trade\Trade.mqh>

protected:
   CTrade            m_trade;                      // trading object


ulong ticket;

int o=OrdersTotal();
for(int i=-1;i<o;i++)
 {
    if(ticket=OrderGetTicket(i)) m_trade.OrderDelete(ticket);
 }
Валерий
1433
Валерий  

Насколько я понимаю, Вы хотите закрыть все открытые позиции, а пытаетесь закрывать ордера. Ордер - заявка на совершение сделки, при исполнении порождает сделку, сделка, в свою очередь, открывает, изменяет или закрывает позицию по инструменту. Работайте с позициями. Проще использовать класс CTrade (Trade.mqh) стандартной библиотеки.
Prival
4596
Prival  
Valmars:

Насколько я понимаю, Вы хотите закрыть все открытые позиции, а пытаетесь закрывать ордера. Ордер - заявка на совершение сделки, при исполнении порождает сделку, сделка, в свою очередь, открывает, изменяет или закрывает позицию по инструменту. Работайте с позициями. Проще использовать класс CTrade (Trade.mqh) стандартной библиотеки.

вот так правильно ?

 void CloseAllPosition()
  {
    CTrade  m_trade;    //trading object
    string  sy;
    int all=PositionsTotal();
    for(int i=all-1; i>=0;i--)  {
      sy=PositionGetSymbol(i);
      m_trade.PositionClose(sy,-1);
      //Print("i=",i," all=",all," ",sy," ",_LastError);
    }
  }

 в #include <Trade\Trade.mqh>

есть строка  

  m_request.deviation =(deviation==ULONG_MAX) ? m_deviation : deviation;

 Что она означает ? 

Ilyas
1205
Ilyas  
Prival :

 в #include <Trade\Trade.mqh>

есть строка  

  m_request.deviation =(deviation==ULONG_MAX) ? m_deviation : deviation;

 Что она означает ? 

if(deviation==ULONG_MAX)
   m_request.deviation=m_deviation;
else
   m_request.deviation=deviation;

Rashid Umarov
Админ
12400
Rashid Umarov  
Prival :

  m_request.deviation =(deviation==ULONG_MAX) ? m_deviation : deviation;

 Что она означает ? 

Установка допустимого проскальзывания (Slippage) при исполнение ордера. (Если вопрос не о синтаксисе).
Валерий
1433
Валерий  

Тут, наверное, вводит в недоумение использование константы ULONG_MAX в качестве признака отсутствия параметра deviation в функции PositionClose(const string symbol,ulong deviation=ULONG_MAX).

С таким же успехом можно было вместо ULONG_MAX использовать -1, как мы привыкли в MQL4, заодно бы проверили на неотрицательность заданную deviation:

m_request.deviation =(deviation<0) ? m_deviation : deviation;

Но тут интересно другое: при закрытии позиции мы можем как явно задать проскальзывание, так и использовать значение по-умолчанию, а вот при открытии - только значение по-умолчанию.

Если учесть, что при создании объекта CTrade m_deviation устанавливается в 10, то при 5-значных котировках этого явно недостаточно, и нам необходимо принудительно устанавливать m_deviation

в нужное значение с помощью метода  SetDeviationInPoints(ulong deviation), прежде,чем открывать позицию.

Можно, конечно, внести свои исправления, но библиотека-то стандартная, и нужно чтобы не было разночтений в трактовании терминов.                      


Prival
4596
Prival  
Rosh:
Установка допустимого проскальзывания (Slippage) при исполнение ордера. (Если вопрос не о синтаксисе).

Вопросов очень много(и о синтаксисе тоже), ответ нигде не могу найти. Метод тыка не помогает.  Нужны знания разработчиков.

Раньше (Slippage) максимальный был равен 10 пунктам (если я не ошибаюсь) больше не было смысла задавать. Теперь как ?

То что я записал -1 вот тут

      if(sy!="") m_trade.PositionClose(sy,-1);

Это правильно ? Цель закрыть по любой цене, как можно быстрее, с любым проскальзыванием.

Раньше в советниках я использовал разработки (KimIV,  http://www.kimiv.ru) очень хочу перевести их на MQL5 но не хватает знаний. Если с этими структурами и классами у меня еще есть надежда разобраться (очень жду статьи), то вот с обработкой ошибок... 

Вот 2 функции. Очень нужен их аналог на MQL5. Без знания разработчиков их не написать. Нужно уметь получать результаты торговой операции и корректно их обрабатывать

//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия  : 19.02.2008                                                      |
//|  Описание: Закрытие одной предварительно выбранной позиции                 |
//+----------------------------------------------------------------------------+
void ClosePosBySelect() {
  bool   fc;
  color  clClose;
  double ll, pa, pb, pp;
  int    err, it;

  if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
    for (it=1; it<=NumberOfTry; it++) {
      if (!IsTesting() && (!IsExpertEnabled() || IsStopped())) break;
      while (!IsTradeAllowed()) Sleep(5000);
      RefreshRates();
      pa=MarketInfo(OrderSymbol(), MODE_ASK);
      pb=MarketInfo(OrderSymbol(), MODE_BID);
      if (OrderType()==OP_BUY) {
        pp=pb; clClose=clCloseBuy;
      } else {
        pp=pa; clClose=clCloseSell;
      }
      ll=OrderLots();
      fc=OrderClose(OrderTicket(), ll, pp, Slippage, clClose);
      if (fc) {
        if (UseSound) PlaySound(NameFileSound); break;
      } else {
        err=GetLastError();
        if (err==146) while (IsTradeContextBusy()) Sleep(1000*11);
        Print("Error(",err,") Close ",GetNameOP(OrderType())," ",ErrorDescription(err),", try ",it);
        Print(OrderTicket(),"  Ask=",pa,"  Bid=",pb,"  pp=",pp);
        Print("sy=",OrderSymbol(),"  ll=",ll,"  sl=",OrderStopLoss(),
              "  tp=",OrderTakeProfit(),"  mn=",OrderMagicNumber());
        Sleep(1000*5);
      }
    }
  } else Print("Некорректная торговая операция. Close ",GetNameOP(OrderType()));
}

и  вторая

//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 21.03.2008                                                     |
//|  Описание : Открывает позицию и возвращает её тикет.                       |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента   (NULL или "" - текущий символ)          |
//|    op - операция                                                           |
//|    ll - лот                                                                |
//|    sl - уровень стоп                                                       |
//|    tp - уровень тейк                                                       |
//|    mn - MagicNumber                                                        |
//+----------------------------------------------------------------------------+
int OpenPosition(string sy, int op, double ll, double Sl=0, double Tp=0, int mn=0) {
  color    clOpen;
  datetime ot;
  double   pa, pb, po, price, sl, tp, min_sl;
  int      dg, err, it, ticket=0, mult;
  string   lsComm=WindowExpertName()+" "+GetNameTF(Period());

  if (sy=="" || sy=="0") sy=Symbol();
  if (op==OP_BUY) clOpen=clOpenBuy; else clOpen=clOpenSell;
  for (it=1; it<=NumberOfTry; it++) {
    if (!IsTesting() && (!IsExpertEnabled() || IsStopped())) {
      Print("OpenPosition(): Остановка работы функции");
      break;
    }
    while (!IsTradeAllowed()) Sleep(5000);
    RefreshRates();
    dg=MarketInfo(sy, MODE_DIGITS);
    pa=MarketInfo(sy, MODE_ASK);
    pb=MarketInfo(sy, MODE_BID);
    po=MarketInfo(sy, MODE_POINT);
    min_sl=MarketInfo(sy,MODE_STOPLEVEL);
//    Print("Минимальный Sl-----",min_sl);
// ----- расчет лота и проверка минимума средств 
    if(!IsTesting() && ll!=0.1) ll=CalculateVolume();
    if(ll<MarketInfo(sy,MODE_MINLOT)) break;
    if (op==OP_BUY) {
           price = pa;
           mult = 1;
    }
    else {
                price = pb;
                mult = -1;
    }
    // расчет sl и tp
    if(Sl!=0)  {
      if(Sl>min_sl) sl = price - mult*Sl*Point;
      else
      sl = price - mult*min_sl*Point;
    }
    if(Tp!=0) tp = price + mult*Tp*Point;
    
    price=NormalizeDouble(price, dg);
    sl   =NormalizeDouble(sl   , dg);
    tp   =NormalizeDouble(tp   , dg);
    ot=TimeCurrent();
    ticket=OrderSend(sy, op, ll, price, Slippage, sl, tp, lsComm, mn, 0, clOpen);
    if (ticket>0) {
      if (UseSound) PlaySound(NameFileSound); break;
    } else {
      err=GetLastError();
      if (pa==0 && pb==0) Message("Проверьте в Обзоре рынка наличие символа "+sy);
      // Вывод сообщения об ошибке
      Print("Error(",err,") opening position: ",ErrorDescription(err),", try ",it);
      Print("Ask=",pa," Bid=",pb," sy=",sy," ll=",ll," op=",GetNameOP(op),
            " price=",price," sl=",sl," tp=",tp," mn=",mn);
      // Блокировка работы советника
      if (err==2 || err==64 || err==65 || err==133) {
        gbDisabled=True; break;
      }
      // Длительная пауза
      if (err==4 || err==131 || err==132) {
        Sleep(1000*300); break;
      }
      if (err==128 || err==142 || err==143) {
        Sleep(1000*66.666);
        if (ExistPositions(sy, op, mn, ot)) {
          if (UseSound) PlaySound(NameFileSound); break;
        }
      }
      if (err==140 || err==148 || err==4110 || err==4111) break;
      if (err==141) Sleep(1000*100);
      if (err==145) Sleep(1000*17);
      if (err==146) while (IsTradeContextBusy()) Sleep(1000*11);
      if (err!=135) Sleep(1000*7.7);
    }
  }
  return(ticket);
}

 Заранее спасибо.

З.Ы. Да и еще одно. Я понимаю, что тут многие «англичане», но хотелось бы получать сообщения терминала и на родном русском языке.

 

Vladislav Andruschenko
101537
Vladislav Andruschenko  

Я это реализовал так:




void CloseAllPosSell()
  {
   int pos=PositionsTotal(); // получим количество открытых позиций
   for(int ip=0;ip<=pos;ip++)
     {
      string sSymbol=PositionGetSymbol(ip);
      if(PositionSelect(sSymbol)==true)
         CloseAllPosSellF(sSymbol,ip);
     
     }

 
  }

void CloseAllPosSellF(string sSymbol,int ip)
  {
   MqlTradeRequest request; // структура запроса
   MqlTradeResult result; // структура ответа



   request.symbol = sSymbol;
   request.volume = PositionGetDouble( POSITION_VOLUME );
   request.action=TRADE_ACTION_DEAL; // операция с рынка
   request.tp=0;
   request.sl=0;
   request.deviation=(ulong) ((SymbolInfoDouble(sSymbol,SYMBOL_ASK)-SymbolInfoDouble(sSymbol,SYMBOL_BID))/SymbolInfoDouble(sSymbol,SYMBOL_POINT)) ; // по спреду
   request.type_filling=ORDER_FILLING_CANCEL;

   if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
     {
      request.type=ORDER_TYPE_SELL;
      request.price=SymbolInfoDouble(sSymbol,SYMBOL_BID);
     }
   if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
     {
      request.type=ORDER_TYPE_BUY;
      request.price=SymbolInfoDouble(sSymbol,SYMBOL_ASK);
     }
    
  if (PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL){ OrderSend(request,result);}
 

  }

 

Валерий
1433
Валерий  
Prival:

То что я записал -1 вот тут

Это правильно ? Цель закрыть по любой цене, как можно быстрее, с любым проскальзыванием.


Это, конечно, неправильно. Так как deviation в методе PositionClose(const string symbol,ulong deviation=ULONG_MAX) класса Ctrade имеет тип  ulong, она не может быть отрицательной. Что произойдёт, если Вы поставите  deviation в -1? Значение по-умолчанию не будет установлено, так как ULONG_MAX не равно -1. Как будет воспринята -1 типом ulong ? Простой скрипт показывает, что -1 для ulong = 18446744073709551615. Скорее всего, такое значение slippage будет проигнорировано сервером. Думаю, надо устанавливать большие, но всё же в разумных пределах, значения  deviation, чтобы закрыть с любым проскальзыванием.
Валерий
1433
Валерий  
Vladon:

Я это реализовал так:




void CloseAllPosSell()
  {
   int pos=PositionsTotal(); // получим количество открытых позиций

   for(int ip=0;ip<=pos;ip++)

   {

   ...

     
   }

 
  }

...
  if (PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL){ OrderSend(request,result);}
 

  }

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

  
for(int ip=pos-1;ip>=0;ip--)
     {

так как после закрытия очередной, список позиций и PositionsTotal() корректируются и закрыть удастся только половину позиций.

Последняя строчка вообще непонятна, OrderSend(...) и для buy и для sell должен быть.


123
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий