文章 "开发多币种 EA 交易(第 3 部分):架构修改"

 

新文章 开发多币种 EA 交易(第 3 部分):架构修改已发布:

我们在开发多币种 EA 方面已经取得了一些进展,该 EA 有几个并行工作的策略。考虑到所积累的经验,让我们回顾一下我们解决方案的架构,并尝试在我们走得太远之前对其进行改进吧。

我们分配了一个 EA 对象(CAdvisor 类或其子类),它是交易策略对象(CStrategy 类或其子类)的聚合器。在 EA 运行开始时,OnInit() 处理函数中会发生以下情况:

  • 创建 EA 对象。
  • 创建交易策略对象并将其添加到 EA 的交易策略数组中。

在 OnTick() 事件处理函数中会发生以下情况:

  • 为 EA 对象调用 CAdvisor::Tick() 方法。
  • 此方法遍历所有策略,并调用它们的 CStrategy::Tick() 方法。
  • CStrategy::Tick() 中的策略执行所有必要操作,以打开和关闭市场仓位。

这可以用示意图来表示:

Fig. 1. Operation mode from the first article

这种模式的优势在于,只要拥有遵循某种交易策略的 EA 的源代码,就可以通过一些相对简单的操作,使 EA 与其他交易策略实例协同工作。

然而,主要的缺点很快就显现出来了:在组合多个策略时,我们必须或多或少地减少每个策略实例所开立仓位的大小。这可能导致某些甚至所有策略实例完全被排除在交易之外。由于公开市场仓位的最小规模是固定的,因此并行工作中包含的策略实例越多或初始存款越少,出现这种结果的可能性就越大。

作者:Yuriy Bykov

 
FOREACH(m_orders, if(m_orders[i].IsOpen()) { m_ordersTotal += 1; })

有时,内心的某种东西会刺激你这样写。

FOREACH(m_orders, m_ordersTotal += m_orders[i].IsOpen())
 
我还没有读完。但我的感觉是,悬而未决的工作(不是在 Tester 中)并不适合这个确实改进了很多的架构。
 

最好能添加一个开关策略的掩码,以考虑虚拟交易量(虚拟交易量的接收者)。

例如,您需要暂时关闭投资组合中的某些 TS:它将继续进行虚拟交易,但不会影响真实环境。同样,也可以反向开启。

 
我想不出有什么办法可以一开始就完善这个架构。现在只能这样做了。
//+------------------------------------------------------------------+
//|| 专家基础类|
//+------------------------------------------------------------------+
class CAdvisor {
protected:
   CStrategy         *m_strategies[];  // 交易策略阵列

但一定有地方可以嵌入类似的东西。

 CAdvisor *m_advisors[];  // 虚拟投资组合阵列

有自己的法师。

 
Оповещение получателя и стратегии должно происходить только при открытии или закрытии виртуальной позиции.

如果报价时段不在交易时段 内,即使在测试仪中也会遇到困难。

交易量同步成功的标志可以帮您解决这个问题。

 
//+------------------------------------------------------------------+
//| 虚拟订单和仓位类别
//+------------------------------------------------------------------+
class CVirtualOrder {
private:
//--- 静态字段 ...
   
//--- 相关收件人和策略对象
   CVirtualReceiver  *m_receiver;
   CVirtualStrategy  *m_strategy;

在虚拟订单中插入一个完全不同的实体是一个值得商榷的解决方案。

似乎在创建架构时,性能问题是并行解决的。我自己也有这样的罪过。


也许,不考虑性能而进行设计仍然是正确的。然后再考虑如何加快速度。

 
fxsaber #:
我还没有读完。但我有一种感觉,使用挂单(不在测试器中)并不适合这个改进了很多的架构。

我不使用真实挂单,似乎只需在虚拟挂单触发时打开市场头寸即可。我意识到,在实际交易中,由于滑点和重新报价,这可能会导致入市头寸不太准确。但在实践中,我还没有遇到过这种情况。下一部分将支持虚拟挂单。

如果您仍想使用真实挂单,原则上架构允许:您必须编写另一个 CVirtualSymbolReceiver 类的实现。目前的实现只是忽略虚拟挂单。

 
fxsaber #:

最好添加一个开/关策略掩码,以考虑到体积计量器(虚拟体积的接收者)。

例如,您需要暂时关闭投资组合中的某些 TS:它将继续进行虚拟交易,但不会影响真实环境。同样,也可以反向打开。

要实现这一点并不难,但在不使用它的情况下,您需要为每个策略制定明确的开/关标准。这是一项比较复杂的任务,我还没有接触过,也许以后也不会接触。

 
fxsaber #:

而且,一定会有一个类似于这样的功能。

CAdvisor *m_advisors[];  // 虚拟投资组合阵列

有自己的法师

目前还没有这方面的计划。合并到投资组合将在 CAdvisor 和 CStrategy 之间的中间层进行。目前已有一个解决方案草案,但在不断重构的过程中可能会发生很大变化。

 
fxsaber 交易时段 内,即使在测试仪中也会遇到困难。

交易量同步成功的标志可以帮您解决这个问题。

它似乎已经存在:

class CVirtualSymbolReceiver : public CReceiver {
  ...
   bool              m_isChanged;      // 虚拟职位的构成是否有任何变化

只有在每个符号成功打开所需的真实交易量时,才会重置该标志。