在“基于真实 tick 数据的每 tick 回测”模式下,回测不会在您看到的K线图上进行交易。它会逐条重放交易终端中保存的 tick 历史数据,并且每个止损单、每个挂单以及每个点差过滤条件均基于这些 tick 数据进行判定。 该工具会对该 tick 历史数据进行审核:它读取某个符号、列表或整个“市场观察”中最近几天的 tick 数据,并统计其中五类问题——不可能的报价、时间戳损坏、 价格反转幅度以点差中位数的倍数计的单 tick 反转、经纪商自有报价时段内的数据缺失,以及 tick 数据与 M1 K 线不一致的分钟区间。

五个“市场观察”符号,每个符号三天数据,于周日服务器时间02:51:02进行一次扫描,耗时1.3秒。 S pts 表示点数的中位点差,Rev≥10S 统计至少达到十个中位点差的单 tick 价格反转,Silence unexpl. 统计经纪商自身会话表无法解释的超过 60 秒的缺口,最后三列则是 tick 与 M1 K 线的一致性检查结果。 为适应页面布局,面板字体大小设为4;默认值为8。
问题
K线是一种汇总。它保留一分钟内的四个价格,并忽略了这些价格出现的顺序,因此,一个下跌了两美元又立即反弹的报价,在图表上充其量只会显示为一根影线——而当该分钟内的其余价格已经覆盖了该范围时,则根本不会显示任何内容。 测试程序无法识别K线。它只看到报价,而位于该波动范围内的止损单会被直接触发。
没有人会肉眼阅读报价 tick,因为数量实在太多:在终端下方测量的黄金代码中,每个交易日大约包含 300,000 个 tick。 因此,那些决定“真实 tick 回测”究竟是实测还是虚构的关键问题,通常无人问津。是否存在卖价低于买价的报价?时间是否会倒流?交易时段中是否存在完全没有 tick 的区间?指标所读取的 M1 K 线是否与回测工具实际交易的 tick 数据一致?
本工具能在两秒内针对五个交易品种和三天数据提出这些问题,并以计数、毫秒级时间戳和CSV数据行作为答案,而非质量百分比。
测量内容
在窗口[最后一个报价 - N天, 最后一个报价)内进行五项检查,两端均取整至分钟。窗口以该交易品种的最新报价结束,而非以实际时间结束,因此周日的运行将审核刚刚结束的当周最后几天。 以下每个定义均精确无误,每项检测结果都会连同其毫秒级时间戳写入 CSV 文件,因此报告内容可经重新计算验证,而非仅凭信任。
- 报价(K1)。 买价 <= 0 或卖价 <= 0 的报价;交叉 报价(卖价 < 买价);锁定 报价(卖价 == 买价)。锁定报价会被计数但不视为违规——某些数据源的报价确实会合法地出现重合。
- 时间戳(K2)。 time_msc 值早于前一 tick 的 tick(倒序);重复 tick,即 time_msc、买价和卖价均与前一 tick 相同;以及 time 字段值与 time_msc / 1000 不一致的 tick。
- 单 tick 反转(K3)。 在改变图表价格的 tick 序列中,当三个连续价格 p0、p1、p2 满足以下条件时,即形成反转:进入 p1 的价格变动与离开 p1 的价格变动符号相反,且 p2 最终落回至距 p0 价格变动幅度的四分之一范围内。 该幅度以点为单位,取两个变动中的较小值,并以 S 的倍数报告,S 是该符号在窗口内的中位点差:计数为 2、5、10 和 20 个点差,且每个至少为 InpReversalMult 个点差(默认 10)的反转均被视为一个发现。 因此,黄金的 10 个点差和 EURUSD 的 10 个点差是等同的。
- 静默期(K4)。 两个连续的报价点间隔超过 InpSilenceSeconds(默认 60)。 该工具会每分钟查询一次SymbolInfoSessionQuote以获取静默时段的信息及其最后1秒的数据:如果其中任何一个时间点落在报价时段之外,则该静默时段有合理解释(如每日休市、周末);如果所有时间点都在报价时段内,则该静默时段无法解释,并被视为一个发现。 完全没有交易时段记录的交易品种将被报告为“未分类”,绝不会被归类为“已解释”。
- 与M1K线对比的报价(K5)。 对于窗口内的每一分钟,该分钟内每个报价的最高和最低图表价格将与经纪商M1K线的最高价和最低价进行对比。 这里计算的是每个 tick,而不仅仅是导致价格变动的那几个:一分钟内的第一个 tick 通常只改变卖价,而其买价仍为该 K 线的开盘价。在开发此工具期间,仅统计导致价格变动的 tick 曾在欧元兑美元(EURUSD)某一天产生了 144 次错误不匹配;而统计每个 tick 则未产生任何错误。 一个下方没有 tick 的 M1 柱线即为异常情况——即策略测试器必须为该分钟“生成” tick;同样,存在 tick 但没有柱线的分钟,以及最高价或最低价与 InpBarTolPoints 偏差超过该值的分钟,也属于异常情况。
该工具会检查自身的运算结果,并为每个交易品种打印正反两方面的数据:异常情况的数量必须等于11个异常计数器的总和,且写入该交易品种异常情况文件的行数必须同时等于这两个数值。
测试示例
对一个Exness模拟终端(版本6230)中的五个市场观察符号,每个符号覆盖三天数据,于2026年10月4日服务器时间02:51进行了一次完整审计。 由于当天是周日,因此外汇和黄金的交易窗口以周五的最后一个报价结束,而周末照常交易的BTCUSD则以运行时刻结束。在1 297毫秒内读取了1 962 511个报价。
| 交易品种 | 交易时段(服务器时间) | 报价数 | S,点 | 反转 >= 2 S / 5 S / 10 S | 最大反转幅度,点 | 沉默时间 > 60 秒:有原因 / 无原因 | 无法解释的秒数(最长) | 带有报价的M1K柱 / 分钟 | M1 不匹配 | 发现 |
|---|---|---|---|---|---|---|---|---|---|---|
| XAUUSD | 09.29 20:57 - 10.02 20:57 | 907 660 | 168 | 532 / 16 / 3 | 2 400 | 3 / 0 | 0 | 4 134 / 4 134 | 0 | 3 |
| 欧元兑美元 | 09月29日 20:58 - 10月02日 20:58 | 177 962 | 6 | 13 / 2 / 0 | 58 | 0 / 6 | 1 514.073 (439.640) | 4 299 / 4 299 | 0 | 6 |
| 英镑兑美元 | 09.29 20:58 - 10.02 20:58 | 215 516 | 7 | 8月14日 | 75 | 0 / 4 | 1 602.183 (741.443) | 4 295 / 4 295 | 0 | 6 |
| 美元兑日元 | 09.29 20:58 - 10.02 20:58 | 321 026 | 7 | 124 / 23 / 0 | 67 | 0 / 11 | 1 397.153 (307.393) | 4 305 / 4 305 | 0 | 11 |
| BTCUSD | 10.01 02:51 - 10.04 02:51 | 340 347 | 700 | 34 / 0 / 0 | 3 084 | 0 / 0 | 0 | 4 320 / 4 320 | 0 | 0 |
其中大部分数据都是干净的。 在 1 962 511 个报价点中,没有等于或低于零的报价,没有交叉报价和锁定报价,没有倒退的报价点,没有重复的报价点,也没有两个时间字段不一致的报价点。 21 353 个 M1 K 线中的每一根下方都有 tick 数据,每分钟若有 tick 数据则对应一个 K 线,且该 K 线的最高价和最低价等于其 tick 数据中截至当前点的最高买价和最低买价。 在此服务器上,指标读取的K线与测试器回放的Tick数据在每个高点和低点上均一致。这一点值得了解,对于未经过测量的服务器,不应对此作出任何假设。
在该时间窗口的每个晚上,交易时段表与数据源都存在不一致。 对于EURUSD、GBPUSD和USDJPY,该经纪商声明周一至周四的报价时段为00:00至24:00。但Tick数据却显示了不同的情况。 在这三个交易日的晚上,每日滚动前最后一个报价点出现在20:59:52至20:59:58之间,而下一个报价点则出现在21:04:28至21:12:18之间: 这期间长达4.5至12.4分钟完全没有报价,而这段时间被该经纪商称为“开放时段”。 最长的是2026年10月1日的英镑兑美元(GBPUSD),持续741.443秒,从20:59:57.249持续至21:12:18.692。 美元兑日元在2026年09月29日滚动后呈现出第二种模式: 在21:15至21:29之间,该货币对曾七次出现持续略超过一分钟的静默期,每次时长分别为60.001至60.007秒,其十一项异常记录中有七项源自此处。 同一服务器上的黄金在20:58至22:00期间显示市场休市,因此其三次交接时段的静默期有合理解释,不属于交易信号。
凡是依赖交易时段表来判断市场是否开放的专家顾问,这一点都至关重要。 K线与报价数据一致——这几分钟内也没有M1 K线,因此回测会看到相同的缺口——但一个通过读取报价时段来决定何时行动的EA会认为市场在21:02仍在报价,而在上述九个交易品种的晚上中,市场实际上都没有在该时间点报价。
最大的反转均发生在美国数据发布之时。 所有五次反转(幅度均至少为十个中位点差——其中三次发生在XAUUSD上,两次发生在GBPUSD上)都发生在2026年9月30日和2026年10月2日服务器时间12:30后的八秒内。 交易终端自身的经济日历显示,这两天均在12:30发布了美国经济数据。其中规模最大的黄金反转,其时间误差仅为1毫秒内的3个点:
符号;状态;时间_毫秒;时间;值1;值2;详情 XAUUSD;反转;1790771407860;2026.09.30 12:30:07.860;2400;141;p0 4198.315 p1 4195.774 p2 4198.174 d1 -2541 d2 2400 S 168
买价下跌2.541后回升至2.400,最终收于起始价(value2)下方0.141处,且整个过程发生在同一毫秒内。这相当于14.3个中位价差。 在M1图表上无法察觉:12:30的K线区间为4192.325至4209.799,因此该K线未显示任何痕迹。 在真实 tick 数据测试中,此时位于 4195.774 至 4198.174 之间的卖出止损或止损单——例如跟随上涨趋势设置的追踪止损——会因这一 tick 而触发。

