基金里投资风险指标的计算工具类(夏普比率,波动率,Var值,最大回撤率)

2020-09-09 00:00:00 波动 比率 投资风险

去年在项目里写了一个计算投资风险指标的计算工具类,包含夏普比率,波动率,Var值,最大回撤率四个指标。
计算全部采用BigDecimal类型,开方计算采用牛顿迭代法计算。
其计算公式如下:
《基金里投资风险指标的计算工具类(夏普比率,波动率,Var值,最大回撤率)》
工具类实现:

/** * @describe 投资分析数学计算工具类 */
public class MathUtil { 
    /** * 默认保留小数位数 */
    private final static Integer DECIMAL_SCALE = 15;
    /** * 默认牛顿迭代法计算平方根时迭代次数 */
    private final static Integer PRECISION = 20;
    private final static Integer COUNT = 0;

    /** * @describe 计算收益率 * @params startNav 期初单位净值 endNav 期末单位净值 */
    public static BigDecimal dayYield(BigDecimal startNav, BigDecimal endNav) { 
        return dayYield(startNav, endNav, DECIMAL_SCALE);
    }

    public static BigDecimal dayYield(BigDecimal startNav, BigDecimal endNav, int decimalScale) { 
        return dayYield(startNav, endNav, decimalScale, BigDecimal.ROUND_HALF_UP);
    }

    public static BigDecimal dayYield(BigDecimal startNav, BigDecimal endNav, int decimalScale, int roundingMode) { 
        BigDecimal dValue = endNav.subtract(startNav);
        return dValue.divide(startNav, decimalScale, roundingMode);
    }

    /** * @describe 计算累计求和 */
    public static BigDecimal sum(BigDecimal[] dataArray) { 
        BigDecimal sum = BigDecimal.ZERO;
        for (BigDecimal data : dataArray) { 
            sum = sum.add(data);
        }
        return sum;
    }

    /** * @describe 计算算术平均值 */
    public static BigDecimal avg(BigDecimal[] dataArray) { 
        return avg(dataArray, DECIMAL_SCALE);
    }

    public static BigDecimal avg(BigDecimal[] dataArray, int decimalScale) { 
        return avg(dataArray, decimalScale, BigDecimal.ROUND_HALF_UP);
    }

    public static BigDecimal avg(BigDecimal[] dataArray, int decimalScale, int roundingMode) { 
        BigDecimal sum = sum(dataArray);
        BigDecimal count = new BigDecimal(dataArray.length);
        return sum.divide(count, decimalScale, roundingMode);
    }

    /** * @describe 计算样本方差 */
    public static BigDecimal variance(BigDecimal[] dataArray) { 
        return variance(dataArray, DECIMAL_SCALE);
    }

    public static BigDecimal variance(BigDecimal[] dataArray, int decimalScale) { 
        return variance(dataArray, decimalScale, BigDecimal.ROUND_HALF_UP);
    }

    public static BigDecimal variance(BigDecimal[] dataArray, int decimalScale, int roundingMode) { 
        BigDecimal avg = avg(dataArray, decimalScale, roundingMode);
        BigDecimal[] resultArray = new BigDecimal[dataArray.length];
        for (int i = 0; i < dataArray.length; i++) { 
            BigDecimal dValue = dataArray[i].subtract(avg);
            resultArray[i] = dValue.multiply(dValue);
        }
        BigDecimal sum = sum(resultArray);
        BigDecimal count = new BigDecimal(resultArray.length - 1);
        return sum.divide(count, decimalScale, roundingMode);
    }

    /** * @describe 计算平方根 */
    public static BigDecimal standardDeviation(BigDecimal data) { 
        return standardDeviation(data, DECIMAL_SCALE);
    }

    public static BigDecimal standardDeviation(BigDecimal data, int decimalScale) { 
        return standardDeviation(data, decimalScale, BigDecimal.ROUND_HALF_UP);
    }

    public static BigDecimal standardDeviation(BigDecimal data, int decimalScale, int roundingMode) { 
        BigDecimal result = data;
        int count = COUNT;
        while (count < PRECISION && result.compareTo(BigDecimal.ZERO) != 0) { 
            result = (result.add(data.divide(result, decimalScale, roundingMode))).divide(BigDecimal.valueOf(2), decimalScale, roundingMode);
            count++;
        }
        return result;
    }

    /** * @describe 计算夏普比率 */
    public static BigDecimal sharpeRatio(BigDecimal[] yieldArray, BigDecimal drVal, BigDecimal vol) { 
        return sharpeRatio(yieldArray, drVal, vol, DECIMAL_SCALE);
    }

    public static BigDecimal sharpeRatio(BigDecimal[] yieldArray, BigDecimal drVal, BigDecimal vol, int decimalScale) { 
        return sharpeRatio(yieldArray, drVal, vol, decimalScale, BigDecimal.ROUND_HALF_UP);
    }

