Помогите новичку. ( Закрытие всех ордеров)

 
void OnTick()
 { 
  if(isNewBar(1,0) && ExistOrders())
   {
     DeleteOrders();
   }
 }

//===============================================================================================
//------------------------- Возвращает флаг существования ордеров ------------------------------+
//===============================================================================================
bool ExistOrders(string sy="", int op=-1, int mn=-1, datetime ot=0) {
 if(sy=="") sy=Symbol();
  for(int i=0; i<OrdersTotal(); i++) {
   if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
    if((OrderSymbol()==sy || sy=="") && (op<0 || OrderType()==op)) {
     if(OrderType()>1 && OrderType()<6) {
      if(mn<0 || OrderMagicNumber()==mn) {
       if(ot<OrderOpenTime()) return(true);
 }}}}}
  return(false);
 }
//===============================================================================================
//------------------------------------- Удаление ордеров ---------------------------------------+
//===============================================================================================
void DeleteOrders(string sy="", int op=-1, int mn=-1, color cl=clrOliveDrab) {
  bool fd=false;
  int ot, err=-1;
  if(sy=="") sy=Symbol();
  for(int i=OrdersTotal()-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 it=1; it<=3; it++) {
        if(!IsTesting() && (!IsExpertEnabled() || IsStopped())) break;
          while(!IsTradeAllowed()) Sleep(5000);
           fd=OrderDelete(OrderTicket(), cl);
        if(fd) { PlaySound("ok.wav"); break;
        } else { PlaySound("timeout.wav"); }
    Sleep(1000*5);
 }}}}}}}}
//===============================================================================================
//----------------------------------- Функция "Новый бар" --------------------------------------+
// при первом запуске возвращает: md: 0-true, 1-ожидает следующий бар                           |
//===============================================================================================
bool isNewBar(int md=1,int prd=0) {
 static datetime tm[10];
 int ft=tfA(prd);
 if(tm[ft]==0 && md==1) { tm[ft]=iTime(Symbol(),prd,0);}
 if(tm[ft]==iTime(Symbol(),prd,0)) { return(false);}
  tm[ft]=iTime(Symbol(),prd,0);
 return(true);
 }
 int tfA(int tf) {
  switch(tf){
   case PERIOD_M1: return (0);
   case PERIOD_M5: return(1);
   case PERIOD_M15: return(2);
   case PERIOD_M30: return(3);
   case PERIOD_H1: return(4);
   case PERIOD_H4: return(5);
   case PERIOD_D1: return(6);
   case PERIOD_W1: return(7);
   case PERIOD_MN1: return(8);
   default: return(9);}
 }
 
Vitaly Muzichenko:
Спасибо большое! Только советник перестал вообще сделки открывать. Может есть код попроще)
 
Arseniy Suharev:
Спасибо большое! Только советник перестал вообще сделки открывать. Может есть код попроще)

Это простой код.

Все функции копируете ниже фунткции  OnTick()/start()

В функцию OnTick()/start() в самом низу только это: 

 

void OnTick()
 { 
  ...
   Здесь основной ваш код
  ...
  if(isNewBar(1,0) && ExistOrders())  { DeleteOrders(); }
 }
 
Vitaly Muzichenko:

Это простой код.

Все функции копируете ниже фунткции  OnTick()/start()

В функцию OnTick()/start() в самом низу только это: 

 

Только теперь ордера выставляются и сразу закрываются , не дожидаясь нового бара
 
Arseniy Suharev:
Только теперь ордера выставляются и сразу закрываются , не дожидаясь нового бара

Функции работают как "часы".

Вы наверное их устанавливаете на новом баре

Тогда это в самый верх

void OnTick()
 { 
  if(isNewBar(1,0) && ExistOrders())  { DeleteOrders(); }
  ...
   Здесь основной ваш код
  ...
 }
 
Точно! Даже не думал, что от перестановки так все меняется. Спасибо!
 
Arseniy Suharev:
Точно! Даже не думал, что от перестановки так все меняется. Спасибо!

Тут всё дело в правильности логической части выполнения действий.

Если производим какое-то действие, то его нужно делать в правильной последовательности.

Ведь если мы хотим установить ордер, то сначала нужно смотреть - а нужен ли он нам? Если нужен, то делаем расчёт в каком месте. Если нужен сейчас, тогда считаем уровни и устанавливаем.

Потому как логически не верно сначала посчитать все уровни, определить место установки и перед самой установкой выяснить, что ордер нам не нужен - достигнут лимит на количество.

Так-же и с сопровождением и удалением,  нужно сначала что-то получить, чтоб что-то потратить, даже есть пословица "Давайте не будем делить шкуру неубитого медведя"

Нужно всё делать по "цепочке". 

 
https://www.mql5.com/ru/code/14161
Close_all-e
Close_all-e
  • голосов: 10
  • 2015.11.09
  • Vasyl Nosal
  • www.mql5.com
Скрипт, закрывающий ордера и (или) удаляющий отложенные ордера.
 
