V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
raquant
V2EX  ›  Java

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

  •  
  •   raquant · 2017-03-28 13:50:03 +08:00 · 2712 次点击
    这是一个创建于 2797 天前的主题,其中的信息可能已经有所发展或是发生改变。

    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 ,期望值就已经确定了。对,期望的意思是,按这种势头搞下去,你一年(或其它自定义的周期)能赚多少。

    • Rf: 抱歉上面的期望不是你的“期望”,但这个 Rf (无风险收益率)你可以自行决定。比如像我这种没什么门道的普通人,就 6%吧,存个长期的理财。如果你有别的门道,比如把钱放到你二大爷那,他每年都能搞出 20%的收益,那么这个值对你来说就是 20%。

    • σ:这个东西就是标准差,用来衡量数列的离散程度。比如你今天翻倍,明天又跌去八成,后天又翻倍,这就说明离散程度较大了,虽然你最后还是赚了,但中间的过程比较惊悚,也就是说,你承受的风险比较大。

    • σd :这个东西是下偏差。有学机械的提出疑问,这是搞装配么,怎么还有下偏差,确定这是统计学里面的?额,我学数理统计的时候确实没有这个东西。它的意思是,只统计基准以下的数据;基准以上的数据统统当作 0 处理。 Sortino ration 的发明者给出的理由是:我亏的才算风险,赚的再多我不怕,怎么能说是有风险呢!所以它的含意是,未超过基准收益部分的数据的离散程度。

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

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

    • (参考标准最终指数 / 参考标准初始指数 - 1) / 回测交易日数量 × 250

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

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

        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));
            }
    
    
    • [镭矿量化交易] 公众号菜单栏提供选择因子生成策略的小工具(策略生成 beta),欢迎大家尝试一下量化的神奇。如果你是程序员,也可以进入镭矿 raquant 量化平台,开启量化之旅。
    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2821 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 07:33 · PVG 15:33 · LAX 23:33 · JFK 02:33
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.