for循环中的MQL5数组需要太长时间,还有更好的方法吗?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (23)

我正在编写一个EA,仅用于战略测试目的,以评估投资组合。所以我有一个数组中的hundreads /成千上万的交易,开盘价和开盘时间,每隔1分钟我检查一次for循环,如果在那一分钟有任何交易开放。这是永远的。

如何在阵列中检查是否有与当前时间一致的开放时间?如何检查(以更快的方式)?

谢谢!

if(NewBar)
 {
  CopyRates(_Symbol,PERIOD_M1,0,5,candle);
  sizeAr=ArraySize(ar);
  arColumns=ArrayRange(ar,1);
  datetime candleNowTime = candle[0].time;
  datetime nextCandleTime = candle[0].time+60;      

  for(int i=0;i<sizeAr/arColumns;i++)
    {
     if(ar[i][openTime]>candleNowTime && ar[i][openTime]<nextCandleTime)
       {
        //code to open trades
       }
    }
 }
提问于
用户回答回答于

最简单的方法是使用类,每个类都扩展CObject,你必须实现Compare函数。首先,创建一个输入(in = true)和退出(in = false)的结构:

struct SEvent
{
   datetime m_time;
   double   m_price;
   bool     m_in;

   void Init(const datetime time,const double price,const bool in)
   {
    m_time=time;
    m_price=price;
    m_in=in;
   }
   int Compare(SEvent &another)const
   {
    return int(m_time-another.m_time);
   }
};

接下来,创建类 CDeal : public CObject

class CDeal : public CObject
{
 static int  getDir(string cmd)
 {
  if(cmd=="Sell")
     return(-1);
  if(cmd=="Buy")
     return(1);
  if(cmd=="Type" || cmd=="Balance")
     return(0);
  printf("%i %s: unknown cmd=|%s|",__LINE__,__FILE__,cmd);
  return(0);
 }
 static string getSymbol(string line)
 {
  return StringSubstr(line,0,StringLen(line)-StringLen(InpReportSuffix))+InpSymbolSuffix;
 }
public:
 intX        m_id;
 int         m_dir;
 SEvent      m_in;
 SEvent      m_out;
 double      m_lot;
 string      m_symbol;
 double      m_osl;
 double      m_otp;
 CDeal(string line)
 {
  //2019.05.13 18:27:56;Sell;0.10;EURCADm#;1.51270;;;2019.05.14 13:36:47;1.51142;;;0.10;
  string array[];
  const ushort separator=(ushort)';';
  int size=StringSplit(line,separator,array);
  if(size<11)
    {
     printf("%i %s: size=%d str=%s",__LINE__,__FILE__,size,line);
     m_dir=0;
     return;
    }
  m_dir=getDir(array[1]);
  m_lot=StringToDouble(array[2]);
  m_symbol=getSymbol(array[3]);
  m_in.Init(StringToTime(array[0]),StringToDouble(array[4]),true);
  m_osl=StringLen(array[5])>0 ? StringToDouble(array[5]) : 0;
  m_otp=StringLen(array[6])>0 ? StringToDouble(array[6]) : 0;
  m_out.Init(StringToTime(array[7]),StringToDouble(array[8]),false);
 }
~CDeal(){}
 virtual int       Compare(const CObject *node,const int mode=0) const 
 {
  CDeal *another=(CDeal*)node;
  if(mode==1)
    {
     return m_in.Compare(another.m_in);
    }
  else
    {
     return m_out.Compare(another.m_out);
    }
 }
 virtual string    toString()const
 {
  return StringFormat("%s;%d;%.2f;%s;%.5f;%.5f;%.5f;%s;%.5f;%s",TimeToString(m_in.m_time),m_dir,m_lot,m_symbol,
     m_in.m_price,m_osl,m_otp,TimeToString(m_out.m_time),m_out.m_price,m_pnl.toString());
 }
};

然后,将所有CDeals 加载stringCArrayObj其中list.Sort(1),以便在输入时对它们进行排序。然后循环,或者从一些static int cursor=0;增量循环,如果TimeCurrent()>((CDeal*) list.At(cursor)).m_in.m_time当然要记住你可以到达列表的末尾,或者如果相同条件为真则分离元素,并附加到另一个CArrayObj listOfOpenDeals。每次添加元素时,不要忘记对现有未结交易列表进行排序。同样的方法检查是否是时候从开放交易列表中关闭一些交易,并在关闭后删除元素。总共300行代码。

扫码关注云+社区

领取腾讯云代金券