股票回测全是骗人的?开源YASS用九年数据撕开夏普比率真相


YASS (Yet Another Stock Screener) 是一个开源的股票筛选与回测框架。它旨在让用户通过修改 YAML 配置文件(而非代码)来定义和回测量化策略。

核心功能与特点

  • 无代码配置:策略的信号、权重和筛选条件均通过 YAML 文件配置,无需修改核心代码。
  • 避免未来函数:采用点时间 (Point-in-Time) 数据,确保回测使用当时已知的信息,避免未来函数导致的偏差。
  • 完善的评估体系:集成了蒙特卡洛分析、因子归因 (OLS)、行情机制分析和样本外检验 (Walk-Forward) 等多种评估工具。
  • 插件化架构:支持自定义信号和筛选器,只需在相应目录下添加 Python 文件即可自动发现并注册。
  • 高效的数据处理:使用 DuckDB 进行数据缓存,Polars 和 Arrow 进行高性能 DataFrame 操作。
  • 实盘交易支持:集成了 Alpaca 和 eToro 等券商接口,支持调仓和持仓跟踪。


股票筛选器能预测未来?别做梦了!回测全是骗人的把戏!

点开这篇文章的你,大概率做过这种事:翻出一个股票筛选策略,跑一遍历史数据,看到年化收益百分之二三十,夏普比率一点几,兴奋得差点下单买股票。停!那个数字是假的。

有个叫YASS的开源项目,作者是个受够了凭感觉投资、自己动手写量化工具的软件工程师。他做了一件很多量化平台打死都不做的事——把回测结果的真实面目,原原本本晒给你看。2017到2026年,九年数据,108个月度收益率,用示例配置跑出来的夏普比率点估计看着不错,但平稳区块自助法算出来的90%置信区间只有0.37到1.38。

什么意思?就是同一个策略,稍微换一下历史数据的采样方式,夏普能从0.37跳到1.38,跨度接近四倍。九年回测,就这精度?你敢拿这个去实盘?


回测是怎么骗你的?未来函数是头号杀手

先解释一个概念,用十岁小孩都能听懂的话。假设今天是2026年8月28号,你要测试一个策略在2020年3月疫情暴跌时能不能扛住。很多回测工具会偷偷把“2026年才知道的财报数据”塞进2020年的决策里。这就是未来函数——用未来的信息,去假装过去的决策。

你回忆一下,2020年3月的时候,你能看到2020年全年的财报吗?看不到。但很多回测系统会让你的策略“看到”。结果就是,回测成绩漂亮得不像话,一上实盘就崩。

YASS做了一个反常识的设计:点时间数据。每次回测日期,系统只使用那个日期之前已经公开的数据。2020年3月的决策,只能用2020年3月之前发布的财报和价格。这才叫诚实。

但这只是第一步。诚实的数据只能保证回测“不造假”,不能保证回测“有意义”。真正的问题在后面。


九年数据还不够?那要多少才够?

很多人觉得,九年回测,够长了吧?够有说服力了吧?

YASS的作者用行动告诉你:不够。

他直接在README里把回测结果的不确定性量化出来了。108个月度收益率,平稳区块自助法算出来的夏普比率置信区间,下限0.37,上限1.38。这是一个什么概念?0.37的夏普意味着策略几乎不产生超额收益,跟买指数基金差不多。1.38的夏普意味着这是一个相当不错的策略。

同一个策略,同一条历史数据,只是换了个统计方法,结论可以从“平庸”变成“优秀”。九年数据,在统计学家眼里,也就是个噪声稍微小一点的样本罢了。

这就怪了。如果九年都不够,那散户自己做的那三五年的回测,还有什么参考价值?


蒙特卡洛分析是什么?就是把你的策略“揍”一万遍

YASS集成了蒙特卡洛分析、因子归因、行情机制分析和样本外检验。这几个词听起来很唬人,拆开来看就懂了。

蒙特卡洛分析:把同一段历史数据随机重排一千次、一万次,每次跑一遍你的策略,看结果分布有多散。如果一万次模拟里有一半跑出来的结果比你实际回测结果还差,说明你的策略纯属运气。

因子归因:用统计学方法拆解你的收益,到底有多少来自选股能力,有多少来自大盘本身在涨。很多策略去掉市场因子之后,超额收益直接归零。

样本外检验:把数据切成很多段,前一段用来优化策略参数,后一段用来验证,窗口不断往前滚。如果你在每一段样本外数据上都能跑出不错的结果,那才算有点东西。

YASS把这些工具全都打包好了,一行命令就能跑。但问题是,绝大多数散户连“未来函数”是什么都不知道,更别说用这些工具去检验自己的策略了。


插件化架构是什么?就是让你不用碰核心代码

YASS的另一个设计是插件化。信号和筛选器都放在特定目录下,丢一个Python文件进去,系统自动发现并注册。

