请观看如何免费下载自动交易
请在Telegram上找到我们!
加入我们粉丝页
有趣的脚本?
因此发布一个链接 -
让其他人评价
喜欢这个脚本? 在MetaTrader 5客户端尝试它
EA

Repaint Inspector - MetaTrader 5EA

Quoc Dat Quach
Quoc Dat Quach
Software engineer with 8 years in fintech and mobile, writing MQL4/MQL5 since 2017. I build Expert Advisors, indicators, trade and risk-management panels and utilities for MT4/MT5, and I trade forex and gold on MT5 myself.
| Chinese English Русский Español Deutsch 日本語 Português 한국어 Français Italiano Türkçe
显示:
12
等级:
(1)
已发布:
MQL5自由职业者 需要基于此代码的EA交易或指标吗?请在自由职业者服务中订购 进入自由职业者服务

用于检测指标是否会重新绘制,而不是仅凭其声明就予以采信。 该工具附着于图表,重新读取待测指标在已收盘K线 上的缓冲区数据,并统计其中出现的每处变化:数值变动、新出现的数值以及消失的数值——同时记录历史数据中仍发生此类变化的最远时间点。

repaint-inspector-zigzag-panel

示例:XAUUSD M1 图表上的 ZigZag(12,5,3)。该面板截图拍摄于运行 1 小时 25 分 12 秒时,即停止运行前 87 秒,因此下表中的总计数值略高。 截图中面板颜色设置为白底黑字;默认设置为深色面板上的浅色文字。

问题

“不重绘”是指标描述中最常见的宣传点,也是最难验证的一点。通常的测试方法是观察图表,大致记住箭头的位置,然后重新加载指标并再次查看。这种测试忽略了两种实际上会导致资金损失的情况。

第一种情况是,当图表保持打开状态时,某根已于一段时间前收盘的K线上的数值发生了变化。肉眼很难察觉:箭头可能只移动了几个像素,或者当注意力集中在图表右边缘时,箭头已被移除。

第二种情况是:指标在运行期间行为正常,但在重新加载后发布的历史数据却有所不同——这正是切换时间周期、终端重启或新建图表时用户会遇到的情况。

这两种情况都是可以测量的。我们需要的是某种机制,能够记录指标首次发布时的数据,并持续进行核对。

它所测量的内容

  • K线通过其开盘时间 来识别,绝非通过其偏移量,因此新K线、滚动和历史数据的刷新都不会被误认为是变化。
  • 仅对已收盘的K线进行比较,且仅限偏移量为1及以上的情况。根据定义,仍在形成中的K线会发生变化,这与重绘无关。
  • 已收盘K线的首次读数将成为基准。此后每次读数都会与前一次读数进行比较(以计数事件),并与首次读数进行比较(以测量漂移)。
  • 三种事件会分别计数,因为它们的严重程度不同:
    • 已更改— 某个值变为另一个值。
    • 出现— 空槽位获得了一个值,因此已在收盘的K线中产生了一个信号。
    • 消失——已发布的数值被清除。这是最严重的情况:交易者据此采取行动的信号,在后续读取者所见的历史数据中已不复存在。
  • 核心指标是MaxShift,即有史以来观察到的最大偏移量。仅重绘最后一个收盘K线的指标,与重写十五根K线历史数据的指标截然不同。
  • 每个事件都会被写入一个 CSV 文件,其中包含 K 线时间、缓冲区、检测时的偏移量以及新旧数值,因此报告可以被审计,而非仅凭信任。
  • 待测指标是通过 IndicatorCreate 函数基于解析后的参数列表生成的,因此无需编辑或重新编译任何内容,即可检查任何自定义指标。解析后的参数会在启动时打印到日志中,这样即使参数列表有误,也能被察觉,而非悄无声息地运行。
  • 可选地,每 N 分钟释放并重新创建指针句柄。记录的历史数据不会 被重置,因此运行过程还能捕获那些在存活期间保持静默、但在重新加载后发布不同历史数据的指标。
  • 当指标句柄尚未存在、指标尚未计算、已收盘K线数量少于要求的深度、无法复制缓冲区,或者在读取时间与读取值之间数据序列发生变动时,该次检查将被丢弃,并计为跳过而非有效数据。

其采样机制:若某个值存在的时间短于检查间隔,则可能被遗漏。这是实际存在的限制,下文将对此进行量化说明。

实测示例

下文中的所有内容均使用交易终端自带的指标,因此任何人都可以复现。

实盘案例:XAUUSD M1,1小时26分钟

在同一交易终端、同一数据源的四个图表上各运行一个副本,时间是2026年9月30日服务器时间02:19至03:46,观察了300根已收盘K线,每秒检查一次。

待测指标缓冲区对比已更改出现消失MaxShift结论
示例\ZigZag (12,5,3)01 315 713001715重绘
示例\ZigZag (12,5,3)11 315 7130031重绘
示例\ZigZag (12,5,3)21 315 71300103重新绘制
示例\自定义移动平均线 (13,0,2)01 305 513000-稳定
示例\分形,确认较晚01 303 71301303重绘
示例\分形,后期确认11 303 71301203重绘

分别进行了4387、4353和4347次检查,跳过了0/0/1次检查,0次重新同步,0次句柄重新加载。事件文件分别包含30、0和25行,这与每种情况下的三个事件列之和相等。

比较计数并非整数,也不应是整数:运行期间新开了 87 个 M1 柱,而刚刚打开的柱目前尚无已关闭柱的历史记录。对于每个实例,(检查次数 - 1) × 300 - 87 正好能精确还原报告的比较计数。

一张表中存在三种不同的特征:

  • ZigZag会删除自身的历史数据。 绘制中的ZigZag缓冲区中有17个值被清除,其中一个是在该K线收盘后15根K线处被清除的,另有13个值来自其后方的两个计算缓冲区。 没有任何变化:ZigZag的极值即为该K线的最高价或最低价,不会发生漂移,因此会被移除并发布到其他位置。这就是为什么事件会“消失”,而delta列保持为空。
  • 收盘柱的移动平均线不会移动。 1 305 513 次比较,未发生任何事件。
  • 分形是第三种情况,该工具将其与第一种情况区分开来。 共25个事件,全部为“出现”,无“更改”,无“消失”,均位于偏移量3处。 这并非重绘,而是延迟确认:绘制分形需要再等待两个K线,因此该值会在三个K线之前合法地出现并保持不变。判定列仍显示“重绘(REPAINTS)”,因为该工具仅报告其观察到的结果,而将判断权留给读者。 如果一个指标的所有事件都在一个固定的偏移量处“出现”,那么该指标可以利用这种内置的延迟;但如果一个指标的事件在分散的偏移量处“消失”,则无法利用这种延迟。

策略测试器,同一测量结果在十秒内

示例\ZigZag(12,5,3),XAUUSD M1,2026年09月28日至2026年09月29日,1分钟OHLC建模,观察300根收盘K线:

计数器值
结论重绘
检查5 512
已关闭柱状图的比较次数1 651 923
已更改 / 出现 / 消失0 / 3 / 342
丢失值的独立柱状图数量341
至少发生过一次事件的独立柱状图数量343
MaxShift28
跳过的检查/重新同步0 / 0
CSV行数345 (= 342 + 3)

在一个交易日内,ZigZag 删除了 342 个它此前已发布在当时已收盘的K线上的数值,其中一次删除发生在相关K线收盘后的第28根K线上。 有三个数值出现在已收盘的K线上。这三个数值中只有一个是数值回补:第17:06的K线损失了4126.184,二十秒后回补了完全相同的数值,随后又在一分钟后再次损失了该数值。 这也是为何该运行中 Max |delta| 的读数为 0.00000000 的原因;这是一种测量值,而非跳空。

repaint-inspector-zigzag-shifts

当天发生的345个事件按其被检测到的时段分类。大多数重绘发生在上一或前两根K线处,这就是为什么仅观察最后一根已收盘K线是不够的。

repaint-inspector-stable-panel

示例\自定义移动平均线(13,0,2),与上文ZigZag指标使用相同的符号和运行窗口:截图时共有1 291 114次比较,且未出现任何数值变化。 比较次数特意印在判定结果旁边——“稳定”的意义仅在于其旁边的数字。

“将 0.0 视为无值”会带来什么变化,以及采样间隙有多大

