Как реализовать закрытие позиций по одной через N-минут ?

 

mql4
После открытия ордера прошло например 5 минут и этот ордер должен закрыться.
Запоминать тикет для закрытия и время открытия для отсчёта минут каждого ордера по отдельности получается слишком пузатый код у меня.
Позиций может быть 1,2,3-10, бай и селл одновременно.

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


 
Так ведь все тикеты и времена открытий уже есть в стандартных массивах.
Перебираем по таймеру все позиции, и сравниваем TimeCurrent()-OrderOpenTime()>=300
 
Taras Slobodyanik:
Так ведь все тикеты и времена открытий уже есть в стандартных массивах.
Перебираем по таймеру все позиции, и сравниваем TimeCurrent()-OrderOpenTime()>=300

Это что за стандартные массивы?
Можно подробнее?

 
стандартные функции MQL, не массивы
Торговые функции - Справочник MQL4
Торговые функции - Справочник MQL4
  • docs.mql4.com
Торговые функции могут использоваться в экспертах и скриптах. Торговые функции OrderSend(), OrderClose(), OrderCloseBy(), OrderModify(), OrderDelete(), изменяющие состояние...
 

Как мне с набором этих функций закрывать позиции по отдельности а не все сразу через 5 минут?

есть первая открытая позиция, записали в переменную время и тикет
далее открылась вторая позиция, мы её видим в цикле как последняя и записываем в переменную время и тикет
вот только все эти действия перезаписываются и получается что данные хранятся только от последней позиции

 
Natalya Dzerzhinskaya:

Как мне с набором этих функций закрывать позиции по отдельности а не все сразу через 5 минут?

есть первая открытая позиция, записали в переменную время и тикет
далее открылась вторая позиция, мы её видим в цикле как последняя и записываем в переменную время и тикет
вот только все эти действия перезаписываются и получается что данные хранятся только от последней позиции

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

Поэтому - пока не знаю что ответить.

Если есть условие, нужно с него и начинать.

А на данный момент все они виртуально выбраны и закроются кучей, один за другим.

У самого первого открытого ордера это: TimeCurrent()-OrderOpenTime() будет самым большим к примеру, тикет его OrderTicket()

Перебрать все Ваши рыночные ордера можно в таком цикле

int i;      
     for (i=OrdersTotal()-1; i>=0; i--)
         {
            if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
               {
                  ............
               }
         }
 
Natalya Dzerzhinskaya:

mql4
После открытия ордера прошло например 5 минут и этот ордер должен закрыться.

Посмотрите функции Кима Игоря.

Вот, на вскидку, функция возвращает количество секунд после открытия последней позиции.

//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 19.02.2008                                                     |
//|  Описание : Возвращает количество секунд после открытия последней позиций. |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента   (""   - любой символ,                   |
//|                                     NULL - текущий символ)                 |
//|    op - операция                   (-1   - любая позиция)                  |
//|    mn - MagicNumber                (-1   - любой магик)                    |
//+----------------------------------------------------------------------------+
datetime SecondsAfterOpenLastPos(string sy="", int op=-1, int mn=-1) {
  datetime t=0;
  int      i, k=OrdersTotal();

  if (sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      if (OrderSymbol()==sy || sy=="") {
        if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
          if (op<0 || OrderType()==op) {
            if (mn<0 || OrderMagicNumber()==mn) {
              if (t<OrderOpenTime()) t=OrderOpenTime();
            }
          }
        }
      }
    }
  }
  return(TimeCurrent()-t);
}

Переделайте её под свою задачу. Добавьте к ней функцию закрытия одной, выбранной позиции.

 
Renat Akhtyamov:

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

Объясню проще:

В рынке 1-ый ордер, далее 2-ой, 3-ий и т.д.
У первого ордера истекло время надо его закрыть, потом 2-ой ордер стал первым в серии, истекло время надо его закрыть и т.д.
По сути надо выбрать самый старый ордер для закрытия если >=5*60
Но чтобы его выбрать из серии для закрытия по тикету, надо как то определить самое малое значение тикета в открытых ордерах и определить время существования.

Aleksandr Volotko:

Посмотрите функции Кима Игоря.

Вот, на вскидку, функция возвращает количество секунд после открытия последней позиции.

Не подойдёт. Интересует самая первая позиция по рынку.

 
Natalya Dzerzhinskaya:

Объясню проще:

В рынке 1-ый ордер, далее 2-ой, 3-ий и т.д.
У первого ордера истекло время надо его закрыть, потом 2-ой ордер стал первым в серии, истекло время надо его закрыть и т.д.
По сути надо выбрать самый старый ордер для закрытия если >=5*60
Но чтобы его выбрать из серии для закрытия по тикету, надо как то определить самое малое значение тикета в открытых ордерах и определить время существования.

Не подойдёт. Интересует самая первая позиция по рынку.


В чем проблема то?

  1. Найти самый старый ордер, открытый экспертом. У него наименьшее OrderOpenTime().
  2. Сравнить, сколько времени прошло от момента открытия этого ордера до текущего времени. Если равно или больше заданного - закрыть.
int nOlderTicket = -1;
datetime dtOlderOrderTime = D'3000.12.30';
for (int i = OrdersTotal() - 1; i >= 0; --i)
{
   if (!OrderSelect(i, SELECT_BY_POS))
      continue;

   if (OrderSymbol() != Symbol())
      continue;

   if (OrderMagicNumber() != i_nMagicNumber)
      continue;

   if (nOlderTicket < 0 || OrderOpenTime() < dtOlderOrderTime)
   {
      nOlderTicket = OrderTicket();
      dtOlderOrderTime = OrderOpenTime();
   }
}

if (TimeCurrent() - dtOlderOrderTime >= время в секундах)
{
   // Закрыть ордер nOlderTicket
}


 
Natalya Dzerzhinskaya:

Объясню проще:

В рынке 1-ый ордер, далее 2-ой, 3-ий и т.д.
У первого ордера истекло время надо его закрыть, потом 2-ой ордер стал первым в серии, истекло время надо его закрыть и т.д.
По сути надо выбрать самый старый ордер для закрытия если >=5*60
Но чтобы его выбрать из серии для закрытия по тикету, надо как то определить самое малое значение тикета в открытых ордерах и определить время существования.

Не подойдёт. Интересует самая первая позиция по рынку.

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

int i, DeltaTimeOpen, prevDeltaMax, prevDeltaMin, TicketFirst, TicketLast, DeltaTimeClose;  
//---------------
prevDeltaMax=0; prevDeltaMin=9999999999999; TicketFirst=0; TicketLast=0; DeltaTimeClose = 5*60;     
     for (i=OrdersTotal()-1; i>=0; i--)
         {            
            if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
               { 
                  DeltaTimeOpen = TimeCurrent()-OrderOpenTime();//возраст ордера в секундах
                  if(DeltaTimeOpen>=DeltaTimeClose)
                  {
                     if(DeltaTimeOpen>prevDeltaMax)
                     {                         
                         TicketLast=OrderTicket();//последний  
                         prevDeltaMax=DeltaTimeOpen;//возраст                    
                     }
                     if(DeltaTimeOpen<prevDeltaMin)
                     {
                         TicketFirst=OrderTicket(); //первый
                         prevDeltaMin=DeltaTimeOpen;//возраст                                              
                     }
                  }
               }
         }
if(TicketFirst>0)
{
//ну и пошло-поехало...
}

 

самое-самое простое - это писать в поле comment время когда ордер должен быть закрыт.

тогда надо помнить только самое ближнее время к закрытию (да и то это оптимизация).

Когда наступает пора "ревизии", по таймеру или как вам удобно, проходите циклом по открытым ордерам и закрываете те, время жизни которых превысило указанное в коментарии