XAUUSD,围绕该波段最大反转点附近的29个连续报价,按到达顺序排列。三个时间戳为12:30:07.860的报价分别为4198.315、4195.774、4198.174。 其余26个点,时间跨度从12:30:07.610至12:30:08.663,属于快速但普通的新闻行情波动,幅度达7.7美元。这些数据源自通过MetaTrader 5自有MCP服务器读取的点数据,而非该工具的文件。
仅凭这些数据无法判断此类报价是错误报盘还是薄单中的真实交易,该工具也不会尝试做出判断。它所做的只是统计这些报价,将其与该交易品种自身的点差进行对比,并提供时间戳,以便您查明回测结果是否取决于其中少数几个报价。 其分布呈陡峭曲线:以黄金为例,有532次反转幅度至少为两个点差,16次至少为五个点差,3次至少为十个点差。
独立验证报告
上表中的每个计数都由一个与该工具代码完全独立的程序重新计算得出,该程序从该工具从未调用的接口获取 tick 数据和 K线数据。 一个 Python 脚本仅从 EA 的文件中读取时间窗口、符号点数和图表模式、四个阈值以及交易时段表,并通过 MetaTrader 5 内置的 MCP 服务器(get_chart_ticks_history、get_chart_history)自行提取原始 tick 数据和 M1 K 线。 随后,它应用上述定义并进行比较。
对于表格中的运行结果:读取了 1 962 511 个 tick,每个符号 31 个汇总字段,加上每个符号的 24 小时表格(每个符号 72 个单元格),未发现任何不匹配。 这 31 个字段包括 29 个计数器、结果文件的行数以及标识符。 两个故意植入的错误——一个计数器增加了 1,一个每小时 tick 计数增加了 1——均被报告出来。 有一个字段未被重新计数:时间字段的检查需要 MqlTick 的时间成员,而 MCP 行不包含该成员,因此其值为零完全取决于 EA 本身。此外,该脚本无法检查基于“收盘价”构建图表的符号;这五个符号均不属于此类。
脚本自身的定义通过针对13个手工生成的Tick的测试来验证,其中每个预期计数均在纸上推算过——包括一次重复、 一次49点的反转、一次 tick 顺序错乱、一次交叉报价和一次锁定报价、一次卖价为零的报价、两个交易时段内的静默期以及一次跨交易时段的静默期——外加一个两 tick 的特例,其中静默期的最后1秒落在交易时段之外。测试本身统计了45个断言。 EA是否应用了相同的谓词,是由真实数据的重新计数来验证的,而非依赖于该测试。
双方均确认的零报价仅为零。在本文所述的所有运行中,均未出现交叉报价、反向报价、重复报价或非正向报价,也未发生M1不匹配,因此这些分支虽已定义并被重新计数,但在该服务器上从未触发过。
使用方法
- 将其附加到任何图表上;除非 InpSymbols 列出了其他符号或为 *(市场观察),否则将审计该图表自身的符号。请阅读日志或面板。
- 将 InpDays 设置为涵盖您关注的回测时间段。该时间窗口始终以终端持有的最后一个 tick 结束。
- 首先查看无法解释的静默期,并查阅结果文件中的时间戳。每天在同一分钟重复出现的静默期,是服务器日程与交易时段表不一致所致;零星出现的静默期则值得对照您终端的连接日志进行核查。
- 先查看10个点差及以上幅度的反转情况,再观察2S和5S的计数以了解分布形态。如果策略的止损点位于价格附近几个点差范围内,请排除已标记的分钟后重新运行回测并进行对比。
- 任何M1级别的不匹配或M1级别K线中缺少报价的情况,都表明该分钟内回测工具与图表数据不一致,或者回测工具生成了虚假价格。此类情况应向经纪商咨询。
- 更换经纪商或服务器后请重新运行回测:报价点质量取决于特定终端在特定时间的历史数据,而非特定交易品种的属性。
输入参数
| 输入 | 默认 | 含义 |
|---|---|---|
| InpSymbols | "" | 符号:空 = 图表符号,* = 市场观察,否则为 CSV 列表 |
| InpDays | 3 | 要审核的报价历史天数(截至最后一个报价) |
| InpCheckQuotes | true | K1:非正值/交叉/锁定报价 |
| InpCheckTimes | true | K2:时间戳倒序、重复或不一致 |
| InpCheckReversals | true | K3:单 tick 价格反转(价格飙升) |
| InpReversalMult | 10.0 | K3:至少达到此中位数点差的旗形反转 |
| 输入反转回报率 | 0.25 | K3:回撤至起点的最大距离,占价格波动幅度的比例 |
| InpCheckSilences | true | K4:与报价时段相比,各 tick 之间的间隔 |
| InpSilenceSeconds | 60 | K4:静默指持续时间超过此值的间隔(单位:秒) |
| InpCheckBars | true | K5:将K线的高点/低点与M1K线进行比较 |
| InpBarTolPoints | 0 | K5:忽略不超过此点数的高/低价偏差 |
| InpChunkMinutes | 360 | 以该分钟数为单位分批读取时间戳 |
| InpMaxExamples | 5 | 日志:每次检查打印的示例结果数量 |
| InpWriteCsv | true | 写入摘要、会话、工时和检查结果的 CSV 文件 |
| InpShowPanel | true | 在图表上绘制结果表 |
| InpPanelCorner | 左上角 | 面板角 |
| InpPanelFontSize | 8 | 面板字体大小 |
| InpPanelX | 10 | 面板 X 偏移量,px |
| InpPanelY | 18 | 面板 Y 偏移量,px |
| InpRefreshMinutes | 0 | 每 N 分钟重新审核一次(0 表示仅审核一次) |
输出文件
所有文件均写入 MQL5\Files\TickIntegrityAuditor\ 目录,以分号分隔且包含标题行,文件名前缀为 <symbols>_<days>d_<chart id>,因此两个实例绝不会互相覆盖。
- <前缀>_<符号>_summary.csv — 每个符号一行:时间窗口(以毫秒为单位)、上述所有计数器、使用的参数以及身份验证结果。已禁用的检查项会将单元格留空,而不是写入 0。
- <前缀>_<符号>_sessions.csv — 经纪商申报的报价时段,每行一个时段(工作日,起始时间至结束时间,单位为秒)。
- <前缀>_<符号>_hours.csv — 按服务器小时划分: tick 数、无法解释的静默及其持续时间(以秒为单位)、标记的反转。
- <前缀>_findings.csv — 每条发现记录占一行,包含符号、检查项、time_msc、可读时间、两个数值及文本详情。 对于反转,value1 表示其幅度,value2 表示回撤至 p0 的距离,均以点为单位;对于静默,value1 表示其持续时间(以秒为单位),value2 表示结束该静默的 tick 的 time_msc 值。
限制,直白说明
- 该工具审计您终端持有的 tick 数据。刷新或重新下载的历史记录可能会改变所有数值,而曾处于离线状态的终端会产生经纪商从未出现过的静默期。
- 交易会话表是经纪商自身的声明。所谓“已解释的静默期”,仅指经纪商曾声明该时段不会有报价;而“未解释的静默期”则是经纪商两份声明之间存在矛盾,并非故障的证据。
- 反转是一种模式,而非定论。该工具无法区分错误报价与真实交易;它仅测量成交量和时间,具体判断由您自行决定。
- 观察窗口限制为 InpDays 天(最多 365 天)。 tick 数据以块为单位读取,因此内存占用较小,但在交易活跃的标的上,较长的观察窗口所需时间会相应增加。
- 以“最后价格”绘制图表的交易品种将基于“最后价格”进行审计。由于该服务器上没有此类交易品种,因此该分支虽然已实现但从未运行,而独立重计仅涵盖以“买价”绘制图表的交易品种。
- 无交易功能、无 DLL、无网络访问:它读取 tick 数据、K 线和交易时段表,并将 CSV 文件写入 MQL5\Files 目录。
由MetaQuotes Ltd译自英文
原代码: https://www.mql5.com/en/code/78008
87.8 Percent from 2021 to YTD at 8.5 Percent MaxDD. The Nikkei EA That Only Buys When Volume Is Quiet
一款适用于M15周期的免费、完全开源的JPN225(日经225)自动交易策略。当价格呈上行趋势、动能未过度扩张且成交量清淡时买入。 2022年至2026年的回测结果:盈利因子1.68,年化收益率+18.5%,通过了15次压力测试。17:00前持平。
Session Sweep Boxes
绘制亚洲、伦敦和纽约交易时段的波动区间框,并标记流动性扫盘:即收盘价位于已结束交易时段高点或低点之外,但最终收盘价又回到了该区间内的K线。支持不重绘的箭头、扩展交易时段水平线、警报以及支持iCustom的缓冲区。