文章 "跨平台智能交易系统: CExpertAdvisor 和 CExpertAdvisors 类"

 

新文章 跨平台智能交易系统: CExpertAdvisor 和 CExpertAdvisors 类已发布:

本文主要介绍 CExpertAdvisor 和 CExpertAdvisors 类, 它们是本系列文章中所述跨平台智能交易系统里用到的所有组件的容器。

CExpertAdvisor 的 OnTick 方法是该类中最常用的函数。大部分发生的动作出自这个方法。该方法的核心操作如下图所示:


CExpertAdvisorBase OnTick

作者:Enrico Lambino

 

你好,恩里科。看起来你已经完成了你的项目。我刚刚看了你的上一篇文章,发现了一个我认为可能是错误的地方:

bool CExpertAdvisorBase::Init(string symbol,int period,int magic,bool every_tick=true,bool one_trade_per_candle=true,bool position_reverse=true)
  {
   m_symbol_name=symbol;
   CSymbolInfo *instrument;
   if((instrument=new CSymbolInfo)==NULL)
      return false;
   if(symbol==NULL) symbol=Symbol();
   if(!instrument.Name(symbol))
      return false;
   instrument.Refresh();
   m_symbol_man.Add(instrument);
   m_symbol_man.SetPrimary(m_symbol_name);
   m_period=(ENUM_TIMEFRAMES)period;
   m_every_tick=every_tick;
   m_order_man.Magic(magic);
   m_position_reverse=position_reverse;
   m_one_trade_per_candle=one_trade_per_candle;
   CCandle *candle=new CCandle();
   candle.Init(instrument,m_period);
   m_candle_man.Add(candle);
   Magic(magic);
   return false;
  }

我在上面用橙色标出了这个错误。我认为返回语句应该是 true 而不是 false。我正在重置我的电脑,因为感染了一个非常糟糕的病毒,这毁了我的一天,所以我决定读点东西。你的作品是论坛上最好的读物之一。你在这个项目中的表现非常出色,干得好。

我的想法与您的相似,我从您的作品中汲取了一些非常棒的想法,谢谢。等我完成后,我会花一些时间在这里与大家分享。

 
Shephard Mukachi:

你好,恩里科。看起来你已经完成了你的项目。我刚刚看了你的上一篇文章,发现了一个我认为可能是错误的地方:

我在上面用橙色标出了这个错误。我认为返回语句应该是 true 而不是 false。我正在重置我的电脑,因为感染了一个非常糟糕的病毒,这毁了我的一天,所以我决定读点东西。你的作品是论坛上最好的读物之一。你在这个项目中的表现非常出色,干得好。

我的想法与您的相似,我从您的作品中汲取了一些非常棒的想法,谢谢。等我完成后,我会花一些时间在这里与大家分享。

 

嗨,谢泼、

Shephard Mukachi:

你好,恩里科。看来你已经完成了你的项目。我刚刚看了你的上一篇文章,发现了一个我认为可能是错误的地方:

我在上面用橙色标出了这个错误。我认为返回语句应该是 true 而不是 false。我正在重置我的电脑,因为感染了一个非常糟糕的病毒,这毁了我的一天,所以我决定读点东西。你的作品是论坛上最好的读物之一。你在这个项目中的表现非常出色,干得好。

我的想法与您的相似,我从您的作品中汲取了一些非常棒的想法,谢谢。等我完成后,我会花一些时间在这里与大家分享。

很遗憾发生了这样的事,但还是要感谢您的反馈。是的,您说得对。我直到现在才注意到。我会改正的。示例中对 Init() 方法的调用没有经过检查,但我对程序库未来计划的一部分是使函数和方法调用更加正规(就像标准程序库 一样),同时提供一个 EA 模板,以便于编码。稍后,我将在代码库中上传库的最新版本,并公开该库。欢迎您提供更多反馈和拉取请求。

不客气,我期待着看到您的程序库。

 
Enrico Lambino:

你好,Shep、

很遗憾听到您的遭遇,但还是要感谢您的反馈。是的,您说得没错。我直到现在才注意到。我会改正的。示例中对 Init() 方法的调用没有经过检查,但我对程序库未来计划的一部分是使函数和方法的调用更加正式(就像标准程序库 一样),并提供一个 EA 模板以方便编码。稍后,我将在代码库中上传该库的最新版本,并公开该库。欢迎您提供更多反馈和拉取请求。

不客气,我期待着看到您的库。


