[诺贝尔粉丝勿入] Dig 一下 Sharpe 比率和 Sortino 比率

2017-03-28 13:50:03 +08:00
 raquant

Sharpe ratio 和 Sortino ratio ,它们都用来衡量每获得一份收益面临着多大风险。下面是两者的计算公式:

Sharpe ratio:    (Rp - Rf )/ σ
Sortino ratio:   (Rp - Rf) / σd

可以看到,这两者的区别是:分母不同。 接下来会挨个解释一下公式中出现的 4 种变量,但在这之前,需要做一些假设,我需要数据来说明。 假设要统计过去半年内以月为周期的 Sharpe 和 Sortino ,以下是过去 6 个月的每月相对收益状况:

    double pf = {0.02, 0.08, -0.01, 0.01, -0.02, 0.04};

1. 参数定义

Rp: 期望的收益值。就是字面上的意思。但是初次接触这个公式的人就会问,这个数该怎么填?我期望每月收益率 100%!抱歉,这里期望是指数学上的期望(百度一下,你将会温习到中学时代的数理统计方面的内容),这个数暂时我来定,因为指定了上面的 pf ,期望值就已经确定了。对,期望的意思是,按这种势头搞下去,你一年(或其它自定义的周期)能赚多少。

2. 年化收益率的计算方法

Rp , Rf 我们可以简单理解为收益率。但要注意到,收益率是有周期单位的,年化收益和日收益、月收益不在一个维度上,没有可比性。不同周期的收益率不能代入上述公式直接计算,这就存在着收益率换算的问题。在知乎上看到有些量化平台给出的 N 日收益换算到年化收益的方法是(还是个高票回答):

不得不指出,这样的计算方法是不合适的。因为每天的收益会改变帐户的资产状况,不能简单的用算术平均来计算。不同周期收益率之间的换算要考虑到资产的变化,即复利,所以一些乘方和开方的运算是不可避免的。

下面给出了以七日收益来计算年化收益预期的实现代码,原始数据取自己余额宝:

    public static void annualProfitTest() {
        // 最近 7 天的万份收益,即存 1 万,收 1 块零几分钱
        double[] pDailyIncome = {1.0213,1.0198,1.0197,1.0337,1.0354,1.0389,1.0399};
        // 最近 7 天的总收入
        double totalIncome = StatUtils.sum(pDailyIncome);
        // 根据 7 日的收益计算日化收益率, 开 7 次方
        double dailyProfitRatio = StrictMath.pow(1+totalIncome/10000.0, 1/7.0)-1;
        // 根据日化收益率计算年化收益率, 365 次方
        double annualProfitRatio = StrictMath.pow(1+dailyProfitRatio, 365)-1;
        System.out.println("Daily: "+dailyProfitRatio+"\nAnnual: "+annualProfitRatio);
    }

类似的,由月收益得到日收益或年收益的时候,可以相应的修改上面的代码。

3. Sharp ratio 的计算方法

接下来是代码 show time ,先算一下 Sharp:

    // 根据单位周期相对收益率,计算总周期的收益率
    	public static double calcTotalProfitRatio(double[] profits) {
    	    double totalProfitRatio = 1;
    	    for(int i=0; i<profits.length; i++) {
    	        totalProfitRatio = totalProfitRatio*(1+profits[i]);
            }
            return totalProfitRatio-1;
        }

        public static void main(String[] args) {
            double[] pf = {0.022, 0.012, -0.016, 0.019, -0.026, 0.023};
            // 6 个月的总收益率
            double Rp = calcTotalProfitRatio(pf);
            // 无风险收益率年化值 6%,存 6 个月能收益多少
            double Rf = StrictMath.pow(StrictMath.pow(1.06, 1/12.0),6)-1;
            // 计算 pf 的标准差
            SummaryStatistics pointStats = new SummaryStatistics();
            for(double val:pf) pointStats.addValue(val);
            double theta = pointStats.getStandardDeviation();

            // 代入 Sharp ratio 计算公式
            double sharp = (Rp-Rf)/theta;

            System.out.println("Rp:"+Rp+"\nRf:"+Rf+"\ntheta:"+theta+"\nsharp:"+sharp);
        }

4. Sortino ratio 的计算方法

计算 Sortino ratio 与计算 Sharpe ratio 的唯一区别是,要用下偏差替代标准差。所谓下偏差,就是忽略掉上偏差的影响。我们可以这样处理,当某一个月的收益超过参考收益时,将其差值置为 0 :

但是,我们会发现,刚才我们使用的 SummaryStatistics 类,并没有计算下偏差的方法,那么,我们可以写一个:

        public static double downDeviation(double[] src, double ref) {
    	    double sum=0d;
    	    for(double val:src) sum += (val>=ref) ? 0d : (val-ref);
    	    return StrictMath.sqrt(sum/(src.length-1.0));
        }

2614 次点击
所在节点    Java
0 条回复

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/350883

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX