Помогите разобраться с кодом.

 

Здравствуйте. 

Вот кусок кода:

   if(OrdersTotal() > 0)
   {
      for(int j = 0; j <= OrdersTotal(); j++)
      {
         OrderSelect(j, SELECT_BY_POS, MODE_TRADES);
         
         if(OrderType() == OP_SELL)
         {
            Prise_Sell = OrderOpenPrice();
            Tiket_Sell = OrderTicket();
            
            for(int k = 0; k <= OrdersTotal(); k++)
            {
               OrderSelect(k, SELECT_BY_POS, MODE_TRADES);
               
               if(OrderType() == OP_BUY)
               { 
                  if((Prise_Sell - OrderOpenPrice())*10000 == Step - Spread)
                  {
                     if((Bid - Prise_Sell)*10000 >= Step * 1.5 || (OrderOpenPrice() - Ask)*10000 >=  Step * 1.5)
                     {
                        OrderCloseBy(Tiket_Sell, OrderTicket(), 0);
                     
                        OrderSend(Symbol(),OP_SELLSTOP,Lot,Prise_Sell,4,0,0,0,0,0,CLR_NONE);
                        OrderSend(Symbol(),OP_BUYLIMIT,Lot,OrderOpenPrice(),4,0,0,0,0,0,CLR_NONE);
                        }
                     }
                  }
               }
            }
         }
      }  

 

Перебираем  ордера пока не найдем открытый SELL.

Перебираем еще раз пока не найдем открытый BAY, который будет на (Step - Spread) пунктов ниже ордера SELL.

Если цена в данный момент выше SELL на (Step * 1.5) или ниже BAY на столько же, закрываем эти два ордера OrderCloseBy.

 

Не могу понять почему ордера не закрываются? Где ошибка?

Может быть я как-то не правильно использую стандартные функции? 

 
antoxin_8p:

Здравствуйте. 

Вот кусок кода:

 

Перебираем  ордера пока не найдем открытый SELL.

Перебираем еще раз пока не найдем открытый BAY, который будет на (Step - Spread) пунктов ниже ордера SELL.

Если цена в данный момент выше SELL на (Step * 1.5) или ниже BAY на столько же, закрываем эти два ордера OrderCloseBy.

 

Не могу понять почему ордера не закрываются? Где ошибка?

Может быть я как-то не правильно использую стандартные функции? 

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

Здравствуйте.

OrderCloseBy(Tiket_Sell, OrderTicket(), 0); - разве не закрывает ордера? 

 
antoxin_8p:

Здравствуйте.

OrderCloseBy(Tiket_Sell, OrderTicket(), 0); - разве не закрывает ордера? 

А, да, теперь вижу, привык что цветом код выделяется.
 

Дело в том, что условие if((Prise_Sell - OrderOpenPrice())*10000 == Step - Spread), судя по всему не выполняется.

Хотя, используя  визуализацию и Comment(), вижу что значения совпадают.

 

Строгое

if((Prise_Sell - OrderOpenPrice())*10000 == Step - Spread)

далеко не всегда бывает, лучше

if((Prise_Sell - OrderOpenPrice())*10000 >= Step - Spread)

И вместо умножения на 10000 грамотнее будет делить на Point.

 

Ещё, вместо такой конструкции:

for(int k = 0; k <= OrdersTotal(); k++) //на 1 элемент в цикле больше, чем надо (100=0..99, а не 0..100, это уже 101)

правильнее будет такое:

for(int k = OrdersTotal()-1; k >=0 ; k--) //счёт от самого свежего к самому старому
 

Поменял (*10000) на (/Point)  и создал Tiket_Buy. Разницы нет.

Подскажите пожалуйста, (Bid - Prise_Sell)*Point рассчитывается как double или int? Может сравнение в принципе не правильно?

 
if((Prise_Sell - OrderOpenPrice())*10000 >= Step - Spread) как раз таки и не подходит. Будет закрытие ордеров которые находятся намного ниже Step - Spread, а требуется именно определенного ордера. 
Может быть тогда диапазон?

	          
 

