Скачать MetaTrader 5
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Проблемы с кодом? Загляни в документацию!
Антон
19
Антон 2014.11.14 13:35 

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

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

   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.

 

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

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

Vitalie Postolache
11137
Vitalie Postolache 2014.11.14 14:25  
antoxin_8p:

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

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

 

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

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

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

 

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

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

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

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

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

Vitalie Postolache
11137
Vitalie Postolache 2014.11.14 14:44  
antoxin_8p:

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

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

А, да, теперь вижу, привык что цветом код выделяется.
Антон
19
Антон 2014.11.14 14:48  

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

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

Vitalie Postolache
11137
Vitalie Postolache 2014.11.14 14:52  

Строгое

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

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

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

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

Vitalie Postolache
11137
Vitalie Postolache 2014.11.14 14:55  

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

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

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

for(int k = OrdersTotal()-1; k >=0 ; k--) //счёт от самого свежего к самому старому
Антон
19
Антон 2014.11.14 15:00  

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

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

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

Сделал диапазон 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);
   }
Заранее спасибо.
Vitalie Postolache
11137
Vitalie Postolache 2014.11.14 20:37  
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());
...другие действия в зависимости от типа ошибки
}
/
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий