文章 "开发多币种 EA 交易 (第 5 部分):可变仓位大小"

 

新文章 开发多币种 EA 交易 (第 5 部分):可变仓位大小已发布:

在前面的部分中,我们正在开发的智能交易系统 (EA) 只能使用固定的仓位大小进行交易。这对于测试来说是可以接受的,但在真实账户交易时并不建议这样做。让我们能够使用可变的仓位大小进行交易。

在上一部分中,我们添加了重启后恢复 EA 状态的功能。无论原因是什么 - 重新启动终端、使用 EA 更改图表上的时间框架、启动较新版本的 EA - 在所有情况下,恢复状态都允许 EA 不从头开始工作并且不会丢失已经打开的仓位,而是继续处理它们。

然而,在整个测试期间,该策略的每个实例的开仓大小保持不变。其大小是在 EA 启动时设定的。如果由于 EA 的运行,交易账户余额增加了,那么这将允许使用增加的仓位大小而不会增加风险。利用这一点是合理的,所以让我们开始实现使用可变仓位大小。

作者:Yuriy Bykov

 

当我使用 (3+3+3) 和缩放比例 2.18 运行 EA SimpleVolumesExpert 时,日志显示已打开虚拟交易,但在策略测试器中没有实际交易。我错过了什么吗?

 
Nigel Philip J Stephens #:

当我使用 (3+3+3) 和缩放比例 2.18 运行 SimpleVolumesExpert 时,日志显示了未结虚拟交易,但在策略测试器中没有实际交易。也许我遗漏了什么?

检查测试器中的初始余额是否达到或超过 10000 美元。当余额不够大时,就会出现这种情况。在这种情况下,并非每个虚拟仓位都会生成真实仓位。但原因可能是其他的,因为你的余额可能是正确的。

如果使用其他策略分组变量运行 EA,是否会出现真实交易?

 
我广泛阅读了您的文章,发现这正是我需要的知识。我很欣赏您对这一主题的详尽解释和深思熟虑的编码决定。谢谢。
 

下午好。感谢您的劳动。我对您的架构非常感兴趣,正在一步一步地理解。我只更改了策略类--我使用自己的策略类。但在现阶段,我在扩展策略方面遇到了困难。为了实验的纯粹性,我使用了该策略的一个实例和缩放乘数_ 1 和 2 的两个变量(fixedBalance_ = 0;)。在这两种情况下,结果都是一样的--手数没有变化。代码中决定手数的位置

//+------------------------------------------------------------------+
//| 确定虚拟位置的实际大小
//+------------------------------------------------------------------+
double CMoney::Volume(CVirtualOrder *p_order) {
   // 申请该虚拟仓位的标准化策略平衡 
   double fittedBalance = p_order.FittedBalance();
   
   // 如果等于 0,则实际卷等于虚拟卷
   if(fittedBalance == 0.0) {
      return p_order.Volume();
   }
   
   // 否则,我们将得出贸易总余额的值
   double totalBalance = s_fixedBalance > 0 ? s_fixedBalance : AccountInfoDouble(ACCOUNT_BALANCE);
   
   // 用虚拟体积返回计算出的实际体积
   return p_order.Volume() * totalBalance * s_depoPart / fittedBalance ;
}
//+------------------------------------------------------------------+

然而,参数 m_fittedBalance 和 m_fixedLot 是在虚拟策略构造函数中默认设置的。

//+------------------------------------------------------------------+
//| 构造函数|
//+------------------------------------------------------------------+
CVirtualStrategy::CVirtualStrategy(double p_fittedBalance = 0,
                                   double p_fixedLot = 0.01) :
   m_fittedBalance(p_fittedBalance),
   m_fixedLot(p_fixedLot) {}

因此手数不会改变。

// 如果等于 0,则实际卷等于虚拟卷
   if(fittedBalance == 0.0) {
      return p_order.Volume();
   }

虽然从逻辑上讲它应该缩放。请告诉我原因何在? 我不想干涉自己的编辑 - 以免破坏它,而且我已经在 CVirtualOrder 类中添加了一些方法,因为我的策略提供了部分平仓、止损和在计数器信号上平仓的功能。

 