Сделал диапазон if((Prise_Sell - OrderOpenPrice())/Point >= Step - Spread && (Prise_Sell - OrderOpenPrice())/Point <= Step - Spread + 2), и изменил цикл на for(int k = OrdersTotal()-1; k >=0 ; k--).

Ордера теперь закрываются. Огромное спасибо!

Но возникли другие косяки. А именно не всегда в замен закрытых ордеров выставляются новые отложенники :( 

 

Выкладываю весь код, может быть кто-нибудь ткнет носом в ошибки:

 

extern double Lot = 1;
extern int Step = 20;
extern int Spread = 2;

bool AllSymbol = false;
int Magic = 0; 
bool CloseAll()
{
   bool error=true;
   int err,nn,OT;
   string Symb;
   while(true)
   {
      for (int j = OrdersTotal()-1; j >= 0; j--)
      {
         if (OrderSelect(j, SELECT_BY_POS))
         {
            Symb = OrderSymbol();
            if ((Symb == Symbol() || AllSymbol) && (Magic==0 || Magic==OrderMagicNumber()))
            {
               OT = OrderType();
               if (OT>1) 
               {
                  OrderDelete(OrderTicket());
               }
               if (OT==OP_BUY) 
               {
                  error=OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(MarketInfo(Symb,MODE_BID),MarketInfo(Symb,MODE_DIGITS)),3,Blue);
                  if (error) Alert(Symb,"  Закрыт ордер N ",OrderTicket(),"  прибыль ",OrderProfit(),
                                     "     ",TimeToStr(TimeCurrent(),TIME_SECONDS));
               }
               if (OT==OP_SELL) 
               {
                  error=OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(MarketInfo(Symb,MODE_ASK),MarketInfo(Symb,MODE_DIGITS)),3,Red);
                  if (error) Alert(Symb,"  Закрыт ордер N ",OrderTicket(),"  прибыль ",OrderProfit(),
                                     "     ",TimeToStr(TimeCurrent(),TIME_SECONDS));
               }
               if (!error) 
               {
                  err = GetLastError();
                  if (err<2) continue;
                  if (err==129) 
                  {  Comment("Неправильная цена ",TimeToStr(TimeCurrent(),TIME_MINUTES));
                     Sleep(5000);
                     RefreshRates();
                     continue;
                  }
                  if (err==146) 
                  {
                     if (IsTradeContextBusy()) Sleep(2000);
                     continue;
                  }
                  Comment("Ошибка ",err," закрытия ордера N ",OrderTicket(),
                          "     ",TimeToStr(TimeCurrent(),TIME_MINUTES));
               }
            }
         }
      }
      int n=0;
      for (j = 0; j < OrdersTotal(); j++)
      {
         if (OrderSelect(j, SELECT_BY_POS))
         {
            if ((OrderSymbol() == Symbol() || AllSymbol) && (Magic==0 || Magic==OrderMagicNumber()))
            {
               OT = OrderType();
               if (OT==OP_BUY || OT==OP_SELL) n++;
            }
         }  
      }
      if (n==0) break;
      nn++;
      if (nn>10) {Alert(Symb,"  Не удалось закрыть все сделки, осталось еще ",n);return(0);}
      Sleep(1000);
      RefreshRates();
   }
   return(1);
}




int Prise, Tiket_Sell, Tiket_Bay;
double Prise_Sell, Prise_Bay;

