行情失真:从 Tick 到 K 线,你的分析对象到底有多真?
用信号处理视角拆解 K 线——为什么大多数指标都建在被重采样、被混叠、被平均过的数据上。
一、同源不同值:周期聚合的陷阱
同一批 tick,聚合成 M1、M5、H1 会得到不同的 OHLC 与指标值。你看到的「突破」在 H1 成立,在 M5 可能早就发生了。技术分析的信号高度依赖你选择的周期,这不是市场变了,是聚合视角变了——同一个事实,被不同窗口讲成了不同的故事。
更微妙的是:不同周期指标还会互相「确认」出虚假共振。当你同时看三个周期都说「金叉」,其实它们源自同一堆 tick,只是被不同窗口讲成了三个故事。这种「多周期共振」往往只是同一噪声的三次回声,而非三个独立证据。
二、前视偏差:用当日 Close 判断当日
最隐蔽的失真来自「未来函数」:在 K 线还没收盘时,用当根 Close 计算信号并回测。回测器会「允许」你在收盘那一刻立刻成交,而实盘你无法在收盘前预知收盘价。这类信号历史好看、实盘失效,是回测盈利实盘亏的首要元凶。
// 错误:用当根未收盘 Close 当信号(含未来) double close = price[0]; if(close > iMA(NULL,0,20,0,MODE_SMA,0)) SignalBuy(); // 正确:只用已收盘的 price[1] double prevClose = price[1]; if(prevClose > iMA(NULL,0,20,0,MODE_SMA,1)) SignalBuy();
养成习惯:任何信号一律基于 price[1] 及更早的数据。回测时若发现「信号总在最佳点触发」,第一反应应是怀疑它偷看了未来,而不是庆祝找到圣杯。
三、幸存者偏差
用「当前还在上市」的股票/品种做历史统计,会自动剔除早已退市的失败者,得出偏乐观的结论。外汇虽无退市,但流动性和点差结构会变,用今天的点差回测十年前的行情,同样是失真——你假设了当年也有今天这么薄的点差,而事实未必。
换月价差(roll-over)对远期合约、库存费(swap)对中长期持仓,都会在「不显眼」的地方改写收益曲线。忽略它们,回测的「稳定盈利」可能只是会计口径的错觉。
四、流动性与滑点失真
回测默认按你指定的价格成交;实盘在流动性差时,大单会推动价格、产生滑点。若策略单笔手数大或交易冷门品种,回测盈利会被严重高估,而实盘每次进出都在「付捐」。滑点不是小费,是策略能否存活的硬成本。
五、复权与分红
股票类标的分红、拆股会改变价格序列连续性。不处理复权直接算收益率,会出现虚假跳空与错误信号。外汇无此问题,但要留意换月价差对远期合约的影响,以及库存费对中长期持仓的侵蚀——很多「长线赚」的策略,扣完 swap 其实是亏的。
六、如何减少失真
根本原则是「让回测尽量像实盘」:信号只用已收盘数据,成交用真实 tick 与真实点差,参数在样本外复核。任何让回测变「漂亮」的简化,都在偷偷抬高你的预期——而实盘会按真实成本结算。
- 信号一律用已收盘 K 线(price[1] 及更早),杜绝未来函数
- 用真实 tick 或「每 tick」模式回测,而非 OHLC 近似
- 在回测设置里加入点差与滑点
- 对周期敏感的指标,固定周期并写明,不跨周期混用
- 对冷门/大单策略单独做流动性压力测试
七、用多周期交叉验证稳健性
一个成熟信号,应在多个周期上「方向一致」而非「数值一致」。若策略在 M15 赚、在 H1 亏,说明它捕捉的只是某一周期的噪声。用多周期交叉验证,能筛掉那些只在单一聚合视角下显得有效的脆弱信号,留下真正跨尺度稳健的逻辑。
具体做法:把同一规则分别在各周期回测,看盈利是否同号、回撤是否可控。若只在某一个周期「神准」,其余都亏,那它大概率是过拟合该周期噪声,而不是抓住了普适规律。
八、失真清单自查
每次看回测数字前,过一遍这份自查:信号是否只用已收盘数据?成交是否含真实点差与滑点?样本是否含已退市/已变结构的标的?参数是否跨周期稳健?流动性是否匹配实盘手数?五项里任一项答「否」,结论就要打折。这份清单比任何指标都更能保护你不被漂亮曲线骗。