第90章 七千万次的小石头(3 / 9)
它们会被写进ppt,会被掛在年报里,会被用来向投资人吹嘘。
但是,失败的东西,常常最先被刪掉。
研究员为了掩盖自己几个月毫无建树的尷尬,或者为了让代码库看起来乾净,会毫不犹豫地按下delete键。
而一个没有失败记录的研究系统,最容易把倖存者当成真理。
在金融市场里,这叫倖存者偏差。
当你只看到那些成功的策略时,你会觉得市场充满规律。
但如果你看不到那99%因为过度擬合而在实盘中亏得血本无归的废弃因子,你就会在下一次研究中,重蹈覆辙。
江临深吸了一口气,熟练地打开终端,新建项目文件夹。
然后用vim打开audit_log.md,敲下了这个审计项目的最高纲领。
第一行:旧因子库首先不是宝库,而是失败记录的墓地。
第二行:本项目不找神因子,不预测未来,只找“研究流程如何骗过自己”。
第三行:所有结论必须严格绑定四个维度:数据版本、样本池版本、因子版本、回测配置版本。脱离版本谈绩效,一律视为学术造假。
写完这三行,他才正式开始第一轮代码层面的扫描。
最初的审计脚本逻辑並不复杂。
江临用python配合pandas和dask,写了几个守卫器。
唯一性检查: 检查因子编號是否唯一,版本號是否连续,每个因子是否严格绑定了当时所用的清洗数据版本。
样本池漂移: 每个回测结果是否绑定了確定的样本池定义?
失败记录完整性: 失败因子有没有保留详细的刪除原因和失效日期的环境切片?
同源性检查: 同名或近似同名因子是否重复出现?
摩擦成本检查: 交易成本假设有没有在不同版本里发生人为的漂移?
回车,运行。
十五分钟后,第一轮扫描结果出来了。很难看,触目惊心的难看。
四百三十七个因子里,有八十多个没有完整的数据版本號约束。这意味著如果现在重跑回测,根本不知道当初是用什么数据跑出来的。
二十七个因子版本断裂,从 v1.2 直接跳到了 v3.0,中间经歷了什么,无人知晓。
十三个因子名称完全不同,但备註里的数学逻辑高度相似。
还有几个因子,名字看起来像是三个截然不同的方向。
但江临的脚本对它们的脱敏输出矩阵求了横截面相关性后发现,它们的皮尔逊相关係数竟然高达0.98。
说明这根本就是同一类想法,在绩效压力和流程失控里被反覆复製、微调参数、改名重跑,试图碰出一个更好看的夏普比率,最后在歷史里留下了三具极其相似的影子。
这就是纯粹的数据挖掘灾难。
江临面无表情,继续跑第二轮:因子输出版本敏感性测试。 ↑返回顶部↑
但是,失败的东西,常常最先被刪掉。
研究员为了掩盖自己几个月毫无建树的尷尬,或者为了让代码库看起来乾净,会毫不犹豫地按下delete键。
而一个没有失败记录的研究系统,最容易把倖存者当成真理。
在金融市场里,这叫倖存者偏差。
当你只看到那些成功的策略时,你会觉得市场充满规律。
但如果你看不到那99%因为过度擬合而在实盘中亏得血本无归的废弃因子,你就会在下一次研究中,重蹈覆辙。
江临深吸了一口气,熟练地打开终端,新建项目文件夹。
然后用vim打开audit_log.md,敲下了这个审计项目的最高纲领。
第一行:旧因子库首先不是宝库,而是失败记录的墓地。
第二行:本项目不找神因子,不预测未来,只找“研究流程如何骗过自己”。
第三行:所有结论必须严格绑定四个维度:数据版本、样本池版本、因子版本、回测配置版本。脱离版本谈绩效,一律视为学术造假。
写完这三行,他才正式开始第一轮代码层面的扫描。
最初的审计脚本逻辑並不复杂。
江临用python配合pandas和dask,写了几个守卫器。
唯一性检查: 检查因子编號是否唯一,版本號是否连续,每个因子是否严格绑定了当时所用的清洗数据版本。
样本池漂移: 每个回测结果是否绑定了確定的样本池定义?
失败记录完整性: 失败因子有没有保留详细的刪除原因和失效日期的环境切片?
同源性检查: 同名或近似同名因子是否重复出现?
摩擦成本检查: 交易成本假设有没有在不同版本里发生人为的漂移?
回车,运行。
十五分钟后,第一轮扫描结果出来了。很难看,触目惊心的难看。
四百三十七个因子里,有八十多个没有完整的数据版本號约束。这意味著如果现在重跑回测,根本不知道当初是用什么数据跑出来的。
二十七个因子版本断裂,从 v1.2 直接跳到了 v3.0,中间经歷了什么,无人知晓。
十三个因子名称完全不同,但备註里的数学逻辑高度相似。
还有几个因子,名字看起来像是三个截然不同的方向。
但江临的脚本对它们的脱敏输出矩阵求了横截面相关性后发现,它们的皮尔逊相关係数竟然高达0.98。
说明这根本就是同一类想法,在绩效压力和流程失控里被反覆复製、微调参数、改名重跑,试图碰出一个更好看的夏普比率,最后在歷史里留下了三具极其相似的影子。
这就是纯粹的数据挖掘灾难。
江临面无表情,继续跑第二轮:因子输出版本敏感性测试。 ↑返回顶部↑