Помогите новичку. ( Закрытие всех ордеров) - страница 2

 
Aleksandr Teleguz:

Здравствуйте. У меня возникла немного другая проблема, но также при закрытии ордеров. 

Написал человеку советника, суть стратегии в локировании ордеров, т.е. при достижении определенной прибыли по всем открытым ордерам, они закрываются. Ордера разнонаправленные, вот функция, которая определяет прибыль по ордерам и при необходимости вызывает функцию закрытия ордеров:

 Кроме этой функции нигде в советнике не вызывается функция закрытия ордеров OrderClose_f, а вот собственно и она:

 Проблема в том, что периодически советник закрывает только один последний ордер, а остальные остаются в рынке. Заказчик при этом использует виртуальный сервер, демо счета, и несколько различных брокеров, если подобная проблема возникает, то единовременно у всех брокеров. А вот в ТЕСТЕРЕ СТРАТЕГИЙ советник работает как часы. 

 Когда ордера не закрываются то советник ПИШЕТ ОШИБКУ 4109. Кто сталкивался с подобной проблемой помогите пожалуйста...

(с)при достижении определенной прибыли по всем открытым ордерам...   Вот интересно, а откуда у вас появляется профит с ордеров?

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

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

double ProfitGeneralCurrency=100; // прибыль для закрытия

void OnTick()
 { 
  if(GetProfitOpenPosInCurrency(Symbol(),-1,-1)>ProfitGeneralCurrency) {
    ClosePosBySortLots(Symbol(),-1,-1,clrYellow);
    Print("Закрытие позиций по прибыли: ",Symbol());
   }
 }
 
//===============================================================================================
//------------- Возвращает суммарный профит открытых позиций в валюте депозита -----------------+
//===============================================================================================
double GetProfitOpenPosInCurrency(string sy="", int op=-1, int mn=-1) {
 double p=0;
  if(sy=="") sy=Symbol();
   for(int i=0; i<OrdersTotal(); i++) {
    if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
     if(OrderType()==OP_BUY || OrderType()==OP_SELL) {
      if((OrderSymbol()==sy || sy=="") && (op<0 || OrderType()==op)) {
       if(mn<0 || OrderMagicNumber()==mn) {
         p+=OrderProfit()+OrderSwap()+OrderCommission();
 }}}}}
  return(p);
 }
//===============================================================================================
//------------------ Закрытие позиций в порядке сортировки по размерам лотов -------------------+
//=== sd = Направление=сортировки лотов==(MODE_ASCEND = возрастание, MODE_DESCEND = убывание) ===
//===============================================================================================
bool ClosePosBySortLots(string sy="",int op=-1,int mn=-1,color cl=clrNONE,int sd=MODE_DESCEND) {
 double a[][2];
 int p=0,i;
  if(sy=="") sy=Symbol();
  for(i=0; i<OrdersTotal(); i++) {
    if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      if((OrderSymbol()==sy || sy=="") && (op<0 || OrderType()==op)) {
        if(OrderType()==OP_BUY || OrderType()==OP_SELL) {
          if(mn<0 || OrderMagicNumber()==mn) {
            p++;
            ArrayResize(a, p);
            a[p-1][0]=OrderLots();
            a[p-1][1]=OrderTicket();
  }}}}}
  // вдруг позиций нету, тогда и закрывать нечего
   if(p>0) {
    ArraySort(a, WHOLE_ARRAY, 0, sd);
    for(i=0; i<p; i++) {
      if(OrderSelect((int)a[i][1], SELECT_BY_TICKET)) {
        // проверим незакрытость на всякий случай,
        // может какая-то позиция уже закрылась по стопу/тейку
        if(OrderCloseTime()==0) if(ClosePosBySelect(cl)!=true) { return(true); }
   }}}
  return(false);
 }
