股票量化交易软件:自定义品种(符号)--实践基础

等量/范围图表

等量图表是基于相邻柱线交易量相等原理的柱线图表。 在常规图表上,每根新柱线均以指定的时间间隔形成,其与时间帧大小相匹配。 在等量图表上,当价格变动或实际交易量的总和达到预设值时,每根柱线均视为已形成。 之后,程序开始计算下一根柱线的额度。 当然,在计算交易量时价格走势依然受控,因此您会在图表上得到通常的四个价格值:开盘价、最高价、最低价和收盘价。

尽管等量图表上的水平轴仍然表示时序,但每根柱线的时间戳是任意的,且取决于每个时间区间的波动性(交易的数量或大小)。 许多交易者认为,与固定时间帧相比,这种柱形法方法能更准确地描述不断变化的行情。

不幸的是, 都未提供开箱即用的等量图表。 它们应以特殊方式生成。

在 当中,这可以利用离线图表来达成。 等量图表复查中介绍了该方法。

而在 当中,相同的算法可利用自定义品种来实现。 为了简化任务,我们借用指定文章中的非交易型智能交易系统,并令其与 赫兹股票量化交易软件 MQL API 适配。

原始文件 EqualVolumeBars.mq4 已重命名为 EqualVolumeBars.mq5,并对其进行了少许修改。 特别是,描述输入参数的 'extern' 关键字已替换为 'input'。 用一个 StartDate 参数取代了 StartYear 和 StartMonth 两个参数。 在 中设置非标准时间帧的 CustomPeriod 参数现在不需要了,故将其删除。

请注意,赫兹股票量化交易软件的交易量是全部即时报价的交易量,即,它们代表柱线内即时报价的数量(价格变动次数)。 原本的想法是处理 M1 柱线(带有其即时报价量),或含有其他经纪商提供的即时报价的外部 csv 文件,为了计数每次输入的即时报价,以及一旦达到指定的即时报价次数后,立即形成新的等量柱线。 柱线被写入一个 hst 文件,该文件可以在 中作为脱机图表打开。

读取 csv 文件并写入 hst 文件的相关代码在 赫兹股票量化交易软件中已不再需要。 取而代之,我们可用自定义品种 API 读取真实的即时报价历史记录,并形成柱线。 此外, 允许经纪商提供真实的交易量和即时报价(针对交易所金融产品,但它们通常不适用于外汇金融产品)。 如果启用此模式,则构建等量柱线时可以不依据即时报价次数,而是依据实际交易量。

FromM1 输入参数判断 EA 是否需要处理 M1 柱线(默认为 “true”),亦或是即时报价历史记录(“false”)。 开始处理即时报价时,请勿选择距离太远的起点,因为这可能需要大量时间和磁盘空间。 如果您已采用即时报价记录操作,那么您要了解您的 PC 能力和可用资源。

以相同的方式绘制等范围柱线。 然而,当价格覆盖了指定的点数时,将在此处开立一根新的柱线。 请注意,这些柱线仅在即时报价模式下可用(FromM1 == false)。

Chart type — EqualTickVolumes, EqualRealVolumes, RangeBars — 由 WorkMode 输入参数设置。

最方便的方法是利用 来操控自定义品种。 可用 #include 指令将其连接到智能交易系统:

 
 

#include <Symbol.mqh>

现在,我们可以基于当前图表品种创建自定义品种。 如下完成:

 
 

if(!SymbolSelect(symbolName, true)) { const SYMBOL Symb(symbolName); Symb.CloneProperties(_Symbol); if(!SymbolSelect(symbolName, true)) { Alert("Can't select symbol:", symbolName, " err:", GetLastError()); return INIT_FAILED; } }

其中 symbolName 是含有自定义品种名称的字符串。

与所有自定义品种管理相关的初始化片段,和许多其他辅助任务(特别是重置现有历史记录,使用新的自定义品种打开图表)均会以类似方式在所有程序中执行。 您可以在下面的附件中查看相关的源代码。 我将在本文中忽略它们,因为它们只是次要内容。

