如何实现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个,以此类推。
第一笔订单的时间已经过了,我们应该关闭它,然后第二笔订单是系列的第一笔,时间已经过了,我们应该关闭它,等等。
事实上,如果是>=5*60,我们应该选择最古老的订单进行关闭。
但要从一系列的票据中选择它来关闭,我们应该以某种方式定义票据在开放订单中的最小值并确定存在的时间。

亚历山大-沃洛特科

请看一下金-伊戈尔的职能。

这里,一目了然,该函数返回最后一个位置被打开后的秒数。

它并不适合。对市场上的第一个位置感兴趣。

 
Natalya Dzerzhinskaya:

我就简单说说吧。

市场上有第1个订单,然后是第2个订单,第3个,以此类推。
第一笔订单的时间已经过期,那么第二笔订单是系列中的第一笔,时间已经过期,应该被关闭,等等。
事实上,如果是>=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个,以此类推。
第一笔订单的时间已经过期,我们应该关闭它,然后第二笔订单是系列的第一笔,时间已经过期,我们应该关闭它,等等。
事实上,如果是>=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)
{
//ну и пошло-поехало...
}

 

最简单的方法是在评论栏中输入订单应关闭的时间。

然后你只需要记住最接近收盘的时间(即便如此,也是优化)。

当到了 "修订 "的时候,用一个定时器或任何你想要的方式,循环浏览未结订单,关闭那些有效期 超过注释中指定时间的订单。