您好。

一切都正确,对于可变手数交易,有必要为策略实例赋予 m_fittedBalance > 0 的值。将此参数传递给继承者后,继承者会将其代入 CVirtualStrategy 构造函数的调用中:

class CSimpleVolumesStrategy : public CVirtualStrategy {
...

public:
   //--- 公共方法
   CSimpleVolumesStrategy(
      string           p_symbol,
      ENUM_TIMEFRAMES  p_timeframe,
      int              p_signalPeriod,
      double           p_signalDeviation,
      double           p_signaAddlDeviation,
      int              p_openDistance,
      double           p_stopLevel,
      double           p_takeLevel,
      int              p_ordersExpiration,
      int              p_maxCountOfOrders,
      double           p_fittedBalance = 0
   );                                     // 构造函数

   ...
};

...

//+------------------------------------------------------------------+
//| 构造函数|
//+------------------------------------------------------------------+
CSimpleVolumesStrategy::CSimpleVolumesStrategy(
   string           p_symbol,
   ENUM_TIMEFRAMES  p_timeframe,
   ...
   int              p_maxCountOfOrders,
   double           p_fittedBalance = 0) :
// 初始化列表
   CVirtualStrategy(p_fittedBalance, 0.01),
   m_symbol(p_symbol),
   m_timeframe(p_timeframe),
   ...
}

在创建实例时,我们会为最后一个参数指定一个特定值,这样就不会将默认值 0 代入其中:

//+------------------------------------------------------------------+
//| 专家初始化函数|
//+------------------------------------------------------------------+
int OnInit() {
   // 在资本管理类中设置参数
   CMoney::DepoPart(expectedDrawdown_ / 10.0);
   CMoney::FixedBalance(fixedBalance_);

   // 创建使用虚拟仓位的智能交易系统
   expert = new CVirtualAdvisor(magic_, "SimpleVolumes_" + EnumToString(group_));

   // 创建并填充包含所有策略实例的数组
   CVirtualStrategy *strategies[] = {
      new CSimpleVolumesStrategy("EURGBP", PERIOD_H1,  13, 0.3, 1.0, 0, 10500,  465,  1000, 3, 1600),
      new CSimpleVolumesStrategy("EURGBP", PERIOD_H1,  17, 1.7, 0.5, 0, 16500,  220,  1000, 3,  900),
      new CSimpleVolumesStrategy("EURGBP", PERIOD_H1,  51, 0.5, 1.1, 0, 19500,  370, 22000, 3, 1600),

     ...
   };

   ...

   return(INIT_SUCCEEDED);
}

在 SimpleVolumesExpertSingle.mq5 Expert Advisor 中,我们不这样做,因为优化只在固定的初始位置大小上进行。请注意,m_fixedLot 参数不必在策略中专门用作所有未结虚拟头寸的大小。它只是一个基础值,我们可以根据它计算其他参数。在文章中的模型策略中,只需所有仓位的大小相同,就可以不加转换地使用该参数。但这并不妨碍您在另一个策略中开立大小为 10*m_fixedLot 的虚拟仓位,然后应用其逐步平仓。

 
Yuriy Bykov #:

你好

一切都正确,对于可变手数交易,有必要为策略实例赋予 m_fittedBalance > 0 的值。将该参数传递给继承者后,继承者会将其代入 CVirtualStrategy 构造函数的调用中:

在创建实例时,我们会为最后一个参数指定一个特定值,这样就不会将默认值 0 代入其中:

在 SimpleVolumesExpertSingle.mq5 Expert Advisor 中,我们不这样做,因为优化只在固定的初始位置大小上进行。请注意,m_fixedLot 参数不必在策略中专门用作所有未结虚拟头寸的大小。它只是一个基础值,我们可以根据它计算其他参数。在文章中的模型策略中,所有仓位的大小都是一样的,使用该参数时无需转换。但这并不妨碍您在另一个策略中开立规模为 10*m_fixedLot 的虚拟仓位,然后应用其逐步平仓。

您好。感谢您的快速回复。我想明白了。我没有立即意识到添加了最后一个参数,因为我使用的是自己的策略类,它的参数集略有不同。