Помогите найти ошибку в простом Советнике!

 

Писал этот советник еще год назад а сейчас адаптировал под новый компилятор. Проблема в том, что этот советник то работает, то не работает. А сейчас совсем перестал работать! Суть Советника - закрытие всех позиций на текущем графике.

int Total,Ticket;
string Symb;
bool Ans =false;
void OnTick ()
{
Symb=Symbol(); // Название фин.инстр.
Total=0; // Количество ордеров
for(int i=1; i<=OrdersTotal(); i++) // Цикл перебора ордер
{
if (OrderSelect(i-1,SELECT_BY_POS)==true) // Если есть следующий
{ // Анализ ордеров:
if (OrderSymbol()!=Symb)continue; // Не наш фин. инструм
if (OrderType()>1) // Попался отложенный
{
Alert("Обнаружен отложенный ордер. Эксперт не работает.");
return; // Выход из start()
}
Total++; // Счётчик рыночн. орд
}
}

Ticket=OrderTicket();
if (OrdersTotal( ) > 0)

{
Alert("Закрытие всех ордеров");

RefreshRates();
Ans=OrderClose(Ticket,OrderLots( ),Ask,3,Yellow);
Ans=OrderClose(Ticket,OrderLots( ),Bid,3,Yellow);



}

}

 
3Sergey:

Писал этот советник еще год назад а сейчас адаптировал под новый компилятор. Проблема в том, что этот советник то работает, то не работает. А сейчас совсем перестал работать! Суть Советника - закрытие всех позиций на текущем графике.

int Total,Ticket;
string Symb;
bool Ans =false;
void OnTick ()
{
Symb=Symbol(); // Название фин.инстр.
Total=0; // Количество ордеров
for(int i=1; i<=OrdersTotal(); i++) // Цикл перебора ордер
{
if (OrderSelect(i-1,SELECT_BY_POS)==true) // Если есть следующий
{ // Анализ ордеров:
if (OrderSymbol()!=Symb)continue; // Не наш фин. инструм
if (OrderType()>1) // Попался отложенный
{
Alert("Обнаружен отложенный ордер. Эксперт не работает.");
return; // Выход из start()
}
Total++; // Счётчик рыночн. орд
}
}

Ticket=OrderTicket();
if (OrdersTotal( ) > 0)

{
Alert("Закрытие всех ордеров");

RefreshRates();
Ans=OrderClose(Ticket,OrderLots( ),Ask,3,Yellow);
Ans=OrderClose(Ticket,OrderLots( ),Bid,3,Yellow);



}

}


for(int i=0; i<OrdersTotal(); i++)
              {
               if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
                 {
                  if(OrderSymbol()==Symbol())
                    {
                      if(OrderType()==OP_BUY)  OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(), MODE_BID),5,Red);
                      if(OrderType()==OP_SELL) OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(), MODE_ASK),5,Red);
                    }
                 }
              }
 
pako:


Всё правильно за исключением одной мелочи.

Для закрытия ордеров направление перебора надо вести от OrdersTotal()-1 до нуля.

for(int i = OrdersTotal()-1; i >= 0; i--)
В остальных случаях не очень важно.
 
AlexeyVik:

Всё правильно за исключением одной мелочи.

Для закрытия ордеров направление перебора надо вести от OrdersTotal()-1 до нуля.

В остальных случаях не очень важно.

поясните почему?
 

Пусть OrdersTotal() = 10, тикеты 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

Начинаем закрывать. счётчик цикла i = 0 -> ордер № 1 пусть будет отложка...

i = 1 -> ордер № 2 закрыли, OrdersTotal() = 9 остались тикеты 1, 3, 4, 5, 6, 7, 8, 9, 10

i = 2 -> ---------- Под индексом 2 оказался ордер № 4... №3 пропущен, закрыли №4 остались 1, 3, 5, 6, 7, 8, 9, 10

i = 3 -> продолжи сам...

 
pako:

