Закрытие встречных ордеров. Нужна ваша помощь!

 

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

Логика такая:

Сначала советник определяет общую прибыль по всем открытым ордерам:

//Определяем общую прибыль по всем открытым ордерам
       Total=OrdersTotal()-1;
       for (int f=Total+1;f>=0;f--)
       {
       OrderSelect(f,SELECT_BY_POS,MODE_TRADES);
       if(OrderType()==OP_SELL)
       {
       Sell_Profit=OrderProfit();
       }
       if(OrderType()==OP_BUY)
       {
       Buy_Profit=OrderProfit();
       }
       double Total_Profit=Buy_Profit+Sell_Profit;
       Total_Orders++;
       Sell_Profit=0;
       Buy_Profit=0;
       }

Если заданный объем прибыли достигнут, советник начинает перебирать все ордера и выбирает наибольшие встречные ордера:

//При достижении требуемого размера прибыли закрываем все открытые и отложенные ордера
       if(Total_Profit<0&&Total>=2)
       {
       while(OrdersTotal()>0)
       {
       int Total2=OrdersTotal()-1;
       for (int l=Total2+1;l>=0;l--)
       {
       OrderSelect(l,SELECT_BY_POS,MODE_TRADES);
//Определяем ордер SELL c наибольшим лотом
       if(OrderType()==OP_SELL)
       {
       SELL_Remains++;
       if (Max_Lot_SELL<OrderLots());
       Max_Lot_SELL=OrderLots();
       int Ticket_SELL=OrderTicket();
       }
//Определяем ордер BUY c наибольшим лотом
       if(OrderType()==OP_BUY)
       {
       BUY_Remains++;
       if (Max_Lot_BUY<OrderLots());
       Max_Lot_BUY=OrderLots();
       int Ticket_BUY=OrderTicket();
       }
//Определяем номер (Ticket) отложенного ордера
       if(OrderType()==OP_SELLSTOP||OrderType()==OP_BUYSTOP)
       {
       int TICKET=OrderTicket();
       }
       }
      

После того как определили наибольшие по объему ордера BUY и SELL взаимно из закрываем. Так же закрываем оставшиеся ордера (если встречных нет) и удаляем отложенный ордер:


       if(Max_Lot_SELL>0&&Max_Lot_BUY>0&&Max_Lot_SELL>Max_Lot_BUY)
       {
       bool Close_BY1=OrderCloseBy(Ticket_SELL,Ticket_BUY);
       Max_Lot_SELL=0;
       Max_Lot_BUY=0; 
       }
       if(Max_Lot_SELL>0&&Max_Lot_BUY>0&&Max_Lot_SELL<Max_Lot_BUY)
       {
       bool Close_BY=OrderCloseBy(Ticket_BUY,Ticket_SELL);
       Max_Lot_SELL=0;
       Max_Lot_BUY=0;
       }
       if(Close_BY1==false&&Close_BY==false)
       {
       Close_BUYSTOP_SELLSTOP=OrderDelete(TICKET,Yellow);
       bool Close_SELL=OrderClose(OrderTicket(),OrderLots(),Ask,0,Yellow);
       bool Close_BUY=OrderClose(OrderTicket(),OrderLots(),Bid,0,Yellow);
       }
       }
       }

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

Не могу в толк взять как работает один цикл (for) в другом (while).

Помогите пож-та разобраться, что не так в коде.

 

void OnTick()   { //---
   double profit=100.00;
   bool res;    if(AccountInfoDouble(ACCOUNT_PROFIT)>=profit)//Определяем общую прибыль по всем открытым ордерам
     {
      for(int i=OrdersTotal()-1;i>=0;i--)
        {
         if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
           {
            if(OrderType()>1) res=OrderDelete(OrderTicket(),clrAqua);
            else res=OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),clrGreen);//При достижении требуемого размера прибыли закрываем все открытые и отложенные ордера
           }
        }
     }
  }


В данном случае ордера закрываются через OrderClose. А как это сделать через OrderCloseBy. Причем так, чтобы ордера взаимно закрывались в порядке уменьшения их объемов.

 
LEV5:

В данном случае ордера закрываются через OrderClose. А как это сделать через OrderCloseBy. Причем так, чтобы ордера взаимно закрывались в порядке уменьшения их объемов.

сортируйте по OrderLots()

 потом закрывайте по  OrderCloseBy

 

В таком случае, пройдет полный цикл, советник отберет два ордера SELL и BUY (наибольшие по объему) и взаимно их закроет.

но еще останутся другие ордера. как с ними быть? как запустить цикл заново?

 

еще один вопрос (больше по теории). Если я понимаю, нельзя при открытии одного цикла в другом задавать для них одинаковые условия?

например:

for (int i=0;i<OrdersTotal;i++)

  {

   ......

       for (int a=0;a<OrdersTotal;a++)

         {

         .......

         }

}

 
LEV5:

В таком случае, пройдет полный цикл, советник отберет два ордера SELL и BUY (наибольшие по объему) и взаимно их закроет.

но еще останутся другие ордера. как с ними быть? как запустить цикл заново?

А массивы не устраивают. Хранить номера тикетов отсортированные по размеру позиций
 
LEV5:

В таком случае, пройдет полный цикл, советник отберет два ордера SELL и BUY (наибольшие по объему) и взаимно их закроет.

но еще останутся другие ордера. как с ними быть? как запустить цикл заново?

Хороший вам совет:

Сначала представьте, потом распишите "на бумажке" алгоритм, как бы вы сами всё это проделали, не с программным кодом, а с, например, яблоками - с нормальными и с подгнившими... А уже потом, сверяясь с алгоритмом, писали бы код.

Ну или - с самыми большими, и с самыми маленькими вплоть, пока не останутся два самых больших, или одно - самое большое.

Наверное начали бы их раскладывать по двум кучкам, постепенно убирая из кучек самые крайние по размеру. Да?

 
Здесь есть функция fClose_AllOrdersBy(), выполняющая закрытие всех рыночных ордеров, начиная со встречных. Суть варианта реализации уловить не сложно.
 

Прописывал по-разному. Не удается настроить выборку для любого количества открытых ордеров.

требуются услуги специалиста по доработке советника.

готов обсудить условия. или пож-та подскажите к кому можно обратиться.

 
artmedia70:

Хороший вам совет:

Сначала представьте, потом распишите "на бумажке" алгоритм, как бы вы сами всё это проделали, не с программным кодом, а с, например, яблоками - с нормальными и с подгнившими... А уже потом, сверяясь с алгоритмом, писали бы код.

Ну или - с самыми большими, и с самыми маленькими вплоть, пока не останутся два самых больших, или одно - самое большое.

Наверное начали бы их раскладывать по двум кучкам, постепенно убирая из кучек самые крайние по размеру. Да?

В советник заложена другая логика:

Одна большая (или не очень) кучка яблок: Зеленые (BUY) и красные (SELL).

Сначала перебираю все перебираю все зеленые яблоки и выбираю самое крупное потом тоже самое красные.

убрал эти яблоки из кучи, потом заново перебираю.

Как мне кажется такая логика тоже верна. Только не могу ее прописать.

 
LEV5:

В советник заложена другая логика:

Одна большая (или не очень) кучка яблок: Зеленые (BUY) и красные (SELL).

Сначала перебираю все перебираю все зеленые яблоки и выбираю самое крупное потом тоже самое красные.

убрал эти яблоки из кучи, потом заново перебираю.

Как мне кажется такая логика тоже верна. Только не могу ее прописать.

Какая разница, как Вы будете ковыряться в Вашей куче? Эквити от  этого не пострадает. Вот, если тока задумаетесь, тогда свопов нахватаетесь.