第四个副本在关闭该开关的情况下运行了相同的ZigZag,因此0.0被视为普通数值: 1 308 513 次比较,18 + 3 + 11 = 32 个事件,全部为“已更改”,MaxShift 仍为 15,主缓冲区中的 Max |delta| 为 4184.08800000。 该数值即为“黄金标准”,因为所谓的“变化”实际上是峰值被 0.0 取代。两种设置描述的是同一重绘过程;默认设置对其命名正确。

这两份副本所看到的列表并不完全相同,这一点值得注意。第四份副本记录了第一份副本遗漏的两个事件:缓冲区 0 和 2 上的 03:32:00 柱,于 03:33:01 被检测到。 这两个副本的启动时间相差14秒,且该值存在的时间不足一个检查间隔,因此其中一个副本采样到了该值,另一个则没有。在M1上,检查间隔为一秒,这就是该工具的分辨率。

repaint-inspector-delta-panel

相同的ZigZag读数若为0.0,也会被计为一个数值。现在每次删除操作都会显示为“已更改”,且其变化量等于价格大小。这作为交叉核对很有用,但作为描述则容易引起误解。

数据审计

计数器数据同样未被直接采信。通过将从交易终端获取的原始K线数据输入独立用Python重新实现的Examples\ZigZag程序,并将结果与事件文件进行比对:

  • 实时运行:在绘制缓冲区丢失值的17根K线中,每一根的该值均未出现在今天的回放中,且这17根K线中,工具的最后读数均与回放值相等。
  • 测试运行:343根包含事件的K线,采用相同的两项检查,未发现不匹配——341个丢失的值在回放中缺失,且343个最后读数中有343个与之相等。

输入

输入默认描述
要检查的指标(iCustom 路径,不带 .ex5;示例:Examples\ZigZag)空自定义指标相对于 MQL5\Indicators 的路径,不包含扩展名,必须完全符合 iCustom 的要求。 故意留空:若未填写任何内容,该工具会在日志和面板中提示此情况,且不会进行任何测量,而非指向终端上可能不存在的指标。如果在实时图表上路径错误,该工具会保持连接状态并每 30 秒重试一次,因此无需将其移除即可修正输入内容。 在 XAUUSD M1 图表上使用错误路径进行测试:该工具仅报告了一次错误代码,而交易终端在每次尝试时(间隔 30.4 秒和 30.7 秒)都会自行添加“无法加载”的提示,修正路径后,测量随即开始,且未解除任何连接。
参数,以逗号分隔(空值 = 指标默认值)空被测指标的输入列表,例如 12,5,3。每个项根据其内容进行类型转换:true 和 false 转换为 bool,包含小数点或指数的数字转换为 double,普通数字转换为 int,其他内容转换为字符串,且会去除周围的引号。 解析后的列表会在开始时打印到日志中,因此错误的列表会立即显现。为空表示指标将使用其自身的默认值运行。
要监视的缓冲区数量(1..32)1读取的缓冲区数量。计算缓冲区也计入其中。如果指标缺少某个缓冲区,将导致整个检查失败:这将被视为跳过检查,前几次发生的情况会连同错误代码一起写入日志,因此会显示出来,而非静默处理。
符号(为空表示图表符号)空在不打开其图表的情况下检查另一个符号上的指标。
时间周期当前在其他时间周期上查看指标。
已观察的收盘K线(偏移量 1..N)300检查深度。K线数乘以缓冲区数上限为 200 000 个槽位;超过该上限时,深度将被缩减,并向日志写入一行记录。
检查间隔的最小秒数,测试器中的模拟时间(0 = 每个 tick)1节流。一秒的间隔足以捕捉任何可能引发人工操作的画面重绘,且比每次时钟 tick 消耗的 CPU 资源少得多,但若某个值存在的时长短于该间隔,则可能被遗漏。在策略测试器中,使用的是模拟时钟而非实际时钟,因此该设置在此同样适用。
忽略小于此值的 |change|(0 = 计数每次变化)0.0以缓冲区为单位的绝对容差,适用于从浮点数重新计算且末位数字存在波动的指标。0 表示计数每次差异。小于该容差的变化将完全不予记录——不生成事件、不生成 CSV 行、也不计入 Max |delta|。
将 0.0 视为“无值”(箭头/锯齿风格缓冲区)true许多信号指标在“无信号”时会输出 0.0 而不是 EMPTY_VALUE。启用此选项后,0.0 将被视为空值,相关事件将报告为“出现”和“消失”。对于精确为零即为有效值的缓冲区,请关闭此选项。
每 N 分钟重建指标句柄(0 = 从不)0该设置将释放指标句柄并向终端请求新的句柄,这将触发全面重新计算,除非另有程序仍持有相同参数的该指标。记录的历史数据不会被清除,因此此设置可捕获运行期间稳定、但重新加载后发生变化的指标。
N 分钟后停止测量(0 = 运行直至被移除)0终止测量并冻结报告,这对于无人值守运行非常方便。
将每个事件写入 MQL5\Files 目录(CSV 格式)true事件文件。
CSV 文件名(留空 = 自动)留空自动生成的文件名由符号、时间周期和开始时间组成。如果当前已存在同名的文件(因为同一分钟内启动了另一个副本),则会添加数字后缀,而不是让该副本在没有文件的情况下运行。 同一分钟内先前运行产生的同名已关闭文件会被覆盖,因此当运行结果重要时,请自行指定文件名。
写入行数达到此值后停止100000防止指标在每个 tick 时重新绘制。达到限制后计数仍会继续;只是文件不再增长,日志中会有一行记录说明这一点。
在图表上显示报告面板true在无人值守或测试运行时将其关闭。
面板 X 方向距离(以 96 dpi 为单位的像素)12位置。面板会根据屏幕 dpi 进行缩放。
面板 Y 距离,96 dpi 下的像素数20位置。
字体大小,点(4点或以上;面板会根据屏幕DPI进行缩放)9该面板是一个采用等宽字体的表格。在高 dpi 屏幕或图表较小时,请降低其高度;上面的屏幕截图使用的是 4。
面板角左上角锚点角。
面板背景色深灰色面板颜色。与任何专家顾问一样,每个图表仅有一个副本;多个图表可同时运行多个副本。
面板边框颜色浅灰色
面板文字颜色浅灰色
当所有缓冲区均处于稳定状态时的标题颜色柠檬绿
缓冲区重绘时的标题颜色番茄红

