案发现场在我自己的数据库里:一只股票的历史价格,是负的。没有暴跌,没有退市,就是负的。价格可以从一百块跌到一块,但从来没有一种跌法叫跌成负数——除非,历史价格被人改写过。
第一现场
先交代口供:我这系统有一个重大偏误——从网上爬来的股价,是不是前复权的?要是前复权,就等于知道日后每一年的股息,那全完蛋了,我这数据是不是白爬了?
前复权的算法是:把日后每一次分红除权,往前折算进历史价格。问题是,1995 年的那根 K 线被 2024 年的分红改写过——而 1995 年的投资者不可能知道 2024 年分不分红。回测的人拿到这份数据,等于提前翻了答案。这在量化行当里有名字,叫前视偏差,具体这一款,叫股息前视。数据没白爬,爬来的是原始价;错的是我用它算收益——收益的计算方式偷看了未来。
三种口径,三种污染
很快,要命的问题自己冒了出来:前复权有一个很大的毛病——价格复着复着,会变成负数。高分红的老股票,几十年的分红一路往前扣,能把历史价格扣穿零。这不只是趋势研究受影响——是整个数据集在数学上就不成立。
那换别的不行吗?不复权、后复权,是不是也污染?过堂的结果是三种口径各有各的罪:不复权,价格序列在除权日断裂,跳空缺口制造假信号——但它的 PE 是真的,因为当年的人就是用当年那个价格算的;后复权,序列连续、方向从过去往后算,没有未来信息,可价格被推得离谱,估值分位全失真;前复权,图表最好看,数学上最不成立。
结论:没有一种现成口径是干净的。干净的方案只有一个——数据库存未复权价,另存一张分红事件表,回测要用哪种口径,当场动态计算。价格是事实,事件是事实,口径是用的时候才该做的决定。
同案犯
案子到这里该结了,结果在指数那儿又撞见一个。恒生指数本身不复权——每年 4% 上下的股息,全部扔掉。价格指数讲长期故事,等于每年把真实的回报砍掉一截,三十年下来系统性低估大约一年 4 个点。
怎么会全球投资者这么傻呢?因为这个偏误大了去了——你看 6% 跟 10% 的差异,那就是 50% 的差距。股息率 6% 的市场,用不含股息的指数讲三十年,差异能吞掉一半的真实回报。报纸在用,基金在用,你的长期收益对比基准也在用。全球投资者不傻——是全球投资者都在看同一张被涂改过的表。
结案
数据不是事实,数据是带口径的事实。每一张 K 线图背后都藏着一个必须审的问题:这条历史价格,是当时的谁、在当时能知道的什么范围内算出来的?答不上来的数据,不能进回测。
我的数据库最后立了新规矩:未复权价、前复权、后复权、分红事件,四件套全存,外加一行"当时可得"的标记。成本是几张表,换来的是历史不再被未来改写。改写历史不需要坏人——一个默认参数就够了。