期货量化交易软件:开发回放系统市场模拟第 03 部分调整设置

本文讲述了如何在MQL5平台上实现市场回放的控制系统,通过创建简单的EA来控制服务的跳价,避免了外部DLL的使用,展示了利用平台内功能的可能性。作者逐步介绍了从规划到创建基本EA的过程,包括回放的控制、全局变量的使用以及EA对象的创建和操作。
摘要由CSDN通过智能技术生成

规划

这个规划步骤非常简单,因为如果您查看上一篇文章中系统的工作原理,就会很清楚我们需要做什么。 赫兹量化需要创建一个控制窗体,在其中我们可以暂停、播放,最重要的是,选择一个特定的时间来开始研究。

在当前视图中,我们将始终从第一次交易跳价开始。 假设我们想自市场的第五个小时开始研究,即从 14:00(假设市场在 9:00 开盘)。 在这种情况下,我们将不得不等待回放 5 个小时,然后才执行必要的分析。 这是完全不可能的,因为如果我们试图停止回放,它将关闭,我们将不得不从第一次交易跳价重新开始。

现在很清楚我们需要马上做什么,因为它现在的工作方式令人沮丧,即使这个想法本身很有趣。

现在我们有了大致的方向,我们就可以继续实现。

添加图片注释,不超过 140 字(可选)

实现

实现会非常有趣,因为我们将不得不经历从最简单到最多样化的不同路径,从而创建真正的控制系统。 不过,如果您仔细阅读解释,所有步骤都很容易理解,并按发布顺序遵循文章所说,无需跳过任何步骤,也无需尝试向前跨出若干步。

与许多人的想法相左,赫兹量化不会在系统中使用 DLL。 我们只使用纯 MQL5 语言实现回放系统。 这个思路是充分利用赫兹量化,并展示在创建必要功能时我们可以在平台内走多远。 求助于外部实现会剥夺使用 MQL5 的很多乐趣,给人的印象是 MQL5 无法满足我们的需求。

如果您查看上一篇文章中所用的代码,您可以看到系统使用服务来创建回放。 它还包括启动它的脚本。 此脚本允许服务发送自定义交易品种的跳价,从而创建回放。 我们用到了一个简单的切换机制。 然而,这种方法不适合更有效的控制。 我们必须走一条更困难的道路。

创建超基本 EA

赫兹量化来尝试利用 EA 实现控制。 该 EA 将控制服务何时应该或不应该为柱线生成跳价。 为什么是 EA? 我们可以使用指标替代 EA,其工作方式相同。 不过,我想使用 EA,因为我们稍后需要它来创建订单模拟系统。 此外,我们将尝试使用我在另一系列文章称为“从头开始开发交易 EA”中介绍的订单系统。 我们现在不必担心订单系统,因为在我们开始之前我们还有很多工作要做。

我们基本 EA 的完整代码如下所示:

 
 

#property copyright "Daniel Jose" #property version "1.00" //+------------------------------------------------------------------+ #include <Market Replay\C_Controls.mqh> //+------------------------------------------------------------------+ C_Controls Control; //+------------------------------------------------------------------+ int OnInit() { Control.Init(); return INIT_SUCCEEDED; } //+------------------------------------------------------------------+ void OnDeinit(const int reason) {} //+------------------------------------------------------------------+ void OnTick() {} //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { Control.DispatchMessage(id, lparam, dparam, sparam); } //+------------------------------------------------------------------+

代码非常简单,但足以控制服务的操作。 现在我们来看一下代码的某些部分,即上面高亮显示的控制对象类。 在开发的早期阶段,代码并不是很复杂。 我们只实现一个按钮来播放和暂停回放服务。 如此,我们来看看这个当前开发阶段的类。

首先要注意的,如下所示:

 
 

#property copyright "Daniel Jose" //+------------------------------------------------------------------+ #include <Market Replay\Interprocess.mqh> //+------------------------------------------------------------------+ #define def_ButtonPlay "Images\\Market Replay\\Play.bmp" #define def_ButtonPause "Images\\Market Replay\\Pause.bmp" #resource "\\" + def_ButtonPlay #resource "\\" + def_ButtonPause //+------------------------------------------------------------------+ #define def_PrefixObjectName "Market Replay _ "

第一个要点是 《蓝色高亮 的头文件。 赫兹量化稍后会详细查看它。 然后,我们有一些位图对象的定义,这些对象将表示播放和暂停按钮。 这里没有什么太复杂的。 一旦定义了这些要点,我们就能迈进类代码,它们非常紧凑。 完整代码如下所示。

 
 