Arseniy Suharev:
Спасибо большое! Только советник перестал вообще сделки открывать. Может есть код попроще)

Поскольку необязательно то, что приведено или будет приведено в вашей ветке, может оказаться лично для вас удобным/понятным/полезным, то порекомендую следующее:

Если что-то неясно для себя, то Учебник от Ковалёва может помогать разобраться в чём-либо, несмотря на то, что язык программирования MQL4 изменился. В т.ч., поскольку там есть простые наглядные примеры и описания.

Т.е., сочетание знакомства с ДокументациейУчебником и функциями других (на форуме или в Code Base) - помощники для разобраться и конструировать свои коды с учётом своих индивидуальных потребностей и задач (создавать что-то своё следствием).


Например, в коде выше здесь, что привёл Vitaly Muzichenko - это применены функции от Игоря Кима.

Так функцию DeleteOrders(...), в авторском исполнении, можно посмотреть здесь, здесь или на сайте Игоря Кима, к примеру. Так же, как и ExistOrders(...).

Т.е., есть две большие ветки с функциями от Игоря:

Добавлю ремаркой, что те же схемы функций от Игоря Ким, полагаю, многим помогли разобраться для себя в каких-то вопросах, несмотря, например, на то, что в чём-то могут не подходить (язык MQL4 изменился со времени их публикации, компилятор мог стать строже в чём-то, и т.д). А программы Игоря Ким (KimIV) и сейчас переиздаются в Code Base другими (с указанием, конечно, реального автора - KimIV).


P./S.: Указывают источник и те, кто приводит/применяет где-либо функции Игоря Ким, их модификации (уважая чужой труд; в благодарность за то, что это самим было полезно). Как-то так.

 

Здравствуйте. У меня возникла немного другая проблема, но также при закрытии ордеров. 

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

void OrderCloseSumProfit() //закрываем ордера по достижению необходимого суммарного профита
  {
   double _sum=0.0; //сумма профитов
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS)==false)
        {
         Print("Ордер не выбран (OrderCloseSumProfit)");
         continue;
        }
      if(OrderSymbol()!=symbol || OrderMagicNumber()!=magic) continue;
      _sum=_sum+OrderProfit()+OrderSwap()+OrderCommission();
     }
   if(_sum<SumProfit) return;
   OrderStopDelete(); //закрывает стоп ордера
   for(int i=OrdersTotal()-1; i>=0; i--) //цикл закрытия ордеров
     {
      if(OrderSelect(i,SELECT_BY_POS)==false)
        {
         Print("Ордер не выбран (OrderCloseSumProfit-2)");
         continue;
        }
      if(OrderSymbol()!=symbol || OrderMagicNumber()!=magic) continue;
      if(OrderType()==OP_BUY)
        {
         bool _close=OrderClose_f(OrderTicket(),OrderLots(),Bid,slippage,clrNONE);
        }
      if(OrderType()==OP_SELL)
        {
         bool _close=OrderClose_f(OrderTicket(),OrderLots(),Ask,slippage,clrNONE);
        }
     }
  }

 Кроме этой функции нигде в советнике не вызывается функция закрытия ордеров OrderClose_f, а вот собственно и она:

bool  OrderClose_f(int ticket,double lots,double price,int _slippage,color arrow_color)
  {
   bool close=false;
   for(int i=10; i>0; i--)
     {
      close=OrderClose(ticket,lots,price,_slippage,arrow_color);
      if(close==true) return(close);
      else
        {
         int error=GetLastError();
         switch(error)
           {
            case 135: Print("Цена изменилась. Пробуем ещё раз..");
            RefreshRates();                     // Обновим данные
            continue;                           // На след. итерацию
            case 136: Print("Нет цен. Ждём новый тик..");
            Sleep(500);                        // Задержка в цикле
            continue;                           // На след. итерацию
            case 146: Print("Подсистема торговли занята. Пробуем ещё..");
            Sleep(500);                         // Простое решение
            RefreshRates();                     // Обновим данные
            continue;                           // На след. итерацию
            case  2 : Print("Общая ошибка.");
            break;
            case  5 : Print("Старая версия клиентского терминала.");
            break;                              // Выход из switch
            case  64: Print("Счет заблокирован.");
            break;                              // Выход из switch
            case  133:Print("Торговля запрещена");
            break;
            case 4109:Print("Скрипту запрещено совершать торговые операции, разрешите торговлю в терминале");// Выход из switch
            break;
            default:  Print("Возникла ошибка ",error);// Другие варианты   
           }
        }
     }
   return(close);
  }

 Проблема в том, что периодически советник закрывает только один последний ордер, а остальные остаются в рынке. Заказчик при этом использует виртуальный сервер, демо счета, и несколько различных брокеров, если подобная проблема возникает, то единовременно у всех брокеров. А вот в ТЕСТЕРЕ СТРАТЕГИЙ советник работает как часы. 

 Когда ордера не закрываются то советник ПИШЕТ ОШИБКУ 4109. Кто сталкивался с подобной проблемой помогите пожалуйста...