int start()
{
   if(AccountEquity() > AccountBalance()) CloseAll();
   
   if(OrdersTotal() == 0)
   {
      OrderSend(Symbol(),OP_BUY,Lot,Ask,4,0,0,0,0,0,CLR_NONE);
      OrderSend(Symbol(),OP_SELL,Lot,Bid,4,0,0,0,0,0,CLR_NONE);
      
      for(int i = 1; i <= 30; i++)
      {
         Prise = i * Step;
         OrderSend(Symbol(),OP_BUYSTOP,Lot,Ask + Prise * Point,4,0,0,0,0,0,CLR_NONE);
         OrderSend(Symbol(),OP_SELLLIMIT,Lot,Bid + Prise * Point,4,0,0,0,0,0,CLR_NONE);
         
         OrderSend(Symbol(),OP_SELLSTOP,Lot,Bid - Prise * Point,4,0,0,0,0,0,CLR_NONE);
         OrderSend(Symbol(),OP_BUYLIMIT,Lot,Ask - Prise * Point,4,0,0,0,0,0,CLR_NONE);
         }
      }
      
      if(OrdersTotal() > 0)
      {
         for(int j = OrdersTotal() - 1; j >= 0 ; j--)
         {
            OrderSelect(j, SELECT_BY_POS, MODE_TRADES);
         
            if(OrderType() == OP_SELL)
            {
               Prise_Sell = OrderOpenPrice();
               Tiket_Sell = OrderTicket();
            
               for(int k = OrdersTotal() - 1; k >= 0 ; k--)
               {
                  OrderSelect(k, SELECT_BY_POS, MODE_TRADES);
               
                  if(OrderType() == OP_BUY)
                  { 
                     if((Prise_Sell - OrderOpenPrice())/Point >= Step - Spread && (Prise_Sell - OrderOpenPrice())/Point <= Step - Spread + 2)
                     {
                        if((Bid - Prise_Sell)/Point >= Step + Step/2)
                        {
                           Tiket_Bay = OrderTicket();
                           Prise_Bay = OrderOpenPrice();
                           
                           OrderCloseBy(Tiket_Sell, Tiket_Bay, 0);
                           
                           OrderSend(Symbol(),OP_SELLSTOP,Lot,Prise_Sell,4,0,0,0,0,0,CLR_NONE);
                           OrderSend(Symbol(),OP_BUYLIMIT,Lot,Prise_Bay,4,0,0,0,0,0,CLR_NONE);
                           }
                        
                        if((Prise_Bay - Ask)/Point >= Step + Step/2)
                        {
                           Tiket_Bay = OrderTicket();
                           OrderCloseBy(Tiket_Sell, Tiket_Bay, 0);
                     
                           OrderSend(Symbol(),OP_SELLLIMIT,Lot,Prise_Sell,4,0,0,0,0,0,CLR_NONE);
                           OrderSend(Symbol(),OP_BUYSTOP,Lot,Prise_Bay,4,0,0,0,0,0,CLR_NONE);
                           }  
                        }
                     }
                  }
               }
            }
         } 
      
   return(0);
   }
Заранее спасибо.
 
antoxin_8p:

Сделал диапазон if((Prise_Sell - OrderOpenPrice())/Point >= Step - Spread && (Prise_Sell - OrderOpenPrice())/Point <= Step - Spread + 2), и изменил цикл на for(int k = OrdersTotal()-1; k >=0 ; k--).

Ордера теперь закрываются. Огромное спасибо!

Но возникли другие косяки. А именно не всегда в замен закрытых ордеров выставляются новые отложенники :( 

 

Выкладываю весь код, может быть кто-нибудь ткнет носом в ошибки:

Проверка положения цены открытия относительно Аск или Бид обязательна, ещё проверка расстояния от текущей цены до цены открытия больше величины селлстоп или фризлевел  тоже обязательна.

Также не помешает проверка исполнения, не просто

OrderSend(Symbol(),OP_BUYLIMIT,Lot,Prise_Bay,4,0,0,0,0,0,CLR_NONE);

а

if(!OrderSend(Symbol(),OP_BUYLIMIT,Lot,Prise_Bay,4,0,0,0,0,0,CLR_NONE))
{ 
Print("Error: ", GetLastError());
...другие действия в зависимости от типа ошибки
}
Причина обращения: