Функция удаления отложников при изменении лота

 

Здравствуйте уважаемые форумчане.

Необходимо написать функцию для удаления отложников при изменении лота.

Лот изменяется следующей функцией

extern double Lots = 0.1;
extern int     Kloss           =      1;
extern double  MultiplierLoss  =      2.0;


void OpenOrder() {

Lot =  KillaLoss();

.....

}


double KillaLoss(){
// -----
int Loss;
// -----
int orders=OrdersHistoryTotal();
  
double Lot=Lots;

   if(Kloss>0){

// ---- Считаем кол-во лоссов
      
      for (int i = orders - 1; i >= 0; i--) {
         if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) == FALSE) {
            Print("Ошибка в истории!");
            break;
         }
         if (OrderSymbol()!= Symbol() || OrderType() > OP_SELL) continue;
         if (OrderMagicNumber()!=MAGIC_NUMBER) continue;
         if (OrderProfit() > 0.0) break;
         if (OrderProfit() < 0.0) Loss++;
         }

// ---- Выставляем новый объём

       if(Loss>=Kloss) {
       
       Lot=Loss*MultiplierLoss*Lot;
      
       }
       
    } //--end if(Kloss>0){    
// -----

 return(Lot);
}


Дело в том что у меня тс построена на отложниках, и новый объем сделки применяется только к вновь открытым отложникам. Старые приходится удалять вручную.

Функция должна отслеживать объём лота, и при его изменении удалять отложники 1 раз (у меня получается ток с зацикленным удалением:) )

Также, если можно хотелось бы просто доработать KillaLoss, чтобы удаляло отложники если случился лосс. Так было бы намного лучше.

P.S.

Пытался сделать так, но не вышло:

void OpenOrder()
//+------------------------------------------------------------------+
{
   lot =   KillaLoss();
   
   if (lot>Lots) CloseLimit();
.....

void CloseLimit() {
   int LimitErrorForClose; // Получение информации об ошибке, GetLastError(), для данной функции
   int LimitDelete;     // Удаление отложников в данной функции
   int CountCloseLimit = 0; // Счетчик для попыток удаления отложников
   while (true) {
      if (OrderMagicNumber() == MAGIC_NUMBER && OrderSymbol() == Symbol()) LimitDelete = OrderDelete(OrderTicket());
      LimitErrorForClose = GetLastError();
      if (LimitErrorForClose == 0/* NO_ERROR */) {
         Print("Close Limit Order. Лимит ордер закрыт");
         return;
      }
      Print("Не могу закрыть лимит ордер по символу ", Symbol(), " Ошибка № ", GetLastError());
      Sleep(500);
      RefreshRates();
      CountCloseLimit++;
      if (CountCloseLimit <= 25) continue;
      break;
   }
   Alert("Order failed to CLOSE - See Journal for errors");
}

Заранее спасибо за помощь.

 

Замените

int CountCloseLimit = 0; // Счетчик для попыток удаления отложников
   while (true) {

На

int CountCloseLimit = 0; // Счетчик для попыток удаления отложников
for(int i=OrdersTotal()-1;i>=0;i--)
{
OrderSelect(i,SELECT_BY_POS);   
while (true) {

и после алерта еще одну закрывающую скобку

И еще, замените return; на continue;

 
Спасибо за помощь, работает. Но теперь остаются отложники большего объёма уже после того как сделка была закрыта в +. То есть был лос, отложники удалились, и лот выставился удвоенный, далее был тейк и лот у ордеров должен стать прежним, но по правилу они удаляются только если новый лот больше текущего
if (lot>Lots) CloseLimit();

То есть после тейка остаются висеть удвоенные отложники.

Если сделать так

if (lot>Lots || lot<Lots) CloseLimit();

то будет бесконечный цикл удаления.

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


Заранее спасибо за помощь.

 
Написал сейчас функцию на основе KillaLoss, но всё равно получается бесконечное зацикливание по удалению отложников после первого ордера.
 

По прежнему проблема актуальна...

Прошу помочь

 

Скажу в двух словах, так думаю проще было)

Ордер закрылся по стоп-лоссу (по траллу) или тейку (не виртуальные), далее нужно чтобы удалились отложники.

Вот нужна функция которая бы удаляла отложники после закрытия ордера.

 

проблем с установкой ордеров нет. Единственно что нужно

>>>

нужна функция которая бы удаляла отложники после закрытия ордера.

Видимо я как-то не так объясняю. Попробую заново объяснить.

Советник выставлять отложенные ордера, например 4 ордера на OP_BUYLIMIT. Для каждого ордера установлены уровни тейка и стопа.

Допустим цена зацепила 1 ордер, и он закрылся по тейку.

(!) Далее необходимо чтобы остальные 3 отложенные ордера OP_BUYLIMIT удались.

Вот нужна функция которая бы удаляла отложники после закрытия ордера.

>>>

Далее, если вести учет открытых ордеров функцией CalculateOrd

if(CalculateOrd(OP_BUY)==0) CloseDelete(OP_BUYLIMIT);
if(CalculateOrd(OP_SELL)==0) CloseDelete(OP_SELLLIMIT);

Не приведет ли это к зацикливанию и бесконечному удалению отложников?

 

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

А если использовать

if(CalculateOrd(OP_BUY)==0) CloseDelete(OP_BUYLIMIT);

То будет бесконечное зацикливание - ордера будут выставляться и сразу удаляться.

 

Можно сделать например удаление отложников, если будет открыт ордер, например так:

if(OrdersCount(OP_SELL,MagicNumber)==1)DeleteOrders(OP_BUYSTOP, MagicNumber);
if(OrdersCount(OP_BUY,MagicNumber)==1)DeleteOrders(OP_SELLSTOP, MagicNumber);

//+----

int OrdersCount(int type, int mn)
{
//+----
  int orders=0;
  int cnt=OrdersTotal();
  for (int i=0; i<cnt; i++) {
    if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
    if (OrderSymbol()!=Symbol()) continue;
    if (OrderMagicNumber()!=mn) continue;
    if (OrderType()==type||type<0) orders++;
  }
//+----
  return (orders);
}

void DeleteOrders(int op=-1, int mn=-1) {
  bool fd;
  int  i, it, k=OrdersTotal();
  for (i=k-1; i>=0; i--) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
        if (OrderSymbol()==Symbol() && OrderType()==op) {
          if (OrderMagicNumber()==mn) {
            for (it=1; it<=5; it++) {
              if (!IsTesting() && (!IsExpertEnabled() || IsStopped())) break;
              while (!IsTradeAllowed()) Sleep(5000);
              fd=OrderDelete(OrderTicket(), 0);
              if (fd) { PlaySound("ok.wav"); break;
              Sleep(1000*5);
            }
          }
        }
      }
    }
  }
  return(0);
}

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

 

А, может я не так написал опять. Всмысле чтобы он 1 раз удалил их и всё (при запуске терминала и если ордер был закрыт по тейку или лоссу), без цикла, разовая процедура, всё равно что удалять скриптом.

Просто лот же нельзя другой выставлять у отложников (модифицировать), вот из-за этого такие трудности.

 

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