你好,恩里科。我终于快要完成新系统的安装了。昨晚我挣扎了几个小时,因为我根本无法控制我的系统,不过现在差不多完成了。我正在用平板电脑浏览阅读。您的图书馆真是了不起。现在完成了,我可以看到完整的逻辑--哇!

我的想法是这样的

- EA 根据 Magic、Symbol 和 Timeframe 组合(使用 Watch Window)创建机器人列表(如 AI 实体)。

- 然后,人工智能实体进入一个技巧袋(信号 - MA、PSAR 等),并确定最佳信号或信号组合。这里的 "最佳 "是基于一个内部反向测试引擎,它可以对信号进行比较。

- 然后,人工智能会将信号添加到一个列表中,并以此为基础进行交易,如果需要,还会重新学习。

- 每个人工智能都有各自管理的止损、订单和头寸对象,并可以访问优化器(GA)对象进行学习。我曾想过使用效用理论来进行人工智能决策(类似于 MQL5 EA 系统中使用的加权),但我不喜欢这种随意性,因此我选择了通过虚拟交易来学习,让人工智能的行为几乎与真人无异。


我很难理解如何实现其中的一些想法,通过阅读您的文章以及论坛上的许多其他文章和书籍,我即将完成一个很酷的项目--反正我是这么认为的。

您提到的一个主要问题是序列化。由于实时订单或头寸不具备打开它的对象的所有属性,系统崩溃会使人工智能进入无效状态,留下大量无主交易。我想到了使用订单注释。因此,在发送订单时,创建一个包含时间框架、信号名称和信号设置的注释。但很快我就意识到,这样做很快就会变得笨重,而且容易出现执行问题。因此,写入文件似乎是唯一有意义的办法。


如果你有兴趣,我会告诉你我的进展。不过你的工作真的很棒,感谢你为这个项目付出的时间。


谢泼

 

嗨,谢泼、

Shephard Mukachi:

你好,恩里科。我终于快要完成新系统的安装了。昨晚我挣扎了好几个小时,因为我根本无法控制我的系统,不过现在差不多完成了。我正在用平板电脑浏览阅读。您的图书馆真是了不起。现在完成了,我可以看到完整的逻辑--哇!

我的想法是这样的

- EA 根据 Magic、Symbol 和 Timeframe 组合(使用 Watch Window)创建机器人列表(如 AI 实体)。

- 然后,人工智能实体进入一个技巧袋(信号 - MA、PSAR 等),并确定最佳信号或信号组合。这里的 "最佳 "是基于一个内部反向测试引擎,它可以对信号进行比较。

- 然后,人工智能会将信号添加到一个列表中,并以此为基础进行交易,如果需要,还会重新学习。

- 每个人工智能都有各自管理的止损、订单和头寸对象,并可以访问优化器(GA)对象进行学习。我曾想过使用效用理论来进行人工智能决策(类似于 MQL5 EA 系统中使用的加权),但我不喜欢这种随意性,所以我选择了通过虚拟交易来学习,让人工智能的行为几乎与真人无异。


我很难理解如何实现其中的一些想法,通过阅读您的文章以及论坛上的许多其他文章和书籍,我即将完成一个很酷的项目--反正我是这么认为的。

您提到的一个主要问题是序列化。由于实时订单或头寸不具备打开它的对象的所有属性,系统崩溃会使人工智能进入无效状态,留下大量无主交易。我想到了使用订单注释。因此,在发送订单时,创建一个包含时间框架、信号名称和信号设置的注释。但很快我就意识到,这样做很快就会变得笨重,而且容易出现执行问题。因此,写入文件似乎是唯一有意义的办法。


如果你有兴趣,我会告诉你我的进展。不过你的工作真的很棒,感谢你为这个项目付出的时间。


谢泼

这听起来是个有趣的项目。不过,这看起来是一个非常大的项目(可能比这个项目更大、更具挑战性)。请允许我分享一些我的想法,相信对你会有所帮助:

我以前写过一个回溯测试脚本。我设法让它在虚拟交易中按照我的要求运行,但如果将它用于实际的 EA(更不用说自我优化的 EA 了!),其性能会很慢。如果能以某种方式让其他 CPU 内核(甚至 GPU)也进行计算(即 DLL 或 OpenCL),您的工作可能会更成功。

机器人列表可以工作,但有一个重大缺陷:它们不是并行执行的。如果机器人数量只有几个到几个,这种滞后性还可以接受,但如果数量更多,排在最后的机器人就会被最后处理。而且这些交易还必须与 EA 执行实际工作所需的资源竞争。

