回测报告里的夏普比率,换一种算法就是另一个数

回测报告里那个夏普比率,是出报告的程序拿一串收益数字算出来的:每一期的收益先减去一个基准,剩下的部分求平均,再除以这部分的标准差。如果旁边标着"年化",那就是又乘过一个换算系数。用的是每天的收益还是每笔交易的收益、基准取了多少、手续费扣没扣,这几样随便换一样,数字就变,而报告上不一定写。
所以"夏普比率多少算好"这个问题,只拿着一个数字答不了。能做的是把五样东西问清楚:收益的周期和年化系数、基准、回测长度与交易笔数、交易成本、调参次数。问清以后,两份报告的数字才能放在一起比,你也能拿原始收益自己复算一遍。
夏普比率怎么算,公式里只有均值和标准差两样
这个比率出自 William Sharpe。1966 年提出时它叫 reward-to-variability ratio,1994 年他又写了一篇 The Sharpe Ratio 把定义重新讲了一遍,全文放在他的斯坦福个人主页上,页面标注发表于 The Journal of Portfolio Management 1994 年秋季号。文中有两个版本:事前(ex ante)版用的是对未来的预期,事后(ex post)版用的是已经发生的历史数据。回测报告里的属于事后版。
事后版分三步算。第一步,把每一期策略的收益减去同一期基准的收益,得到差额收益 D。第二步,对所有期的 D 求平均。第三步,求这些 D 的标准差。平均值除以标准差就是夏普比率,意思是历史上每承担一单位波动,平均换来多少差额收益。
"基准"最早取的是无风险证券的收益,后来也有人换成和被评价的基金风格相近的组合。公式里要减掉什么,是算的人自己选的。
夏普比率多少算好,Sharpe 自己的文章里没有划线
1994 年那篇文章没有给出"大于多少算好"的门槛。文中带数字的参照是一处举例:发达国家股票市场的年度超额收益,典型估计是均值 6%、标准差 15%,对应的年度夏普比率是 0.40。它的用处是给读者一个参照,文章没有把它当及格线。
在别处看到任何一条分档线,先问它配的是哪种周期、哪种基准算出来的数。后面的例子里,同一串收益可以算出 1.60,也可以算出 1.00,拿其中一个去套一条不知道怎么来的线,得不出结论。
按日收益、小时收益还是每笔收益算,年化系数差在哪
夏普比率和测量周期有关,事前版、事后版都一样。最简单的情形是:把 T 期的差额收益直接相加,并且各期之间没有序列相关,那么 T 期的均值是单期的 T 倍,标准差是单期的 √T 倍,两者一除,T 期的夏普比率等于单期的 √T 倍。Sharpe 的建议是用比较短的周期(比如月)来量收益和风险,再换算到年,方便互相比较。
年化系数就是这么来的。月收益算出的比率乘 √12,日收益算出的乘"一年天数"的平方根。这里马上有一个要问的地方:一年按多少天。按 365 天,系数是 √365≈19.1;按 252 个交易日,系数是 √252≈15.9。同样是日夏普 0.05,前一种年化成 0.96,后一种是 0.79。全年不休市的品种和有休市日的品种,报告用的天数可能不同,比较前要统一。
按小时或按每笔交易算的,要问的更多。小时数据乘的是一年小时数的平方根,全年 8760 小时对应的系数约 93.6;按笔算的,要先知道一年大约多少笔,而每笔持仓时间长短不一,"一期"本身就不等长。报告只给一个年化数字、不说基础周期的话,这个数字没法复算。
√T 这个换算本身也有前提。Sharpe 文中紧接着就说,实际情况更复杂:多期收益一般按复利算,各期差额收益之间也可能有序列相关。Andrew Lo 2002 年发表在 Financial Analysts Journal 的 The Statistics of Sharpe Ratios 处理的正是这一点。按它的摘要(摘要页和前面那篇全文都是 2026 年 10 月的版本),月度夏普比率乘 √12 只在很特殊的条件下才成立;在他举的实证例子里,对冲基金的年度夏普比率因为月收益存在序列相关,可以被高估多达 65%。
如果平台能导出逐日或逐笔的收益明细,把它贴进表格:一列收益,一列减去基准后的差额,用求平均和求标准差两个函数各算一次,相除,再乘年化系数。算出来和报告上的数对不上,差的那部分就是报告没有交代的设定,拿这个差去问客服或者策略作者。表格里的标准差有除以 N 和除以 N-1 两个函数,期数少的时候两者差得明显,用的是哪一个也要问。
同一串月收益,算出 1.60、1.20 和 1.00 三个夏普比率
拿这样 12 个月的收益来算(单位 %):3、4、2、-1、-2、0、3、4、2、-1、-2、0。合计 12,月均 1。
算法一,基准取 0,按月算。每个月与均值的差是 2、3、1、-2、-3、-1,重复两遍;平方和是 56,除以 12 再开方,标准差约 2.16。月夏普 = 1 ÷ 2.16 ≈ 0.463,乘 √12(约 3.464)得 1.60。
算法二,基准取每月 0.25%(相当于一年 3%,不计复利)。每个月都减同一个数,标准差不变,均值变成 0.75。月夏普 ≈ 0.347,年化 1.20。
算法三,基准仍取 0,但先把每三个月的收益相加,变成四个季度:9、-3、9、-3。季均 3,标准差 6,季夏普 0.5,乘 √4 得 1.00。
| 算法 | 基础周期 | 每期基准 | 单期均值 | 单期标准差 | 年化系数 | 年化夏普 |
|---|---|---|---|---|---|---|
| 一 | 月 | 0 | 1 | 2.16 | √12 | 1.60 |
| 二 | 月 | 0.25 | 0.75 | 2.16 | √12 | 1.20 |
| 三 | 季 | 0 | 3 | 6 | √4 | 1.00 |
一和三用的是同一串数字、同一个基准,差在哪?这串收益是连着三个月赚、再连着三个月不赚,相邻月份之间是正相关的。√T 换算假定各期不相关,按这个假定,季度标准差应该是 2.16 × √3 ≈ 3.74,实际是 6。按月算的时候,这种成段的起伏没有完整进到标准差里,年化出来的数字就偏高。
另外,上面三种算法用的都是除以期数 N 的标准差。Sharpe 文中事后版用的是除以 N-1 的那种,按它算,算法一的年化结果是 1.54。他在脚注里补了一句:参加比较的几个对象期数相同时,用除以 N 的也可以,因为相对大小不变。
无风险利率取了多少,手续费和滑点扣没扣
算法二已经说明基准的影响:每月多减 0.25%,年化夏普从 1.60 掉到 1.20。回测工具里这一项填的是 0 还是别的数,要去设置页或说明文档里找。取 0 本身不算错,只是和别人取了 3% 的数字放在一起比就不公平。
手续费和滑点的作用方式和基准一样,都是从每一期收益里减掉一块。还用上面的例子:如果每个月的交易成本合计吃掉 0.3%,月均收益从 1 变成 0.7,标准差不变,年化夏普变成 1.12。交易越频繁,减掉的这一块越大。
要问的有三件事。回测里每笔扣的费率是多少,和你账户实际适用的费率是否一致。成交价用的是信号出现那根 K 线的收盘价,还是下一根的开盘价。市价单有没有留滑点。其中任何一样填的是 0,报告上的夏普比率都只能当上限看。
回测区间有多长、有多少笔交易、参数调过几次
历史夏普比率和 t 统计量关系很近。t 统计量检验的是"平均差额收益是不是显著不为零",Sharpe 文中给的关系是 t 等于夏普比率乘以期数的平方根。把它和年化公式放在一起,能推出一个好用的式子:t ≈ 年化夏普 × √(回测年数)。
年化夏普同样是 1.6,回测一年,t 约 1.6;回测四年,t 约 3.2。数字一样,后者是碰巧的可能性小得多。只有三个月的回测,折算成 t 只剩年化夏普的一半。
交易笔数是同一个问题的另一面。一年的回测如果只有十来笔交易,盈利又集中在其中两三笔上,这个夏普比率就是靠很少几次结果撑起来的。看报告时把"总交易笔数"找出来,再看盈利最大的几笔占了总盈利多少。
参数调过多少次,要问做回测的人。如果用了参数优化,把几十上百组参数各跑一遍,再挑结果最好的一组拿出来展示,那么挑出来的数天然偏高,试的组数越多偏得越多。留一段没参与调参的数据再跑一次,数字掉得厉害,就说明前面那个主要是挑出来的。回测信号到了实盘会不会挪位置,是另一件要单独查的事,写在 指标重绘为什么让回测信号在实盘消失 里。
· 基础收益的周期,和年化时乘的系数
· 无风险利率或基准的取值
· 回测起止日期和总交易笔数
· 每笔手续费率和滑点的设定
· 试过的参数组数,以及有没有留一段没参与调参的数据
夏普比率高,也看不出它和你其它持仓会不会一起跌
这个比率不包含策略与其它资产、负债之间相关性的信息,也不包含策略与它自己过去收益之间相关性的信息,Sharpe 因此提醒某些用途下要拿别的指标来补。前一条的意思是,两套夏普比率都不低的策略,如果总在同一种行情里一起亏,合在一起并不会更稳。后一条对应的就是上面例子里算法一和算法三的差别。
另一个性质是它与规模无关。仓位放大一倍,均值和标准差同比例放大,比率不变。所以它回答不了"该用几倍杠杆""最多会亏掉多少本金"这类问题,这些要到报告里的最大回撤和保证金占用那几栏去看。
接着读:回测数字好看之后,对实盘收益该抱多大期望,可以看 交易机器人到底能不能赚钱;策略真跑起来以后程序会在哪些地方出问题,在 交易机器人不下单、报错怎么办:九类故障先查什么 里。