报告

这是当上述实时ZigZag运行被停止时,该工具输出到日志中的摘要块,原文照录。图表中的面板显示了相同的表格,其中运行时间对齐于右侧:

=== 重绘检查器摘要 =====================================
重绘检查器   Examples\ZigZag (12,5,3)
XAUUSD M1   观察了 300 个已收盘柱   运行时间 01:26:39
检查 4 387   跳过 0   重新同步 0   处理重新加载 0
缓冲区  判定      比较次数    已更改   出现   消失   最大偏移    最大 |delta|
  0  重绘       1 315 713          0          0         17         15              -
  1  重绘       1 315 713          0          0          3          1              -
  2  重绘       1 315 713          0          0         10          3              -
CSV:RepaintInspector_XAUUSD_M1_20260930_0219.csv(30 行)
于 2026.09.30 02:19:31(服务器时间)开始,共执行 4387 次检查,0 次跳过,0 次重新同步,0 次处理重新加载
事件总数 30,CSV 行数 30
缓冲区 0:REPAINTS,比较次数 1315713,已更改 0,新出现 0,消失 17,涉及 K 线 17
缓冲区 0:最大偏移量 15(在 2026.09.30 02:59 的柱线上消失)
缓冲区 0:最大 |delta| 无
缓冲区 0:第一个事件 2026.09.30 02:23:02,最后一个事件 2026.09.30 03:46:03

位于 MQL5\Files 目录下的事件文件中,每个事件占一行:

检测时间;K线时间;检测时偏移量;缓冲区;事件;旧值;新值;变化量;与首个事件的漂移量;重新加载后
2026.09.28 17:11:20;2026.09.28 17:06:00;5;0;VANISHED;4126.18400000;EMPTY;;;0

