文章 "跨平台智能交易系统: 停止位"

 

新文章 跨平台智能交易系统: 停止位已发布:

本文讨论智能交易系统中停止价位的实现, 以便在两个平台 Metatrader 4 和 Metatrader 5 之间兼容。

正如我们从前一篇文章 (参见 跨平台智能交易系统: 订单) 中了解到的那样, 在交易操作 (入场) 成功之后创建了一个 COrder 实例。对于 MetaTrader 4 和 MetaTrader 5, 关于止损和止盈的信息可以从经纪商的后台获取并保存。然而, 如果要对经纪商隐藏停止位或涉及多个停止位的情况下, 关于这些停止位的更多信息就应该被保存在本地。因此, 在后一种情况下, 在仓位成功入场后, 应首先创建 COrder 实例, 随后是代表其止损和止盈价位的对象实例。在早前的文章中, 我们已演示了如何在创建时将 COrder 实例添加到订单管理器中, 正如下图所示:


TradeOpen

作者:Enrico Lambino

 

应使用哪种方法将 SL/TP 设置为特定值,而不是与开盘价的 距离?

 
这就是 StopLossCustom 和 TakeProfitCustom 方法。这些方法将在下一篇文章中讨论。
 

我尝试在我的 EA 中使用几个止损点。添加了您的函数 manage_trades(),这就是我在最后一个止损激活(平仓)后得到的结果:

2017.09.10 09:48:25.706 2017.01.03 17:50:23   failed market buy 0.00 EURUSD [Invalid volume]
2017.09.10 09:48:25.706 2017.01.03 17:50:23   CTrade::OrderSend: market buy 0.00 EURUSD [invalid volume]
2017.09.10 09:48:25.706 2017.01.03 17:50:23   position #2  is already closed, closing object..
2017.09.10 09:48:25.706 2017.01.03 17:50:23   failed market buy 0.00 EURUSD [Invalid volume]
2017.09.10 09:48:25.706 2017.01.03 17:50:23   CTrade::OrderSend: market buy 0.00 EURUSD [invalid volume]
2017.09.10 09:48:25.707 2017.01.03 17:50:23   position #2  is already closed, closing object..
2017.09.10 09:48:25.707 2017.01.03 17:50:23   failed market buy 0.00 EURUSD [Invalid volume]
2017.09.10 09:48:25.707 2017.01.03 17:50:23   CTrade::OrderSend: market buy 0.00 EURUSD [invalid volume]

使用了 3 个止损点,都是虚拟的。

这与手数有关。我使用固定手数 0.1。第一次平仓后,剩余交易量为 0.06。最后一次平仓后(没有指定交易量的主止损),我出现了上述错误。

如果手数较高,就会出现上述错误。您的 EA 示例也是如此。

 
mbjen:

我尝试在我的 EA 中使用几个止损点。添加了您的函数 manage_trades(),这就是我在最后一个止损激活(平仓)后得到的结果:

使用了 3 个止损点,都是虚拟的。

这与手数有关。我使用固定手数 0.1。第一次平仓后,剩余交易量为 0.06。最后一次平仓后(没有指定交易量的主止损),我出现了上述错误。

如果手数较高,就会出现上述错误。您的 EA 示例也是如此。

请确保您使用的是最新版本的库(本文所附的版本)。此外,如果您能在此附上 EA 的源代码,将大有帮助。

 
Enrico Lambino:

请确保您使用的是最新版本的库(本文所附的版本)。此外,如果您能在此附上 EA 的源代码,将大有帮助。


是的,我已经更新了本文所附的所有文件。但我不知道你是否又更新了一次。

您是否可以尝试使用您的示例 stops_ha_ma2,将 MM 更改为固定手数,并将手数更改为某个小值?

 
mbjen:

是的,我已经更新了本文附件中的所有文件。但我不知道您是否又更新了一次。

您能否尝试将您的示例 stops_ha_ma2 中的 MM 更改为固定手数,并将手数更改为某个小值?

能否在此发布出现问题的 EA 的源代码?我们的对话是公开的,您上面发布的错误对于 EA 而言是一个严重的问题。我希望其他读者也能从这次对话中学习,让他们有机会测试您的代码。
 
Enrico Lambino:
您能在这里发布出现问题的 EA 的源代码吗?我们的对话是公开的,您在上面发布的错误对于 EA 来说是一个严重的问题。我希望其他读者也能从这次对话中吸取教训,让他们有机会测试您的代码。

这与我的 EA 无关,因为我在使用你的 EA 时也遇到了同样的错误。无论如何,我已经将它安装到另一个终端副本中,现在看起来很好。不再出错了。也许是我的标准库 或其他方面出了问题......

