Spread Profile by Hour
- 实用工具
-
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. - 版本: 1.0
Spread Profile by Hour 根据你的经纪商自己的 tick 历史,为一个交易品种统计服务器日中每个小时的点差分布,并绘制成 24 根柱。柱的实心部分是该小时的点差中位数,颜色较浅的顶部延伸到第 90 百分位数。输入你常用的止损大小后,每根柱都会标注其点差中位数占该止损的比例,这样成本就与你的风险使用同一单位。
这是一个测量工具。它不下任何订单,不使用 DLL,也不使用 WebRequest,除了你开启的 CSV 导出之外,不写入任何文件。
为什么需要它:对于日内和剥头皮规则,决定优势能否保留下来的往往是点差,而不是入场信号。终端显示的是此刻的点差,而K线历史每根K线只保存一个点差值,这掩盖了一小时之内实际发生的情况。同样的规则可能在清淡时段有效,却在每日换日或交易时段开盘时亏损,原因仅仅是那时的点差要宽好几倍。本指标读取报价本身——通过 CopyTicksRange 读取最近 N 个日历日内的每一个卖价 (Bid) 和买价 (Ask) tick——并按服务器时间中一天里的小时将它们分组。
它为每个服务器小时计算以下内容,统计范围为最近 N 个日历日,不含今天,因此在你交易期间画面不会变动:
- 面板上显示每个小时以点为单位的点差中位数和第 90 百分位数;CSV 导出中还包含每个小时的平均值、最大值以及所依据的报价数量。
- 两种采样模式。Tick count:每个报价计一次。Time-weighted:每个报价按其保持有效的时间计权,最长 60 秒。按 tick 计数会使快速行情的占比偏高,而快速行情往往伴随较宽的点差;按时间加权回答的是:在该小时内随机的某一时刻,你会遇到多大的点差。
- 星期过滤(星期一至星期五),用于每周只在某一天交易的规则;使用时请同时增加历史深度,因为 20 个日历日中同一个星期几只有两到三天。
- 成本视图:输入以点为单位的止损大小后,每根柱都会标注点差中位数占该止损的百分比,标题栏也会以同一单位显示当前小时的中位数和第 90 百分位数。当窗口太窄、无法为每根柱显示标签时,只有中位数最高的那根柱保留标签。
- 当前小时的点差中位数,以每 1.00 手的账户货币金额表示,根据交易品种的最小变动价值和最小变动价位计算。
- 标题栏中显示中位数排名两端的小时,每端最多三个。中位数相同的小时会一起列出或合并概括,例如“Cheapest: 23 hours at 6 pt”,因此相同的数值绝不会被当作排名呈现;如果所有小时的中位数都相同,标题栏会直接说明。
- 当前服务器小时高亮显示,实时点差以一条横穿各柱的虚线绘出。
- 可选的 CSV 导出:将逐小时统计表以 UTF-8 编码写入 MQL5\Files\SpreadProfile_<symbol>_<yyyymmdd>.csv,每次计算后写入。
它如何处理 tick 历史,这部分决定了这些数字是否可信:每个定时器步骤只加载一天,并立即释放,因此即使是每天超过 100,000 个 tick 的黄金或加密货币,图表也能保持流畅响应。终端仍在下载的某一天会重试几秒钟;某一天的 tick 如果覆盖不到当天自己的 M1 K线,也会先重试再使用。按从最近到更早的顺序逐日读取。当连续三个交易日没有返回 tick(使用星期过滤时,为该星期几的连续三天),或者连续十天既没有 tick 也没有 M1 K线时,这些日子会在暂停后再读取一次;如果仍然为空,加载即停止,标题栏显示实际使用的最早一天的日期;经纪商 tick 存储内部出现同样长度的空缺时,加载也以同样方式结束。标题栏还会统计作为部分数据使用的天数(即 tick 未到达最后一根 M1 K线)和不可用的天数(即有 M1 K线但没有 tick)。完全没有 tick 历史的交易品种会在大约二十秒内报告这一情况,而不是绘制一个空面板。每次计算会在日志中写入一行汇总——使用的天数、读取的 tick 数、已填充的小时数——开启导出时,另有一行写明 CSV 文件名。
如何阅读面板。每根柱代表服务器时间中一天里的一个小时。实心部分是中位数:一半的报价(在 Time-weighted 模式下为一半的时间)点差小于或等于该值。较浅的顶部是第 90 百分位数:每十个报价中有一个点差比它更宽。以下是截图中的测量结果,取自模拟账户,共 20 个日历日,其中 17 天有 tick:
- EURUSD,Tick count,50 点止损:24 个小时中有 23 个小时的中位数为 6 点。在服务器时间 21:00,即每日换日时,中位数为 34 点,第 90 百分位数为 58。也就是说,一天中大部分时间点差为止损的 12%,而在那一个小时为 68%。
- GBPUSD,Time-weighted,未输入止损:23 个小时的中位数为 7 点,21:00 的中位数为 46,第 90 百分位数为 94。在 Tick count 模式下,同一小时的读数为 54 和 100,因为报价集中在换日前后,而那时的点差很宽。
- XAUUSD,Tick count,1500 点止损:每个有数据的小时中位数都是 182 点,即止损的 12%,每 1.00 手 18.20 USD,因此标题栏直接说明这一点,而不是对相同的数值排名。21:00 的每日休市时段 tick 数少于设定的最小值,显示为短横线。
实际用途是对交易小时做出决策:如果你的系统在点差中位数占止损比例很大的小时内交易,要么跳过该小时,要么放宽止损,要么确认预期的价格波动足以覆盖这项成本。第 90 百分位数展示的是一次糟糕但并不罕见的成交是什么样子。
独立核验。用另一套独立的 Python 实现,从同样的原始 tick 重新计算了逐小时统计。两种采样模式下,每个小时的中位数、第 90 百分位数、平均值、最大值和 tick 数量全部一致,例如 EURUSD 20:00(10,692 个 tick)和 21:00(8,097 个 tick),以及 GBPUSD 21:00 的两种模式。在同一台机器上的加载测试:XAUUSD 20 天,4.29 百万个 tick,耗时 1 到 3 秒;60 天并筛选为星期一,2.60 百万个 tick,耗时 1.3 秒;EURUSD 365 天,在有 tick 的 232 天中共 9.37 百万个 tick,耗时约 30 秒,其中包括对 tick 历史开始之前那些日子的第二次读取。你的耗时取决于经纪商的 tick 密度,以及这些 tick 是否已经保存在磁盘上。
输入参数:以日历日计的历史深度(1 到 365,默认 20)、采样模式、星期过滤、以点为单位的直方图范围(带溢出区间)、一个小时被显示所需的最少 tick 数、以点为单位的止损大小(0 表示关闭百分比标签)、窗口高度、七种颜色(其中四种在保持 None 时自动推导:背景取自图表,文字和网格取自该背景,第 90 百分位数顶部取自柱的颜色)、字体大小,以及 CSV 开关。每个输入参数在终端中都有各自的注释说明。
注意事项和局限。tick 历史深度取决于你的经纪商,以及终端已经下载了哪些数据。在较长深度下首次运行时,终端可能仍在下载 tick;仍在下载中的某一天会重试几秒钟,然后作为部分数据使用或被跳过,因此如果加载提前停止,请在下载完成后重新将指标加载到图表上——第二次运行会从磁盘读取。所有小时都是服务器小时,因此换日之类的事件在夏令时和冬令时之间可能相差一个服务器小时,而跨越切换点的历史窗口会显示该事件分散在相邻的两个小时中。模拟账户与真实账户,以及标准、原始点差和零点差账户类型,同一交易品种的点差可能差别很大——请在你实际交易的账户上测量。点差历史并不能预测未来的点差:新闻、节假日和流动性稀薄都可能产生远高于此处显示的第 90 百分位数的点差。每手成本使用当前的最小变动价值,对于交叉货币对,它会随汇率变动。该分布在每个新的服务器日重新计算一次,并在输入参数、交易品种或时间周期改变时重新计算。指标在独立的子窗口中打开,一个图表上可以运行多个副本,每个副本各占一个窗口。