bool ClosePosBySelect(color cl=clrNONE) {
 bool fc=false;
 double ll, pa, pb, pp;
 int err=0, it;
  if(OrderType()==OP_BUY || OrderType()==OP_SELL) {
    for(it=1; it<=10; it++) {
      if(!IsTesting() && (!IsExpertEnabled() || IsStopped())) break;
      while(!IsTradeAllowed()) {Sleep(5);}
      RefreshRates();
      pa=MarketInfo(OrderSymbol(), MODE_ASK);
      pb=MarketInfo(OrderSymbol(), MODE_BID);
      if(OrderType()==OP_BUY) {
        pp=pb;
      } else {
        pp=pa;
      }
      ll=OrderLots();
      fc=OrderClose(OrderTicket(), ll, pp, _slippage, cl);
      if(fc==true) {
        return(true);
        break;
      } else {
        err=GetLastError();
        if(err==146) {
        while(IsTradeContextBusy()) {Sleep(100);}
        Print("ClosePosBySelect(): Error Close Positions: ",(string)err," (",(err),") Параметры: Ask=",(string)(pa)," Bid=",(string)(pb),
              ", op=",OrderType(),", sy=",(string)OrderSymbol()," Ticket=",(string)OrderTicket(),", try=",it);
        }
        if(err==132 || err==133) {
          Print("ClosePosBySelect(): Error Close Positions: ",(string)err," (",(err),") Параметры: Ask=",(string)(pa)," Bid=",(string)(pb),
              ", op=",OrderType(),", sy=",(string)OrderSymbol()," Ticket=",(string)OrderTicket(),", try=",it);
         Sleep(50);
          Alert("ClosePosBySelect(): Error Close Positions: ",(string)err," (",(err),") Параметры: Ask=",(string)(pa)," Bid=",(string)(pb),
              ", op=",OrderType(),", sy=",(string)OrderSymbol()," Ticket=",(string)OrderTicket(),", try=",it);
            Sleep(1000*60*15);
            break;
        }
        if(err==2 || err==5 || err==7 || err==9 || err==64 || err==65) {
          Alert("ClosePosBySelect(): Critical Error Close Positions=",(string)err," (",(err),"), "," sy=",(string)OrderSymbol());
          break;
        }
        if(err==6) {
         Alert("ClosePosBySelect(): Error Close Positions: ",(string)err," (",(err),") Параметры: Ask=",(string)(pa)," Bid=",(string)(pb),
              ", op=",OrderType(),", sy=",(string)OrderSymbol()," Ticket=",(string)OrderTicket(),", try=",it);
         Sleep(1000*10);
         break;
        }
        if(err!=146) {
         Print("ClosePosBySelect(): Error Close Positions: ",(string)err," (",(err),") Параметры: Ask=",(string)(pa)," Bid=",(string)(pb),
              ", op=",OrderType(),", sy=",(string)OrderSymbol()," Ticket=",(string)OrderTicket(),", try=",it);
         Sleep(200);
         }
       }
      Sleep(5);
     }
   }
  return(false);
 }
//===============================================================================================
 
Vitaly Muzichenko:

(с)при достижении определенной прибыли по всем открытым ордерам...   Вот интересно, а откуда у вас появляется профит с ордеров?

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

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

Я не пояснил некоторые строки... 

if(_sum<SumProfit) return;

 Здесь происходит выход из функции если профит по ордерам не достиг нужного значения. А дальше сумма профитов по ордерам не проверяется, а следующий цикл for закрывает все ордера, открытые советником и кстати ордер с самым большим профитом (в этом алгоритме) всегда закрывается первым.

 
Aleksandr Teleguz:

Я не пояснил некоторые строки... 

 Здесь происходит выход из функции если профит по ордерам не достиг нужного значения. А дальше сумма профитов по ордерам не проверяется, а следующий цикл for закрывает все ордера, открытые советником и кстати ордер с самым большим профитом (в этом алгоритме) всегда закрывается первым.

Начнем с того, что всё что с профитом или убытком, не может быть ордером по определению.

Я ваш код читал, и написал причину не закрывания - вы читали?

Дублирую:

"У вас получается так: есть сигнал на закрытие, срабатывает функция и закрывает первую попавшую позицию, и хорошо если убыточную, то цикл закрытия продолжится, а вот если закроет прибыльную, тогда исчезает условие для закрытия и ничего не происходит:  вот тут условие и останавливается, так-как баланс стал меньше прописанного.