虚拟交易可以建立很好的模型,但无法捕捉市场中的实际噪音(即新闻)。这一点我深有体会。

对于标准库 的 CSignal 类中使用的称重系统,我也有同样的想法。在我看来,如果将该系统放在优化器上,很容易造成过度拟合。我有一个使用市场评分模型(LMSR,但仍在努力改进库存风险)的做市商机器人。我认为这是一个很好的替代方案,因为买入信号和卖出信号(甚至是无信号)的权重都可以综合考虑,而且输出是以概率表示的。而且它的资源密集程度远低于深度学习。

保存到文件可能是目前保存易变数据的最佳选择。使用 GVs 是另一种方法,但它可能比使用订单注释更加混乱。此外,有些经纪商会在订单注释中插入其他代码(如二元期权),因此在我看来,这也不是一个很好的方法。另一种方法是将所有数据保存在一个字典对象上,这样就可以避免编写代码来实现大量的加载和保存方法,但也需要保存到磁盘上。但是,当用户想使用 EA 启动新会话时,就会出现一个大问题。这个问题必须手动解决(要么删除保存文件,要么指定一个新的保存文件名)。

在实现该库中的文件类时,我违反了一些 OOP 规则。我遇到过这样的问题:当文件句柄在方法和函数中传递时(即使使用 const 限定符),它的值会丢失(变成 INVALID_HANDLE)。我不确定现在是否还是这种情况,但我对当前的解决方案非常满意。老实说,在库中使用 CFile 后裔并不那么优雅,但它很有效,代码量也少得多。

一切顺利

恩里科

 

非常感谢你们的意见。我随时欢迎您的意见。

是的,你说得没错,这将是一个大项目,但愿不会比你的项目更大。不过,我喜欢编程,而且我实际上是一名金融分析师。我开始编程是迫不得已,因为我需要将一些更复杂的财务模型自动化。我只是有一种奇怪的能力,能想出疯狂、怪异的想法。如果我能像你一样编码就好了!

目前我正在研究字典和 List<T>。特别是 List<T>,它是共享对象列表的一种更简便的方法,也可用于绑定。字典则用于存储和序列化。我一直在尝试一些想法,以便让我的代码库更轻量化,同时也拥有一个快速、易于维护的系统,而且一旦放到 Chart 上,就可以摆脱束缚。你关于列表的观点非常有价值,所以这个想法可能不是很理想。

你说得很对,如果我不采用并行执行,处理渣滓的速度就会很慢。这也是我在测试中发现的问题之一。列表中的最后一个对象出现得太晚了,尤其是当市场波动非常大时,OnTick 甚至会在列表中的第一个对象被调用之前就被调用好几次。根据您的建议,我研究了 OpenCL 作为可能的解决方案。我必须投资定制系统。

虚拟交易确实是个好模型,在嘈杂的市场中可以完全抹掉你的账户。有一天,我惊慌失措地看着我的 EA 在新闻期间艰难地下单,更不用说平仓了。这就是交易的残酷现实,但我们必须尝试。

是的,我同意你的观点,即评分模型方法更好。LMSR 绝对是更优越的方法,尤其是考虑到每种工具的看涨和看跌走势都截然不同。概率加权法无疑能提高准确性。

对于自学习,是的,它的速度会相当慢。它只会在开始时用于设置人工智能代理,用适当的信号武装它们,然后在给定的时间间隔内使用,比如 5 分钟代理在日终使用,1 小时代理在周五使用。事实上,这就是你所说的虚拟培训的意义所在,它能让你赚到数十亿美元,但却让你在实际交易中赔得血本无归。因此,我的目标是找到既简单又快速的信号,这样我就不会损失太多的速度。我希望系统能剥头皮,比如在扣除点差和佣金后只剥几个点。这意味着交易必须是非常高概率的设置,比如最近 20 个交易日最低点的锤子线之类。

因为我想专注于剥头皮,所以我可能不需要过多地监控交易。代理只需检查 设置,然后用止损和止盈下单,止损后即可获利平仓。再说一遍,我还在试验。

我还有很多工作要做,要围绕信号尝试各种想法。当我找到效果非常好的方法时,我会与大家分享。

你确实打破了一些规则,但这不正是编程的魅力所在吗?你可以墨守成规,也可以完全陷入困境,感觉就像要翻墙一样,这太神奇了。有时,打破常规正是你取得进步所需要的。你的作品很棒,为此我非常敬佩你。恩里科 编程是一项艰苦的工作。顺利的时候感觉很好,不按计划进行的时候就会很痛苦。

非常感谢你的意见。我非常感激,一定会随时向您汇报。

再次感谢、

谢泼

 
Shephard Mukachi:

非常感谢您的意见。我随时欢迎您的意见。

是的,你说得没错,这将是一个大型项目,但愿不会比你的项目更大。不过,我喜欢编程,而且我实际上是一名金融分析师。我开始编程是迫不得已,因为我需要将一些更复杂的财务模型自动化。我只是有一种奇怪的能力,能想出疯狂、怪异的想法。如果我能像你一样编码就好了!

目前我正在研究字典和 List<T>。特别是 List<T>,它是共享对象列表的一种更简便的方法,也可用于绑定。字典则用于存储和序列化。我一直在尝试一些想法,以便让我的代码库更轻量化,同时也拥有一个快速、维护简便的系统,而且一旦放到 Chart 上,就可以放手不管了。你关于列表的观点非常有价值,所以这个想法可能不是很理想。

你说得很对,如果我不采用并行执行,处理渣滓的速度就会很慢。这也是我在测试中发现的问题之一。列表中的最后一个对象出现得太晚了,尤其是当市场波动非常大时,OnTick 甚至会在列表中的第一个对象被调用之前就被调用好几次。根据您的建议,我研究了 OpenCL 作为可能的解决方案。我必须投资定制系统。

虚拟交易确实是个好模型,在嘈杂的市场中可以完全抹掉你的账户。有一天,我惊慌失措地看着我的 EA 在新闻期间艰难地下单,更不用说平仓了。这就是交易的残酷现实,但我们必须尝试。

是的,我同意你的观点,即评分模型方法更好。LMSR 绝对是更优越的方法,尤其是考虑到每种工具的看涨和看跌走势都截然不同。概率加权法无疑能提高准确性。

对于自学习,是的,它的速度会相当慢。它只会在开始时用于设置人工智能代理,用适当的信号武装它们,然后在给定的时间间隔内使用,比如 5 分钟代理在日终使用,1 小时代理在周五使用。事实上,这就是你所说的虚拟培训的意义所在,它能让你赚到数十亿美元,但却让你在实际交易中赔得血本无归。因此,我的目标是找到既简单又快速的信号,这样我就不会损失太多的速度。我希望系统能剥头皮,比如在扣除点差和佣金后只剥几个点。这意味着交易必须是非常高概率的设置,比如最近 20 个交易日最低点的锤子线之类。

因为我想专注于剥头皮,所以我可能不需要过多地监控交易。代理只需检查设置,然后用止损和止盈下单,止损后即可获利平仓。再说一遍,我还在试验。

我还有很多工作要做,要围绕信号尝试各种想法。当我找到效果非常好的方法时,我会与大家分享。

你确实打破了一些规则,但这不正是编程的魅力所在吗?你可以墨守成规,也可以完全陷入困境,感觉就像要翻墙一样,这太神奇了。有时,打破常规正是你取得进步所需要的。你的作品很棒,为此我非常敬佩你。恩里科 编程是一项艰苦的工作。顺利的时候感觉很好,不按计划进行的时候就会很痛苦。

非常感谢你的意见。我非常感激,一定会随时向您汇报。

再次感谢、

谢泼

不客气,也感谢您的分享。另外,最近我在处理数据存储(具体来说,是动态创建的图形控件)时开始使用 Dictionary<T>。它使用 FNV1-a 作为散列函数,可以存储基元和对象指针(但不能存储结构体)。保存和加载部分尚未完成,但我将在完成后立即在 CodeBase 上与大家分享。如果为每个代理安排优化时间(而不是同时处理所有代理),我相信通过哈希值获取代理并在单独的线程上进行处理,也许能提高执行速度。为此,你需要一个字典对象或一些相关的数据结构。是的,如果你的目标是剥头皮,你确实需要尽可能快的速度。
 

你好,恩里科、

您知道如何根据触发交易的信号为订单/仓位添加特定注释吗?比方说,信号 1 起作用 - 注释 "信号 A",以此类推。

谢谢。

 

对我来说,这并不容易,因为我刚刚来到这里,但我感谢所有那些让我通过他们的知识取得进步的人。

 
MetaQuotes Software Corp.:

已发表文章跨平台交易顾问:CExpertAdvisor 和 CExpertAdvisors 类

作者:Enrico Lambino

我们做了大量工作。

非常感谢!