你想加一个新信号?在signals/目录下新建一个文件,写一个类,定义好name、description、higher_is_better和compute方法就行。配置文件里直接引用这个信号的名字,权重随便调。核心代码一行都不用改。

这听起来很基础对不对?但你去看看市面上那些量化平台,有几个让你这么自由地加自定义信号的?大部分是给你几个固定的指标下拉菜单,选来选去就那几样。想加一个自己研发的因子?对不起,不支持。

YASS还内置了七个现成信号:Piotroski F评分、12个月动量、低杠杆增长、质量评分、利润率扩张、中盘质量、折价中盘质量。你可以直接用,也可以改权重,也可以拿来做参考写自己的信号。

数据方面,支持Sharadar和Financial Modeling Prep两个数据源,字段覆盖估值、质量、成长、利润率、效率、价格动量等类别。没API密钥?自动降级到模拟数据。想先看看框架长什么样,不用花钱买数据。


持有奖励和止损:反常识的交易设计

YASS有两个配置项值得单独拎出来说。

一个是持有奖励。配置里有个hold_bonus参数,默认值是1.0。它的作用是给当前持有的股票一个Z-score加成,降低换手率。频繁调仓会产生交易成本和税收,这个设计就是在提醒你:别整天折腾。

另一个是止损。position_stop_loss默认是0.0,也就是关掉的。README里专门解释了一句:日内锯齿波会伤害动量策略。什么意思?很多策略教程告诉你必须设止损,但YASS的作者说,对动量策略来说,日内价格上下乱跳的时候设止损,反而会被反复打脸出场。关掉止损,有时候比设止损更好。

这两个设计都在反常识。别人告诉你多交易、严止损,YASS告诉你少折腾、别止损。


实盘集成:从回测到真金白银的最后一公里

YASS集成了Alpaca和eToro的接口。支持调仓和持仓跟踪,还有dry-run模式先跑一遍看看。

最值得关注的是track命令。它会把你实际账户的已实现收益率和持仓记录里的模型收益率做对比。这才是真正的样本外检验——你的策略在真实市场上到底表现如何,跟回测差了多少。

很多量化框架只管回测不管实盘。回测跑出来好看,实盘怎么执行、怎么跟踪、怎么对比,全都不管。YASS把这个链路打通了。


等一下,项目作者到底是谁?

YASS的作者叫JIXIN LIAO,在eToro上的自我介绍是“受够了凭感觉投资、自己动手写了这个量化股票筛选器的软件工程师”。

一个软件工程师,不是对冲基金量化研究员,不是金融学教授。他做这个项目的动机很简单:自己投资老亏钱,凭感觉不行,那就写代码来解决。

项目采用Apache 2.0许可证,完全开源。免责声明写得清清楚楚:仅用于教育和信息目的,不构成投资建议,过去的表现不代表未来的结果。

这句话每个量化平台都会写,但YASS是少数几个把这句话真正落实到了产品设计里的——它把回测的不确定性直接怼到你脸上,让你没法假装没看见。


回测结果的置信区间,才是真正的“收益预测”

回到开头那个问题。你翻出一个策略,回测年化收益20%,夏普1.2。这个数字到底意味着什么?

在YASS的框架里,这个数字只是一个点估计。真正有意义的是它的置信区间。如果夏普的点估计是1.2,但90%置信区间是0.37到1.38,那你实际能拿到的夏普,大概率落在这个区间里的某个位置。至于是0.37还是1.38,鬼知道。

九年数据都搞不定的事,你指望三年数据能搞定?

YASS的作者在README里写了一句话,值得每个做量化投资的人贴在显示器上:“a 9-year backtest is a noisy point estimate, not a promise”。九年回测只是一个充满噪声的点估计,不是一个承诺。

这句话的反面是什么?是那些拿两三年回测数据就敢卖策略、卖课程、卖软件的人。他们卖的不是策略,是确定性幻觉。


你回测时看到的每一个漂亮数字,背后都藏着一个你没问的问题

最后一个问题留给你自己。

你下次再看到一张回测曲线图,年化收益百分之多少、夏普比率多少、最大回撤多少,别急着兴奋。先问三个问题。

第一,这个回测用了点时间数据吗?还是偷偷用了未来的财报?

第二,这个回测的置信区间是多少?点估计旁边有没有给误差范围?

第三,这个策略做过样本外检验吗?还是只在同一段数据上反复优化直到好看?

如果这三个问题一个都答不上来,那这张回测图跟算命先生的卦象没有本质区别。

YASS这个项目把这三个问题的答案,全部放在了代码里。你不用信它,你自己去跑一遍evaluate命令,看图表自己判断。

但有个细节你可能没注意到:README里那张回测图表,是2026年7月3日重新生成的。为什么要重新生成?因为数据变了、代码改了、结果也跟着变了。一个开源项目的回测结果,随着版本迭代都在波动。你那一次跑出来的漂亮数字,又能稳多久?

注意:股票数据和股票数据的解读是两回事,回测的是解读。