for(int i=10; i>0; i--)
     {
      close=OrderClose(ticket,lots,price,_slippage,arrow_color);
      if(close==true) return(close); // После первой закрытой - остановка функции

// для продолжения срабатывает условие, не закрывать, потому как эквити уже в минусе, а не в плюсе как было перед началом закрытия.
if(_sum<SumProfit) return;

 

Более правильно закрывать не самый прибыльный, а самый крупный, именно с самым большим лотом нужно закрывать первым, потому как изменение цены на один тик, отразиться сильно на эквити, и хорошо если в положительную сторону. Ведь есть разница, или 0.01 лот изменится на один тик, или 0.5 лота! 

Ставьте функции которые выложил, они у меня  работают на реале с мартином уже несколько лет, и проблем не обнаружено, начинает закрывать с максимального лота на уменьшение. Я так понял у вас тоже мартин присутствует.

 

Я ваш код читал, и написал причину не закрывания - вы читали?

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

for(int i=10; i>0; i--)
     {
      close=OrderClose(ticket,lots,price,_slippage,arrow_color);
      if(close==true) return(close);

 Этот цикл находится в функции OrderClose_f, которая лишь получает тикет позиции, которую нужно закрыть, это оболочка функции OrderClose, а в выше представленном цикле for, i это счетчик попыток закрытия.

Когда происходит выход из цикла, то управление передается в вызывающую функцию, а именно в OrderCloseSumProfit(), т.е сюда:

void OrderCloseSumProfit() //закрываем ордера по достижению необходимого суммарного профита
  {
   double _sum=0.0; //сумма профитов
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS)==false)
        {
         Print("Ордер не выбран (OrderCloseSumProfit)");
         continue;
        }
      if(OrderSymbol()!=symbol || OrderMagicNumber()!=magic) continue;
      _sum=_sum+OrderProfit()+OrderSwap()+OrderCommission();
     }
   if(_sum<SumProfit) return;
   OrderStopDelete();
   for(int i=OrdersTotal()-1; i>=0; i--) //цикл закрытия ордеров
     {
      if(OrderSelect(i,SELECT_BY_POS)==false)
        {
         Print("Ордер не выбран (OrderCloseSumProfit-2)");
         continue;
        }
      if(OrderSymbol()!=symbol || OrderMagicNumber()!=magic) continue;
      if(OrderType()==OP_BUY)
        {
         bool _close=OrderClose_f(OrderTicket(),OrderLots(),Bid,slippage,clrNONE);
        }
      if(OrderType()==OP_SELL) //вот суда, а этот цикл не проверяет сумму профитом открытых позиций, он просто закрывает все SELL и BUY ордера, посмотрите на его условие
        {
         bool _close=OrderClose_f(OrderTicket(),OrderLots(),Ask,slippage,clrNONE);
        }
     }
  }

 Я весь подсчет прибыли по открытым позициям повторно не производится, он уже был сделан выше. У меня в функции два цикла for, второй стоит после проверки по прибыли.

Напоминаю, что в тестере все работает как часы, и когда на демо что-то не срабатывает, то советник выдает ошибку 4109, как будто торговля запрещена, но вручную все закрывается, это либо косяк vps (но тогда была бы ошибка типа "нет связи"), либо мне нужно как, то ее обработать, может разнонаправленные позиции подругому закрывать (сразу), может паузы больше делать, может вы с подобным сталкивались и выяснили, что дело в ДЦ или VPS, подскажите...

 
Aleksandr Teleguz:

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

 Этот цикл находится в функции OrderClose_f, которая лишь получает тикет позиции, которую нужно закрыть, это оболочка функции OrderClose, а в выше представленном цикле for, i это счетчик попыток закрытия.

Когда происходит выход из цикла, то управление передается в вызывающую функцию, а именно в OrderCloseSumProfit(), т.е сюда:

 Я весь подсчет прибыли по открытым позициям повторно не производится, он уже был сделан выше. У меня в функции два цикла for, второй стоит после проверки по прибыли.

Напоминаю, что в тестере все работает как часы, и когда на демо что-то не срабатывает, то советник выдает ошибку 4109, как будто торговля запрещена, но вручную все закрывается, это либо косяк vps (но тогда была бы ошибка типа "нет связи"), либо мне нужно как, то ее обработать, может разнонаправленные позиции подругому закрывать (сразу), может паузы больше делать, может вы с подобным сталкивались и выяснили, что дело в ДЦ или VPS, подскажите...

Я с таким не сталкивался, бывает только изначально торговля запрещена вообще, но не в середине процесса ) Был случай когда брокер мне отключил автоторговлю, но это единичные экземпляры так поступают, и было это очень давно. Может у вас что с и ВПС. Более ничего не скажу - не сталкивался.