Не получается удалить старые отложенные ордера

 
int start()
  {
  bool   open_b=false,
         open_s=false,
         close_b=false,
         close_s=false;
  string Symb=Symbol();         
  int    Ticket,Tip;
  double price,sl,tp,sign0,sign1,
         stop=200,
         take=300;


//-------- Учет ордеров-----------//

  for(int i=1; i<=OrdersTotal(); i++)
   {
    if(OrderSelect(i-1,SELECT_BY_POS)==true)
      {
         if(Symbol()!=Symb)continue;
         
         Tip=OrderType();
         if(Tip>1)
            {
             Ticket=OrderTicket();
            }
      }
   }
   
 //--------Критерии открытия ордеров-----------//
   
  sign0=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,0);
  sign1=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,1);

  if(sign1 > 0 && sign0 <= 0) 
   {
    close_s=true;
    open_s=true;
   }

   if(sign1 < 0 && sign0 >= 0) 
   {
    close_b=true;
    open_b=true;
   }


//--------Закрываем старые отложенные ордера -----------//

  while(true)    
   {
      if(Tip==2 && close_b==true)
         {
          OrderDelete(Ticket);
          return;
         }
      if(Tip==3 && close_s==true)
         {
          OrderDelete(Ticket);
          return;
         }
     break;
   }

//--------Установка отложенных ордеров -----------//

   while(true)    
      {
         if(open_s==true)
          {
            price=High[iHighest(NULL,0,MODE_HIGH,20,0)];
            sl=price+stop*Point;
            tp=price-take*Point;
            OrderSend(Symbol(),OP_SELLLIMIT,1,price,0,sl,tp);
          }
         if(open_b==true)
          {
            price=Low[iLowest(NULL,0,MODE_HIGH,20,0)];
            sl=price-stop*Point;
            tp=price+take*Point;
            OrderSend(Symbol(),OP_BUYLIMIT,1,price,0,sl,tp);
          }
          
         break;
      }

   return(0);
  }

Код представил выше. Цель такова: Подходит моя позиция, устанавливаю отложенный ордер (BuyLimit или SellLimit).

Предположим установлен BuyLimit. Как только позиция на открытие BuyLimit подходит во второй раз, а мой отложник еще не сработал, его нужно удалить и поставить новый. Аналогично с SellLimit.

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

if(sign1 > 0 && sign0 <= 0) 
   {
    close_s=true;
    open_s=true;
   }

   if(sign1 < 0 && sign0 >= 0) 
   {
    close_b=true;
    open_b=true;
   }
 

kilnart:

Код представил выше. Цель такова: Подходит моя позиция, устанавливаю отложенный ордер (BuyLimit или SellLimit).

Предположим установлен BuyLimit. Как только позиция на открытие BuyLimit подходит во второй раз, а мой отложник еще не сработал, его нужно удалить и поставить новый. Аналогично с SellLimit.

Здесь ошибка:

//-------- Учет ордеров-----------//

  for(int i=1; i<=OrdersTotal(); i++)
   {
    if(OrderSelect(i-1,SELECT_BY_POS)==true)
      {
         if(Symbol()!=Symb)continue;
         
         Tip=OrderType();
         if(Tip>1)
            {
             Ticket=OrderTicket();
            }
      }
   }

Ордера нужно начинать перебирать с 0-го, а заканчивать (OrdersTotal() - 1). А ещё лучше цикл построить таким образом:

 for(int i = OrdersTotal()-1; i >= 0; i--)
 {
   ...
 }

А ещё лучше лучшего и самое удобное (для Меня видится по крайней мере) сигналы считать до цикла, а ордера удалять в самом цикле, а не после него. Но для тестера стратегий с одним ордером в рынке сойдёт и Ваш вариант.


kilnart:

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

А с этим Сами разберётесь. Я как-то MACD не использовал. Ограничиваюсь MA-шками... Ведь MACD - это набор их же. Но визуально просто выглядит куда удобнее.

 
теперь старый ордер удаляет, а новый отложенный не выставляет
 
kilnart:
теперь старый ордер удаляет, а новый отложенный не выставляет

Так вот же в чём причина:

  if(sign1 > 0 && sign0 <= 0) 
   {
    close_b=true;
    open_s=true;
   }

   if(sign1 < 0 && sign0 >= 0) 
   {
    close_s=true;
    open_b=true;
   }

При сигнале на BUY, Вам нужно удалять SELL, а не опять же BUY. Изменил индексы у булевых переменных "close_x".