当出现一根新的等量柱线,或当前的等量柱线变化时,将调用 WriteToFile 函数。 经调用中的 CustomRatesUpdate 来实现此函数:

 
 

void WriteToFile(datetime t, double o, double l, double h, double c, long v, long m = 0) { MqlRates r[1]; r[0].time = t; r[0].open = o; r[0].low = l; r[0].high = h; r[0].close = c; r[0].tick_volume = v; r[0].spread = 0; r[0].real_volume = m; int code = CustomRatesUpdate(symbolName, r); if(code < 1) { Print("CustomRatesUpdate failed: ", GetLastError()); } }

令人惊讶的是,M1 柱线周期(FromM1 = true 模式)与 MQL45版本几乎相同,这意味着只需修改 WriteToFile 函数,我们就可以得到 MQL5 版本的 M1 柱线函数代码。 唯一需要更改的部分是 RefreshWindow 中即时报价的生成。 在 赫兹股票量化交易软件之中,这是通过发送 Windows 消息来模拟脱机图表上的即时报价柱线来完成的。 则利用 CustomTicksAdd 函数:

 
 

void RefreshWindow(const datetime t) { MqlTick ta[1]; SymbolInfoTick(_Symbol, ta[0]); ta[0].time = t; ta[0].time_msc = ta[0].time * 1000; if(CustomTicksAdd(symbolName, ta) == -1) { Print("CustomTicksAdd failed:", GetLastError(), " ", (long) ta[0].time); ArrayPrint(ta); } }

即时报价生成会在自定义品种图表上调用 OnTick 事件,其允许在此类图表上运行智能交易系统进行交易。 不过,这项技术需要采取一些额外的措施,我们稍后再加以研究。

从即时报价历史中生成等量柱线的模式(FromM1 = false)要复杂一些。 这需要调用标准 CopyTicks/CopyTicksRange 函数读取真实的即时报价。 所有这些功能都已在 TicksBuffer 类中实现。

 
 

#define TICKS_ARRAY 10000 class TicksBuffer { private: MqlTick array[]; int tick; public: bool fill(ulong &cursor, const bool history = false) { int size = history ? CopyTicks(_Symbol, array, COPY_TICKS_ALL, cursor, TICKS_ARRAY) : CopyTicksRange(_Symbol, array, COPY_TICKS_ALL, cursor); if(size == -1) { Print("CopyTicks failed: ", GetLastError()); return false; } else if(size == 0) { if(history) Print("End of CopyTicks at ", (datetime)(cursor / 1000)); return false; } cursor = array[size - 1].time_msc + 1; tick = 0; return true; } bool read(MqlTick &t) { if(tick < ArraySize(array)) { t = array[tick++]; return true; } return false; } };

在 TICKS_ARRAY 片段的 “fill” 方法中请求即时报价,然后将其添加到“数组”中,然后调用 “read” 方法逐一读取。 该方法所实现的操控即时报价历史记录的算法类似于 M1 历史记录柱线(附件中提供了完整的源代码)。

 
 