空值写为EMPTY,未定义的差值留空,这样读者就不会将缺失的数值误认为零。 第二个文件 <name>_summary.csv 每行记录一个缓冲区,包含每个计数器以及指示器、其参数、符号、时间框架和深度,在运行期间每 15 秒刷新一次,因此无需解析日志即可从事件文件中重新计算这些数值。 当工具被移除时,日志会获取起始区块、前20个事件的完整记录以及上述摘要。

如何使用

  1. 将您要检查的指标放入 MQL5\Indicators 目录,并记下其参数列表。
  2. 将“重绘检查器”附加到您实际交易的符号和时间周期的图表上,填写路径和参数,并设置缓冲区数量。
  3. 让它在您交易的时间段内运行。重绘是市场活动的特性,而非时间因素,一个平静的周日傍晚并不能证明什么。
  4. 先阅读“MaxShift”,然后查看“Changed”、“Appeared”和“Vanished”之间的划分,接着打开 CSV 文件并查看几行数据。
  5. 如果指标通过了这一检验,将“重新加载”间隔设置为30分钟,并再次运行。

限制,直白地说

  • 该工具无法证明不存在回绘现象。它只能在测量期间内未能发现任何回绘,这就是为什么每个判定结果旁边都标有比较次数。
  • 它以检查间隔为单位进行采样。在单个间隔内出现并消失的数值可能会被遗漏,而上面的测量结果显示,这种情况在一小时半内发生了两次。
  • 它仅测量指标通过缓冲区发布的信号。对于那些直接在图表上绘制对象而非填充缓冲区的指标,该工具无法检测到。
  • 策略测试器在此处很有用,因为它将一天的时间压缩为几秒,但测试器中的重绘与实盘中的重绘并不一定相同。当结果至关重要时,请在实盘中运行。
  • 在策略测试器中,待测指标必须在运行开始前就已存在并编译完成。测试器将 IndicatorCreate 失败视为严重错误并卸载专家顾问,而工具内部的任何错误处理都无法改变这一结果: 若采用故意错误的路径进行测试,在 OnInit 中创建句柄会引发“指标创建错误”,随后出现“OnInit 严重错误”;而改在首次检查时创建,则会产生同样六条以“OnTester 严重错误”结尾的错误记录。 在实时图表上,相同的错误路径并不致命:工具保持连接并重试,修正后的路径随即开始就地测量。
  • 这与指标是否盈利毫无关系。一个不重绘的指标仍可能毫无用处,而某些重绘指标则是被有意且正确地使用的。
  • 无需交易功能、DLL、网络访问或外部文件。它读取缓冲区并将CSV文件写入MQL5\Files目录。

由MetaQuotes Ltd译自英文
原代码: https://www.mql5.com/en/code/77842

ATS Liquidity City - liquidity pools and sweeps, drawn as a neon city ATS Liquidity City - liquidity pools and sweeps, drawn as a neon city

显示止损位可能位于何处,以及哪些止损位刚刚被触发。流动性池 = 价格尚未突破的已确认震荡高点和低点、等价高点/低点(更大的池)以及昨日的高点和低点。 当K线突破某个价格池时,该池会被标记为“已被扫过”;若同一根K线收盘价回撤至该价格池内,则标记为“被触及并被拒绝”。不重绘:只有在价格在价格池两侧各收盘N根K线后,才将该波段视为有效。 该面板是一幅绘制在 CCanvas 上的霓虹城市:价格是一辆飞行汽车,卖出止损位是其下方的塔楼,买入止损位是其上方的漂浮平台,昨日价位是金色的广告牌,一束探照灯扫过天空,而电子显示屏则滚动显示当天的“渔获”。 两个缓冲区提供上方和下方最近的活跃价格池,供专家顾问使用。仅限指标:该指标从不进行交易。

Symbol Spec Auditor Symbol Spec Auditor

一个图表面板,用于显示决定仓位规模和交易成本(点值、点差成本、保证金、掉期、成交规则)的合约规格详情(以账户货币为单位),会就那些会悄无声息地破坏手数代码的经纪商设置发出警告,并能将每个“市场观察”符号的审计记录导出为CSV文件。

加速震荡(AC) 加速震荡(AC)

加速/减速技术指标(AC)用于衡量当前驱动力的加速和减速。

离散 离散

离散技术指标由价格和交易量的变化决定。