    public static BigDecimal sharpeRatio(BigDecimal[] yieldArray, BigDecimal drVal, BigDecimal vol, int decimalScale, int roundingMode) { 
        BigDecimal avg = avg(yieldArray, decimalScale, roundingMode);
        BigDecimal variance = variance(yieldArray, decimalScale, roundingMode);
        BigDecimal standardDeviation = standardDeviation(variance, decimalScale, roundingMode);
        return avg.subtract(drVal).divide(standardDeviation, decimalScale, roundingMode).multiply(vol).setScale(decimalScale, roundingMode);
    }

    /** * @describe 计算波动率 */
    public static BigDecimal yieldVar(BigDecimal[] yieldArray, BigDecimal vol) { 
        return yieldVar(yieldArray, vol, DECIMAL_SCALE);
    }

    public static BigDecimal yieldVar(BigDecimal[] yieldArray, BigDecimal vol, int decimalScale) { 
        return yieldVar(yieldArray, vol, decimalScale, BigDecimal.ROUND_HALF_UP);
    }

    public static BigDecimal yieldVar(BigDecimal[] yieldArray, BigDecimal vol, int decimalScale, int roundingMode) { 
        BigDecimal variance = variance(yieldArray, decimalScale, roundingMode);
        BigDecimal standardDeviation = standardDeviation(variance, decimalScale, roundingMode);
        return standardDeviation.multiply(vol).setScale(decimalScale, roundingMode);
    }

    /** * @describe 计算Var */
    public static BigDecimal var(BigDecimal[] yieldArray, BigDecimal zVal) { 
        return var(yieldArray, zVal, DECIMAL_SCALE);
    }

    public static BigDecimal var(BigDecimal[] yieldArray, BigDecimal zVal, int decimalScale) { 
        return var(yieldArray, zVal, decimalScale, BigDecimal.ROUND_HALF_UP);
    }

    public static BigDecimal var(BigDecimal[] yieldArray, BigDecimal zVal, int decimalScale, int roundingMode) { 
        BigDecimal variance = variance(yieldArray, decimalScale, roundingMode);
        BigDecimal standardDeviation = standardDeviation(variance, decimalScale, roundingMode);
        return standardDeviation.multiply(zVal).setScale(decimalScale, roundingMode);
    }

    /** * @describe 计算最大回撤率 */
    public static BigDecimal maxRetracement(BigDecimal[] dataArray) { 
        return maxRetracement(dataArray, DECIMAL_SCALE);
    }

    public static BigDecimal maxRetracement(BigDecimal[] dataArray, int decimalScale) { 
        return maxRetracement(dataArray, decimalScale, BigDecimal.ROUND_HALF_UP);
    }

    public static BigDecimal maxRetracement(BigDecimal[] yieldArray, int decimalScale, int roundingMode) { 
        BigDecimal maxRetracement = BigDecimal.ZERO;
        BigDecimal maxTotalYield = BigDecimal.ZERO;
        BigDecimal totalDayYield = BigDecimal.ZERO;
        for (int i = 1; i < yieldArray.length; i++) { 
            totalDayYield = (totalDayYield.add(BigDecimal.ONE)).multiply(yieldArray[i].add(BigDecimal.ONE)).subtract(BigDecimal.ONE);
            if (totalDayYield.compareTo(maxTotalYield) >= 0) { 
                maxTotalYield = totalDayYield;
            } else { 
                BigDecimal retracement = maxTotalYield.subtract(totalDayYield).divide(BigDecimal.ONE.add(maxTotalYield), decimalScale, roundingMode);
                maxRetracement = retracement.compareTo(maxRetracement) > 0 ? retracement : maxRetracement;
            }
        }
        return maxRetracement;
    }

    /** * @describe 用资产净值计算日收益率数组 */
    public static BigDecimal[] yieldArray(BigDecimal[] assetArray, BigDecimal[] cashFlowArray) { 
        //日收益率数组
        BigDecimal[] yieldArray = new BigDecimal[assetArray.length - 1];
        for (int i = 0; i < assetArray.length - 1; i++) { 
            yieldArray[i] = dayYield(assetArray[i], assetArray[i + 1].subtract(cashFlowArray[i + 1]));
        }
        return yieldArray;
    }

    /** * @describe 用单位净值计算日收益率数组 */
    public static BigDecimal[] yieldArray(BigDecimal[] navArray) { 
        // 日收益率数组
        BigDecimal[] yieldArray = new BigDecimal[navArray.length - 1];
        for (int i = 0; i < navArray.length - 1; i++) { 
            yieldArray[i] = dayYield(navArray[i], navArray[i + 1]);
        }
        return yieldArray;
    }
}

    原文作者:会写代码的劫
    原文地址: https://blog.csdn.net/qq_43365046/article/details/114700156
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。

相关文章