基金里投资风险指标的计算工具类(夏普比率,波动率,Var值,最大回撤率)
去年在项目里写了一个计算投资风险指标的计算工具类,包含夏普比率,波动率,Var值,最大回撤率四个指标。
计算全部采用BigDecimal类型,开方计算采用牛顿迭代法计算。
其计算公式如下:
工具类实现:
/** * @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
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
原文地址: https://blog.csdn.net/qq_43365046/article/details/114700156
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
相关文章