А цикл for (учёт ордеров) верните какой был. Только учтите, что ордера с индексом OrdersTotal() при переборе функцией OrderSelect() в режиме SELECT_BY_POS нет!! Так как отчёт начинается с 0...

И всё же лучше будет сигнал поставить до for (учёта ордеров) и не запоминать тикет, а сразу удалять отложенные ордера в цикле for перебора ордеров (учёта ордеров). Вдруг у Вас этих тикетов много потом станет?

 

Ещё здесь заметил недочёт:

//--------Установка отложенных ордеров -----------//

   while(true)    
      {
         if(open_s==true)
          {
            price=High[iHighest(NULL,0,MODE_HIGH,20,0)];
            sl=price+stop*Point;
            tp=price-take*Point;
            OrderSend(Symbol(),OP_SELLLIMIT,1,price,0,sl,tp);
          }
         if(open_b==true)
          {
            price=Low[iLowest(NULL,0,MODE_HIGH,20,0)];
            sl=price-stop*Point;
            tp=price+take*Point;
            OrderSend(Symbol(),OP_BUYLIMIT,1,price,0,sl,tp);
          }
          
         break;
      }

Считаю, что логика нарушена. Но может так и нужно! :)))

Цитирую "Документацию":

Константа Значение Описание
MODE_OPEN0Цена открытия
MODE_LOW1Минимальная цена
MODE_HIGH2Максимальная цена
MODE_CLOSE3Цена закрытия
MODE_VOLUME4Объем (количество тиков, сформировавших бар)
MODE_TIME5Время открытия бара
 

нет.

 if(sign1 > 0 && sign0 <= 0) 
   {
    close_s=true;
    open_s=true;
   }

   if(sign1 < 0 && sign0 >= 0) 
   {
    close_b=true;
    open_b=true;
   }

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

теперь я говорю, что нужно закрыть старый ордер (close_s (закрыть старый SellLimit)) и открыть новый (open_s (открыть новый SillLimit))

 
MaxZ:

Ещё здесь заметил недочёт:

Считаю, что логика нарушена. Но может так и нужно! :)))

Цитирую "Документацию":

Константа Значение Описание
MODE_OPEN0Цена открытия
MODE_LOW1Минимальная цена
MODE_HIGH2Максимальная цена
MODE_CLOSE3Цена закрытия
MODE_VOLUME4Объем (количество тиков, сформировавших бар)
MODE_TIME5Время открытия бара


здесь правда напутал. но это не критично
 
kilnart:

нет.

 if(sign1 > 0 && sign0 <= 0) 
   {
    close_s=true;
    open_s=true;
   }

   if(sign1 < 0 && sign0 >= 0) 
   {
    close_b=true;
    open_b=true;
   }

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

теперь я говорю, что нужно закрыть старый ордер (close_s (закрыть старый SellLimit)) и открыть новый (open_s (открыть новый SillLimit))

Аааа... Если так, то Вам точно нужно сигналы ("Критерии открытия орердов") считать до "учёта ордеров", а ордера удалять в цикле for ("учёта ордеров").


Короче разбирайтесь. Составьте блок-схему программы, понаставьте Print'ов, мониторинг переменных сделайте с помощью функции Comment().

Увы, но Люди не идеальны и невнимательностью, спешкой - каждый из Нас страдает! ;))

 
я не могу понять. программе дается команда закрыть старый отложенный ордер и открыть новый в один момент. программа это воспринимает как одну команду сделать или то или это и производит только одно действие. как с этим бороться?
 
MaxZ:

Аааа... Если так, то Вам точно нужно сигналы рассчитывать до "учёта ордеров", а ордера удалять в цикле for ("учёта ордеров").


Короче разбирайтесь. Составьте блок-схему программы, понаставьте Print'ов, мониторинг переменных сделайте с помощью функции Comment().

Увы, но Люди не идеальны и невнимательностью, спешкой - каждый из Нас страдает! ;))



пропробую
 
kilnart:
я не могу понять. программе дается команда закрыть старый отложенный ордер и открыть новый в один момент. программа это воспринимает как одну команду сделать или то или это и производит только одно действие. как с этим бороться?

У Вас отложенных ордера может быть два, а переменная, хранящая OrderType() одна и для OrderTicket() одна... Что Вы хотите? Чтобы функция OrderSelect() на каждом тике случайно перебирала ордера и однажды Вам попался тот ордер, который нужен? :)))

Если не хотите написать более оптимальный код, который можно использовать в других советниках, то заведите две переменных TicketB, TicketS, а от переменной Tip откажитесь, а точнее используйте её только в цикле for ("учёта ордеров")... Всё. Я есть хочу! :)))

Причина обращения: