Como implementar o fechamento das posições um de cada vez após N minutos ?

 

mql4
Por exemplo, 5 minutos se passaram depois que o pedido foi aberto, e este pedido deve fechar.
O código é muito pesado para memorizar o bilhete a ser fechado e o tempo de abertura a ser usado para calcular os minutos para cada pedido separadamente.
Pode haver 1,2,3-10 posições, comprar e vender ao mesmo tempo.

Você pode sugerir uma função para armazenar esses dados em uma matriz para comparar e fechar ainda mais o bilhete necessário?


 
Afinal, todos os ingressos e horários de abertura já estão presentes em matrizes padrão.
Percorra todas as posições por temporizador e compare TimeCurrent()-OrderOpenTime()>=300
 
Taras Slobodyanik:
Afinal, todos os ingressos e horários de abertura já estão presentes em matrizes padrão.
Enumeramos todas as posições por temporizador e comparamos TimeCurrent()-OrderOpenTime()>=300

O que são essas matrizes padrão?
Você pode elaborar sobre eles?

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

Como posso usar estas funções para fechar posições individualmente e não todas de uma só vez após 5 minutos?

Há a primeira posição aberta, registramos o tempo e o ticket
na variável, depois a segunda posição aberta, a vemos no loop como a última e a registramos na variável tempo e ticket
, mas todas essas ações são sobrescritas e acontece que os dados são armazenados apenas a partir da última posição

 
Natalya Dzerzhinskaya:

Como posso usar estas funções para fechar posições individualmente e não todas de uma só vez após 5 minutos?

Há a primeira posição aberta, registramos na variável tempo e ticket
depois a segunda posição aberta, a vemos no loop como a última e a registramos na variável tempo e ticket
mas todas essas ações são sobrescritas e acontece que os dados são armazenados apenas a partir da última posição

A condição de selecionar apenas uma ordem dentre as que precisamos fechar não antes de 5 minutos após sua abertura não é muito clara.

Portanto, não sei o que responder.

Se houver uma condição, devemos começar com ela.

No momento, todos eles foram virtualmente selecionados e serão fechados em uma pilha, um após o outro.

A primeira ordem em aberto tem isto mesmo: TimeCurrent()-OrderOpenTime() será o maior, por exemplo, seu OrderTicket().

Você pode passar por todas as suas ordens de mercado no seguinte ciclo

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

mql4
Por exemplo, passaram 5 minutos após a abertura da ordem e esta ordem deve ser fechada.

Dê uma olhada nas funções de Kim Igor.

Aqui, num relance, a função retorna o número de segundos depois que a última posição foi aberta.

//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. 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);
}

Revise-a para adequá-la à sua tarefa. Acrescente a ela a função que fecha uma posição.

 
Renat Akhtyamov:

Não está bem claro se é uma ordem que tem que ser fechada pelo menos 5 minutos após a abertura.

Deixe-me explicar de uma forma mais simples:

Há a primeira ordem no mercado, depois a segunda, terceira e assim por diante.
O tempo do primeiro pedido expirou e devemos fechá-lo, então o segundo pedido é o primeiro da série, o tempo expirou e devemos fechá-lo, etc.
Na verdade, devemos escolher a ordem mais antiga para fechar se for >=5*60
Mas para selecioná-lo de uma série a ser fechada pelo bilhete, devemos de alguma forma definir o menor valor do bilhete nas ordens abertas e determinar o tempo de existência.

Aleksandr Volotko:

Dê uma olhada nas funções de Kim Igor.

Aqui, num relance, a função retorna o número de segundos depois que a última posição foi aberta.

Não se encaixa. Interessado na primeira posição no mercado.

 
Natalya Dzerzhinskaya:

Vou simplificar as coisas:

Há a primeira ordem no mercado, depois a segunda ordem, a terceira e assim por diante.
O tempo do primeiro pedido expirou, depois o segundo pedido é o primeiro da série, o tempo expirou, ele deve ser fechado, etc.
Na verdade, devemos escolher a ordem mais antiga para fechar se for >=5*60
Mas para selecioná-lo a partir de uma série a ser fechada pelo bilhete, devemos de alguma forma definir o menor valor do bilhete nas ordens abertas e determinar o tempo de existência.

Não vai caber. Interessado na primeira posição no mercado.


Qual é o problema?

  1. Encontre o pedido mais antigo aberto pelo Expert Advisor. Ela tem o menor OrderOpenTime().
  2. Compare o tempo decorrido desde o momento da abertura desta ordem até a hora atual. Se for igual ou maior do que o tempo especificado, feche-o.
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:

Vou simplificar as coisas:

A 1ª ordem está no mercado, depois a 2ª, 3ª e assim por diante.
O tempo do primeiro pedido expirou e devemos fechá-lo, então o segundo pedido é o primeiro da série, o tempo expirou e devemos fechá-lo, etc.
Na verdade, devemos escolher a ordem mais antiga para fechar se for >=5*60
Mas para selecioná-lo a partir de uma série a ser fechada pelo bilhete, devemos de alguma forma definir o menor valor do bilhete nas ordens abertas e determinar o tempo de existência.

Não vai caber. Você está interessado na primeira posição no mercado.

Em termos de tempo de existência, você pode selecionar tanto a primeira ordem aberta quanto a mais recente. Neste caso, lembramo-nos do bilhete e do número de segundos de existência. Por exemplo

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)
{
//ну и пошло-поехало...
}

 

A maneira mais fácil é entrar no campo de comentários na hora em que o pedido deve ser fechado.

Então, basta lembrar a hora mais próxima para fechar (e mesmo assim, é a otimização).

Quando chegar a hora da "revisão", em um temporizador ou o que você quiser, faça um loop através das ordens abertas e feche aquelas cuja vida útil excede o tempo especificado no comentário