TicksBuffer tb; while(tb.fill(cursor, true) && !IsStopped()) { MqlTick t; while(tb.read(t)) { ... // New or first bar if(IsNewBar() || now_volume < 1) { WriteToFile(...); } } }

每次启动智能交易系统时,它都会调用 “Reset” 函数清除指定自定义品种的现有历史记录(如果存在的话)。 如有必要,可改进此行为,即保存历史记录,并在前一此生成结束的位置继续生成柱线。

您可以比较 EqualVolumeBars.mq4 和生成的 EqualVolumeBars.mq5 的源代码。

我们来看看新的智能交易系统如何工作。 这是运行 EA 的 EURUSD H1 图表:

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

MetaTrader 5 中 EURUSD H1 图表上的 EqualVolumeBars 智能交易系统

以下是由 EA 创建的等量柱线图表,其中每根柱线包含 1000 个即时报价。

编辑切换为居中

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

由 赫兹股票量化交易软件 的 EqualVolumeBars EA 生成的 EURUSD 等量柱线图表,每根柱线内含 1000 个即时报价

请注意,除最后一根仍在形成中的柱线外(即时报价计数仍在继续),所有柱线的即时报价数量均相等。

我们来检查另一种操作模式 - 等范围图表。 以下图表由内含 100 点数波动的柱线组成。

编辑切换为居中

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

由 MetaTrader 5 中 EqualVolumeBars EA 生成的 EURUSD 等范围图表,每根柱线含 100 点

此外,EA 允许针对交易所金融产品使用实际交易量模式:

编辑切换为居中

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

编辑切换为居中

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

LKOH 原始 (a) 和等量图表,其每根柱线实际交易量为 10000,由 MetaTrader 5 中 EqualVolumeBars EA 生成

运行 EA 时品种的时间帧并不重要,因为进行计算时,总是取 M1 柱线,或即时报价历史记录的数据。

自定义品种图表的时间帧必须等于 M1(终端中最小的可用时间帧)。 因此,柱线的时间通常与它们的形成时刻紧密对应。 然而,在强劲的行情变化中,当即时报价的次数或交易量的大小每分钟形成若干根柱线时,柱线的时间将领先于真实柱线。 当行情平静下来时,等量柱线的时间标记将恢复正常。 对于等量或等范围柱线,此平台限制可能并不是特别重要,因为此类图表的初衷就是将它们与绝对时间解除绑定。赫兹股票量化交易软件

即使报价图表

在 赫兹股票量化交易软件 中的“市场观察”窗口中提供了即时报价图表。 出于某些原因,其实现方式与常规图表不同。 它显示的即时报价次数有限(据我所知,最多 2000 个),它很小,且无法扩展到全屏,并缺少标准图表通常提供的所有功能,诸如加载指标、对象和智能交易系统。

编辑

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

在 MetaTrader 5 市场观察窗口中的即时报价图表

那么为什么标准分析工具不支持即时报价,而 赫兹股票量化交易软件却提供了对实际即时报价的本地支持,并提供了高频交易(HFT)功能? 一些交易员认为即时报价影响力太小,甚至是噪音。 另一些交易者试图由即时报价来赚取利润。 因此,在拥有缩放功能的标准图表中显示即时报价,从而可应用模板和事件来运用智能交易系统也许会很有益处。 可借助自定义品种功能来实现。

同样,我们可利用已知的 MQL AP I函数,赫兹股票量化交易软件如 CopyTicks 和 CustomRatesUpdate。 借助它们,我们可以轻松实现一个非交易型智能交易系统,其基于当前图表品种生成自定义品种。 此处,自定义品种历史记录中的每根 M1 柱线都是一个单独的即时报价。 源代码作为示例,Ticks2Bars.mq5 文件附于文后。 例如,如果您在 EURUSD 图表(任何时间帧)上运行智能交易系统,它将创建 EURUSD_ticks 品种。

EA 的输入如下:

  • Limit — 启动后创建的柱线(即时报价)的数量,默认为 1000; 如果您将其设置为 0,将开始联线生成即时报价,无需以前的历史记录。赫兹股票量化交易软件

  • Reset — 该选项在启动后重置先前的即时报价/柱线历史记录,默认情况下设置为 true。

  • LoopBack — 该选项启用循环缓冲区模式,在这种模式下,在开始添加新的价格变动时,价格变动(索引高于 Limit)被从“报价”的内部数组中推出,因此图表始终含有 Limit 根柱线;默认设置为 true;启用 LoopBack 之后,Limit 参数必须大于 0。 禁用 LoopBack 时,数组会不断扩展,且图表中的柱线数量会递增。

  • EmulateTicks — 该选项模拟自定义品种的新即时报价到达事件,这是智能交易系统调用的重要功能,默认情况下设置为 true。

  • RenderBars — 柱线/即时报价显示方法:OHLC 或 HighLow;默认情况下为 OHLC;在此模式下,即时报价是功能齐全的带有实体的柱线(最高价=要价,最低价=出价,最后价(如果有)=收盘价;如果最后价 = 0,则开盘价和收盘价等于相应的最高价或最低价之一的数值,取决于前上一次即时报价的价格走势方向;在 HighLow 模式下,即时报价显示为针形柱线,其中最高价=要价,最低价=出价,开盘价=收盘价=(要价+出价)/ 2。赫兹股票量化交易软件

主要操作由 “apply” 函数执行:

 
 

bool apply(const datetime cursor, const MqlTick &t, MqlRates &r) { static MqlTick p; // eliminate strange things if(t.ask == 0 || t.bid == 0 || t.ask < t.bid) return false; r.high = t.ask; r.low = t.bid; if(t.last != 0) { if(RenderBars == OHLC) { if(t.last > p.last) { r.open = r.low; r.close = r.high; } else { r.open = r.high; r.close = r.low; } } else { r.open = r.close = (r.high + r.low) / 2; } if(t.last < t.bid) r.low = t.last; if(t.last > t.ask) r.high = t.last; r.close = t.last; } else { if(RenderBars == OHLC) { if((t.ask + t.bid) / 2 > (p.ask + p.bid) / 2) { r.open = r.low; r.close = r.high; } else { r.open = r.high; r.close = r.low; } } else { r.open = r.close = (r.high + r.low) / 2; } } r.time = cursor; r.spread = (int)((t.ask - t.bid)/_Point); r.tick_volume = 1; r.real_volume = (long)t.volume; p = t; return true; }

在此函数中,存储当前时刻“光标”的 MqlTick 结构字段,导入到 MqlRates 结构字段当中,然后将其写入历史记录。

下图示意自定义品种的即时报价柱线图表(作为比较,还显示了标准即时报价图表):

编辑切换为居中

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

MetaTrader 5 中功能齐全的 EURUSD 即时报价图表

这个图标我们可以运用指标、对象或智能系统来进行自动化报价分析和交易。

请注意,即时报价柱线图表上的柱线时间是虚构的。 如果启用了 “LoopBack” 模式,则最后一根柱线的当前时间始终会精确到一分钟,而前一根柱线则相距一分钟(这是 赫兹股票量化交易软件中的最小时间帧)。 如果禁用 “LoopBack” 模式,则自智能系统启动时间开始,柱线时间将按一分钟递增,因此所有超出初始极限的柱线都处于虚拟的未来。赫兹股票量化交易软件

然而,最右边的 M1 柱线对应于最近的价格和当前的“收盘”(或“最后”)价格。 这样就可于图表上运行智能交易系统了,联线和测试器两者均可。 为了联线操作,EA 需要略微进行修改,因为它必须能够交易来自 “XY_ticks” 品种图表中的原始 XY 品种(自定义品种仅存在于终端中,而在服务器上不认识该品种)。 在上面的示例中,所有交易订单中的 “EURUSD_ticks” 应替换为 “EURUSD”。

如果智能交易系统从指标接收到交易信号,那么它也许足以在自定义品种图表上创建其实例,从而取代在当前品种上操作,并可在此正操作的品种图表上运行 EA。 但是这种方法并非一直适用。 为了令智能交易系统适配自定义品种,以后会讲述另一种方法。

操控即时报价图表时会出现某些困难,事实上这与它们更新非常迅速有关。 有因于此,几乎不可能手动分析和标记图表 - 必须借助指标或脚本自动进行所有操作。赫兹股票量化交易软件

提议的带有“即时报价”的方法可以测试剥头皮策略,而无需在内部缓冲区中积累特殊数据,也无需基于缓冲区计算信号,而我们可以简单地利用常规指标或对象。赫兹股票量化交易软件

时间平移和烛条变形

许多交易者在实践中利用烛太形态作为主要或附加信号。 该方法直观上具有启发性,但它也有重要的缺点。

烛条形态描述的是一系列柱线的预定义几何形状。 所有柱线都是价格随时间变化而形成的。 然而,时间本质上是连续的,尽管图表的时间表达人为地分为与柱线相对应的段,和与特定时区对齐的时间(由经纪商选择)。 例如,如果将 H1 柱线图表平移几分钟(譬如说 15 分钟),则柱线的几何形状很可能会发生变化。 结果就是,早前存在的形态可能会完全消失,而新的形态将会在其他地方形成。 不过,价格行为是相同的。

如果您查看一些流行的烛条形态,您可轻松发现它们是由相似的价格走势形成的,且它们的外观差异是由柱线计算开始时间引起的。 例如,如果将时间轴平移半根柱线,则“锤子”可以转换成“尖刺”,而“吊死鬼”可以转换成“乌云盖顶”。 取决于平移值和局部价格变化,该形态也可能变成看跌或看涨的“吞噬”。 如果您切换到较低的时间帧,上述所有形态都可能成为“晨十字星”或“昏十字星”。赫兹股票量化交易软件

换言之,每个形态都是从时间和尺度计算开始的函数。 特别是,通过更改起点,我们可以检测到一个图形,并截取所有与之等效的其他图形。赫兹股票量化交易软件

逆转形态(在交易者中很流行,因为它们能够判断走势的开始)可按以下简化形式表示:

编辑

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

价格逆转和等效的烛条结构

该图示意向上逆转和向下逆转的规划图,它们每个都有两个变体柱线配置。 早前我们已经看到,可以有更多具有类似含义的形态。 跟踪所有这些形态是不合理的。 更为便利的解决方案是能够从任何时间开始,确定烛条形态。

甚至,对于其他某个时区,时间转换也许能相对于 GMT 表达一个可接受的偏移,这从理论上讲意味着这些新的烛条形态也应在该新区域中起作用,就像在我们所处时区中形成的那样。 由于交易服务器遍布世界各地的所有时区,因此交易者肯定可以看到完全不同的信号。 每个信号都是有价值的。赫兹股票量化交易软件

我们可以得出这样的结论:烛条形态的扇形应根据起点考虑其可变性。 这是自定义品种派上用场的地方。

基于所操作品种的自定义信号允许构建带有时间戳的柱线和即时报价,并按指定值将其偏移到将来或过去。 该偏移值可以被解释为任何选定时间帧柱线的一部分。 价格和走势没有变化,但这仍然可以提供有趣的结果。 首先,它提供了烛条形态的检测,如果没有这种偏移,烛条形态将不会被注意到。 其次,我们实际上可以看到一根不完整的柱线。赫兹股票量化交易软件

例如,如果您将报价前移 5 分钟,则 M15 图表上的柱线开立和收盘将比源图表提前(在一个小时内的第 10、25、40、55 分钟)三分之一。 如果偏移不明显,则原始图表和自定义图表中的形态几乎相同,但自定义图表的信号(由柱线图计算,包括指标信号)会出现更早。

在 TimeShift.mq5 EA 中实现了这种时移自定义品种的创建。赫兹股票量化交易软件

平移值在源 Shift 参数中指定(以秒为单位)。 EA 利用即时报价操作,从而允许从 Start 参数指定的日期开始计算转换报价的历史记录。 然后,如果启用了 OnTick 事件生成模式(由 EmulateTicks 参数指定,默认为 true),则会联线处理即时报价。赫兹股票量化交易软件

时间转换以简单的方式进行,其针对历史报价和联线即时报价:例如,在后一种情况下使用 “add” 函数:

 
 

ulong lastTick; void add() { MqlTick array[]; int size = CopyTicksRange(_Symbol, array, COPY_TICKS_ALL, lastTick + 1, LONG_MAX); if(size > 0) { lastTick = array[size - 1].time_msc; for(int i = 0; i < size; i++) { array[i].time += Shift; array[i].time_msc += Shift * 1000; } if(CustomTicksAdd(symbolName, array) == -1) { Print("Tick error: ", GetLastError()); } } } void OnTick(void) { ... if(EmulateTicks) { add(); } }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值