class C_Controls { private : //+------------------------------------------------------------------+ string m_szBtnPlay; long m_id; //+------------------------------------------------------------------+ void CreateBtnPlayPause(long id) { m_szBtnPlay = def_PrefixObjectName + "Play"; ObjectCreate(id, m_szBtnPlay, OBJ_BITMAP_LABEL, 0, 0, 0); ObjectSetInteger(id, m_szBtnPlay, OBJPROP_XDISTANCE, 5); ObjectSetInteger(id, m_szBtnPlay, OBJPROP_YDISTANCE, 25); ObjectSetInteger(id, m_szBtnPlay, OBJPROP_STATE, false); ObjectSetString(id, m_szBtnPlay, OBJPROP_BMPFILE, 0, "::" + def_ButtonPause); ObjectSetString(id, m_szBtnPlay, OBJPROP_BMPFILE, 1, "::" + def_ButtonPlay); } //+------------------------------------------------------------------+ public : //+------------------------------------------------------------------+ C_Controls() { m_szBtnPlay = NULL; } //+------------------------------------------------------------------+ ~C_Controls() { ObjectDelete(ChartID(), m_szBtnPlay); } //+------------------------------------------------------------------+ void Init(void) { if (m_szBtnPlay != NULL) return; CreateBtnPlayPause(m_id = ChartID()); GlobalVariableTemp(def_GlobalVariableReplay); ChartRedraw(); } //+------------------------------------------------------------------+ void DispatchMessage(const int id, const long &lparam, const double &dparam, const string &sparam) { u_Interprocess Info; switch (id) { case CHARTEVENT_OBJECT_CLICK: if (sparam == m_szBtnPlay) { Info.s_Infos.isPlay = (bool) ObjectGetInteger(m_id, m_szBtnPlay, OBJPROP_STATE); GlobalVariableSet(def_GlobalVariableReplay, Info.Value); } break; } } //+------------------------------------------------------------------+ };

这里我们有两个主要函数:Init 和 DispatchMessage。它们在这个早期阶段实现 EA 操作所需的所有工作。 为了更好地解释其中的一些细节,我们来看看下面的这两个函数。 我们从 Init 开始。

 
 

void Init(void) { if (m_szBtnPlay != NULL) return; CreateBtnPlayPause(m_id = ChartID()); GlobalVariableTemp(def_GlobalVariableReplay); ChartRedraw(); }

调用 Init 时,它首先检查之前是否已创建控制元素。 如果这已经发生,那么它就返回。 这很重要,因为如果您更改图表周期,或进行任何需要 EA 重新加载图表的更改(这种情况经常发生),回放服务的状态将不会更改。 那么,如果服务正在运行,也就是说,如果它暂停了,就按原样继续;如果它正在运行,它将继续发送跳价。

如果是第一次调用,则创建主控制,目前只是播放和暂停按钮。 接下来,我们创建一个全局终端值,该值将用于 EA 和服务之间的通信。 此刻,赫兹量化只是创建一个变量,且不为其分配任何值。

=之后,我们必须在屏幕上应用对象。这很重要,因为如果不进行强制更新,EA 将被加载,但服务就会停止,如此令您认为系统崩溃了。 但事实上,我们将等待赫兹量化为我们更新图表,以便绘制对象,并运行市场回放。

您有没有注意到它是多么容易? 现在我们来看看 DispatchMessage 函数的代码,其在此阶段也非常简单。 下面是它的代码:

 
 

void DispatchMessage(const int id, const long &lparam, const double &dparam, const string &sparam) { u_Interprocess Info; switch (id) { case CHARTEVENT_OBJECT_CLICK: if (sparam == m_szBtnPlay) { Info.s_Infos.isPlay = (bool) ObjectGetInteger(m_id, m_szBtnPlay, OBJPROP_STATE); GlobalVariableSet(def_GlobalVariableReplay, Info.Value); } break; } }

赫兹量化利用赫兹量化 来管控一切。 我们使用 u_Interprocess 联合来设置全局终端值,从而检查位图按钮的状态。故此,我们调整终端全局变量,如此将其传递给负责创建回放的服务进程。

由此,赫兹量化将始终以暂停状态启动重播系统。 一旦 EA 及其所有对象加载到图表上,我们就可以随时播放它,或暂停市场回放。 这会令事情变得更加有趣。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值