поясните почему?


Ну закроете первый ордер, цепочка сдвинется и на месте первого будет который стоял следующим. И проверка этого ордера будет пропущена.

 
AlexeyVik:

splxgf


Проверьте
 

Проверено неоднократно. Зря сомневаешься.

Если этот код выполняется постоянно, на каждом тике, то конечно будут удалены все ордера. Но только за несколько заходов в цикл.

Сделай это скриптом и ты получишь пропущенные ордера.

 

Спасибо парни за помощь!

 
pako:

Проверьте

Проверено, реально правильно говорят AlexeyVik: splxgf

например не всегда отрабатывает вот этот штатный скрипт - он не ВСЕГДА удяляет

//+------------------------------------------------------------------+
//|                                               delete_pending.mq4 |
//|                      Copyright © 2004, MetaQuotes Software Corp. |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2004, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net/"
#property show_confirm
//+------------------------------------------------------------------+
//| script "delete first pending order"                              |
//+------------------------------------------------------------------+
int start()
  {
   bool   result;
   int    cmd,total;
//---
   total=OrdersTotal();
//---
   for(int i=0; i<total; i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         cmd=OrderType();
         //--- pending orders only are considered
         if(cmd!=OP_BUY && cmd!=OP_SELL)
           {
            //--- print selected order
            OrderPrint();
            //--- delete first pending order
            result=OrderDelete(OrderTicket());
            if(result!=TRUE) Print("LastError = ",GetLastError());
            break;
           }
        }
      else
        {
         Print("Error when order select ",GetLastError());
         break;
        }
     }
//---
   return(0);
  }
//+------------------------------------------------------------------+


а этот не всегда ВСЕ закроет


//+------------------------------------------------------------------+
//|                                                        close.mq4 |
//|                      Copyright © 2004, MetaQuotes Software Corp. |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2004, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net/"
#property show_confirm
//+------------------------------------------------------------------+
//| script "close first market order if it is first in the list"     |
//+------------------------------------------------------------------+
int start()
  {
   bool   result;
   double price;
   int    cmd,error;
//---
   if(OrderSelect(0,SELECT_BY_POS,MODE_TRADES))
     {
      cmd=OrderType();
      //--- first order is buy or sell
      if(cmd==OP_BUY || cmd==OP_SELL)
        {
         while(true)
           {
            if(cmd==OP_BUY) price=Bid;
            else            price=Ask;
            result=OrderClose(OrderTicket(),OrderLots(),price,3,CLR_NONE);
            if(result!=TRUE)
              {
               error=GetLastError();
               Print("LastError = ",error);
              }
            else
               error=0;
            if(error==135)
               RefreshRates();
            else
               break;
           }
        }
     }
   else
      Print("Error when order select ",GetLastError());
//---
   return(0);
  }
//+------------------------------------------------------------------+

в этих скриптах логический глюк...

 
YuraZ:

Проверено, реально правильно говорят AlexeyVik: splxgf

например не всегда отрабатывает вот этот штатный скрипт - он не ВСЕГДА удяляет


а этот не всегда ВСЕ закроет


в этих скриптах логический глюк...




Последний скрипт предназначен для закрытия одного ордера а не всех :) Хотя ошибка в логике в нем есть, он берет "0" т.е. самый последний ордер по номеру тикета, а это может быть и отложенник а не открытая позиция и тогда он закончит работу ничего не закрыв

Надо добавить цикл for(int i=0; i<OrdersTotal(); i++) или наоборот for(int i=OrdersTotal()-1; i>=0; i--) тогда он закрыв одну открытую позицию выйдет только заменить break на return или оставить break но тогда он все позиции позакрывает :)) От того с какого конца начали перебирать ордера зависит какой он закроет ордер - самый первый или последний из списка открытых позиций, а для случая закрытия все позиций надо использовать только второй вариант for(int i=OrdersTotal()-1; i>=0; i--)

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