谢谢。

 
mbjen:

这与我的 EA 无关,因为你的 EA 也出现了同样的错误。无论如何,我已经将它安装到另一个终端副本中,现在看起来很好。不再出错了。也许是我的标准库 或其他方面出了问题......

我的 EA 是根据其中一个示例 EA 的部分内容修改而成的。我起初想知道你的代码出了什么问题。但既然你说现在没有错误了,我也不太确定是什么原因导致了你遇到的问题。如果您再次遇到这个问题,请在这里或通过邮件告诉我。
 

恩里科,你好、


在 ExpertAdvisorBase 中,时间函数 为,而应如下所示;

datetime CExpertAdvisorBase::Time(const int index=0)
  {
   if(index>=0)
     {
      double time[];
      if(CopyTime(m_symbol_name,m_period,index,1,time)>0)
         return(time[0]);
     }
   return(-1);
  }

上面的时间类型是 double 而不是 datetime。

datetime CExpertAdvisorBase::Time(const int index=0)
  {
   if(index>=0)
     {
      datetime time[];
      if(CopyTime(m_symbol_name,m_period,index,1,time)>0)
         return(time[0]);
     }
   return(-1);
  }

此外,TimesBase 的 Evaluate 函数没有传递默认值;

bool CTimesBase::Evaluate(datetime current) const

如果改为下面的值,则应该是;

bool CTimesBase::Evaluate(datetime current) const

在编译 Base\Order 文件夹时,文件会出现很多错误。

例如,下面 OrderBase 中的 CreateStops 函数;

void COrderBase::CreateStops(CStops *stops)
  {
   if(!CheckPointer(stops)) return;
   if(stops.Total()>0)
     {
      for(int i=0;i<stops.Total();i++)
        {
         CStop *stop=stops.At(i);
         if(CheckPointer(stop)==POINTER_INVALID) continue;
         m_order_stops.NewOrderStop(GetPointer(this),stop);
        }
     }
  }

抛出'operator='--没有一个重载可以应用到函数调用 OrderBase.mqh

'At'--预期对象指针 OrderBase.mqh

Base\Stop 也有同样的问题,即抛出大量与停止、类型等有关的错误。

感谢您的出色工作,Shep

 
嗨,谢泼、
Shephard Mukachi:

你好,恩里科、


在 ExpertAdvisorBase 中,时间函数 为,而应如下所示;

上面的时间类型是 double,而不是 datetime。

Shephard Mukachi:

你好,恩里科、


此外,TimesBase 的 Evaluate 函数不传递默认值;

如果改成下面的值,应该可以;

感谢您指出这些问题。我直到现在才注意到这一点。我将更新代码。

Shephard Mukachi

在编译 Base\Order 文件夹时,文件出现了很多错误。

例如,下面 OrderBase 中的 CreateStops 函数;

抛出'operator='--没有一个重载可以应用到函数调用 OrderBase.mqh

'At'--预期对象指针 OrderBase.mqh

Base\Stop 也有同样的问题,即抛出大量与停止、类型等有关的错误。

感谢您的辛勤工作,Shep

是的,我知道这个问题。这仍然是由于前向声明造成的。CStop 在其方法中需要 COrder 和 COrderStop 的实例。当您尝试编译 CStop 时也是如此。所有这些相互需要的类都应该一起编译。如果每个类都单独编译,就会出错。例如

class Object1
{
public:
   Object2 *m_object2;
   Object1(){}
  ~Object1(){}
};

class Object2
{
public:
   Object1 *m_object1;
   Object2(){}
  ~Object2(){}
};

This 将无法编译。您必须声明一个前向声明,这样编译器才能识别 object1 类中的类成员 m_object2:

class Object2;
class Object1
{
public:
   Object2 *m_object2;
   Object1(){}
  ~Object1(){}
};

class Object2
{
public:
   Object1 *m_object1;
   Object2(){}
  ~Object2(){}
};

如果 Object1 和 Object2 位于同一个文件中,则可以这样做。如果它们在两个不同的文件中,那么您需要在 Object1 的类文件中为 Object2 进行正向声明,在 Object2 的类文件中为 Object1 进行正向声明。在为这两个类中的任何一个添加方法之前,情况确实如此。

当前版本的编译器可以识别前向声明,但不能识别前向声明的类中列出的方法。这就是为什么你不会收到类似 "CStop - declaration without type"(CStop-无类型声明)的错误信息,而会收到编译器错误信息的原因,比如你上面发布的方法。编译器能识别类,但不能识别向前声明的类的方法。