跳空缺口 - 是能够获利的策略还是五五开?(基础篇)
跳空缺口:能榨出利润还是纯赌大小
跳空缺口到底算不算可榨利的策略,还是说本质上就是五五开的赌大小?2018 年 12 月一篇面向 MT5 用户的实测把这个问题摆上了台面,当时原文在站内的基础阅读量约 4563、互动 12,说明这类价格行为话题在外汇/贵金属交易者里一直有硬需求。 作者先把范围框死:不盯单一品种,而是操作一组交易品种来做统计,避免样本偏差把偶然当规律。外汇与贵金属跳空常发生在周日晚间开盘与重大数据后,杠杆环境下风险极高,任何缺口策略都只能用概率语言描述。 数据收集环节依赖 CGraphic 做可视化,并调用系统“选择文本文件”对话框来载入历史缺口记录;随后在多个非当前品种上跑统计分析,看缺口回补率是否跨品种稳定。这类做法你今天开 MT5 就能复刻:导出 tick/bar 数据、自己筛跳空阈值。 结论层面原文没有给出“必赚”断言,只把缺口策略定位为可统计、但胜率随品种与时段漂移的现象。真要落地,先跑一组你常做的 XAUUSD 与 EURUSD 的周日缺口,看回补概率再谈仓位。
「D1跳空缺口的方向惯性检验」
在股票品种上,D1 周期出现的跳空缺口之后,价格延续缺口方向还是反向回填,是这篇文章要量化的问题。 我们关心两个频率:一是缺口出现后市场继续沿缺口方向运行的比例,二是缺口被完全回补的概率。 为减少人工筛选成本,品种文件通过系统 GetOpenFileName 的 DLL 函数弹出对话框选取,结果用自定义的 CGraphic 图表类直接绘制,方便肉眼核对分布。 外汇与贵金属同样存在跳空,但流动性断层更剧,相关统计结论迁移过去时风险偏高,仅可作参考而非依据。
◍ 挑股票而不是外汇做日线缺口研究
做 D1 级别的跳空缺口统计,股票比外汇更合适。股票每天只在固定时段交易,不是连续盘面,缺口出现频率明显更高;而且像 ABBV 这类标的上市历史长,能攒出足够的日线样本。期货虽然也有跳空,但主力合约生命周期往往只有三到六个月,拿来跑长周期历史回测根本不够看。 MetaEditor 5 里新建一个脚本 TestLoadHistory.mq5,把文档里同名的示例代码整段贴进去覆盖原内容,编译后它就会出现在终端导航器里。想查某个品种,就先打开对应图表并把周期切到 D1,从导航器拖脚本上去,参数里填品种名、选 D1、起始日期设 1970 年即可。 以 ABBV 为例,脚本跑完显示历史从 2015.09.18 起,一共加载了 758 根 D1 柱。这个样本量对日线缺口的规律挖掘已经够用,外汇品种大多没这么长的连续日线断点积累。 外汇与贵金属杠杆高、跳空常伴跳空滑点,实盘验证缺口策略前请先在 MT5 用脚本自测品种历史深度,避免拿不够长的数据硬凑结论。
TestLoadHistory(ABBV,D1) Start loadABBV,Dailyfrom1970.<span class="number">class="num">03.16</span> <span class="number">class="num">00</span>:<span class="number">class="num">00</span>:<span class="number">class="num">00</span> TestLoadHistory(ABBV,D1) Loaded OK TestLoadHistory(ABBV,D1) <span style="background-class="type">class="kw">color:rgb(class="num">255, class="num">235, class="num">85);">First date <span class="number">class="num">2015.09</span>.<span class="number">class="num">18</span> <span class="number">class="num">00</span>:<span class="number">class="num">00</span>:<span class="number">class="num">00</span></span> - <span style="background-class="type">class="kw">color:rgb(class="num">164, class="num">192, class="num">228);"><span class="number">class="num">758</span> bars</span>
按组抓取品种清单的脚本套路
在 MT5 里做跨品种统计,第一步是把某个品种组(比如 NASDAQ(SnP100))里的所有代码名落盘成文本。最省事的做法是:在组里随便开一个品种的图表,跑一个遍历品种树的脚本,它会自动把同组所有品种写进通用文件目录下的 txt,每行一个。 脚本核心逻辑分七步:先取当前图表的 SYMBOL_PATH,再用反斜杠拆路径,去掉末段(品种名)保留组路径;然后扫全部可用品种,路径前缀匹配的就收进数组;最后把数组写文件,文件名里的 / 和 \ 会被自动替换成下划线,例如 Stock Markets_USA_NYSE_NASDAQ(SnP100)_.txt。 判断脚本真跑通了,只看专家日志有没有出现 "Everything is fine. There are no errors. Create file: " 这一行,下一行就是可用文件名。拿这个文件名喂给后续的缺口统计脚本,就能跳过全市场扫描,直接读组文件算数据。外汇与贵金属品种同样适用此分组法,但杠杆与跳空风险高,落盘后务必人工核对品种数量。 下面这段是脚本头部与 OnStart 前几步的原文,已做关键行中文标注:
class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Symbols on symbol tree.mq5 | class=class="str">"cmt">//| Copyright © class="num">2018, Vladimir Karputov | class=class="str">"cmt">//| http://wmua.ru/slesar/ | class=class="str">"cmt">//+------------------------------------------------------------------+ class="macro">#class="kw">property copyright "Copyright © class="num">2018, Vladimir Karputov" class="macro">#class="kw">property link "http:class=class="str">"cmt">//wmua.ru/slesar/" class="macro">#class="kw">property version "class="num">1.000" class=class="str">"cmt">//--- class="macro">#include <Files\FileTxt.mqh> CFileTxt m_file_txt; class=class="str">"cmt">// 文本文件对象 class=class="str">"cmt">//--- class="type">class="kw">string m_file_name=""; class=class="str">"cmt">// 文件名 class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| 脚本程序起始函数 | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">void OnStart() { class=class="str">"cmt">//--- 第一步 class="type">class="kw">string current_path=""; if(!SymbolInfoString(Symbol(),SYMBOL_PATH,current_path)) { Print("ERROR: SYMBOL_PATH"); class="kw">return; } class=class="str">"cmt">//--- 第二步 class="type">class="kw">string sep_="\\"; class=class="str">"cmt">// 分隔符字符 class="type">class="kw">ushort u_sep_; class=class="str">"cmt">// 用于分隔字符的代码 class="type">class="kw">string result_[]; class=class="str">"cmt">// 用于取得字符串的数组 class=class="str">"cmt">//--- 取得分隔符代码 u_sep_=StringGetCharacter(sep_,class="num">0); class=class="str">"cmt">//--- 把字符串分成子字符串 class="type">int k_=StringSplit(current_path,u_sep_,result_); class=class="str">"cmt">//--- 第三步 class=class="str">"cmt">//--- 现在输出所有取得的字符串 if(k_>class="num">0) {