package com.simuwang.calc; import cn.hutool.core.collection.CollUtil; import com.smppw.common.pojo.dto.CompoundRet; import com.smppw.utils.BigDecimalUtils; import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.util.List; @Service public class CompetitionIndicatorCalcService { private static final BigDecimal INDICATOR_MAX_VALUE = new BigDecimal(999999999); /** * 计算年化收益率 * 年化收益是用月年化 * * @param intervalReturn 区间收益率 * @param monthsBetween 区间内的月份 * @return 年化收益率 */ public BigDecimal calcRetA(BigDecimal intervalReturn, Integer monthsBetween) { if (intervalReturn != null) { double ret = Double.parseDouble(String.valueOf(intervalReturn)); double retA = Math.pow(1 + ret, 12.0 / monthsBetween) - 1; return BigDecimal.valueOf(retA); } return null; } /** * 计算周胜率 * 周收益 > 0 ? 1: 0 * * @param fundRetList 基金周收益率 * @return 周胜率(平均周胜率) */ public BigDecimal calcWinRate(List fundRetList) { if (CollUtil.isEmpty(fundRetList) || fundRetList.size() == 1) { return null; } // 第一周的收益率为null double winWeekCount = (double) fundRetList.stream().map(CompoundRet::getRetOfFund).filter(e -> e != null && e.compareTo(0.0) > 0).count(); return BigDecimal.valueOf(winWeekCount / (fundRetList.size() - 1)); } /** * 计算超额胜率 * 基金周收益 > 基准周收益 ? 1: 0 * * @param fundRetList 基金周收益率和基准的周收益率 * @return 超额胜率(平均超额胜率) */ public BigDecimal calcExcessWinRate(List fundRetList) { if (CollUtil.isEmpty(fundRetList) || fundRetList.size() == 1) { return null; } double winWeekCount = 0d; for (CompoundRet compoundRet : fundRetList) { Double retOfFund = compoundRet.getRetOfFund(); Double retOfBmk = compoundRet.getRetOfBmk(); if (retOfFund == null || retOfBmk == null) { continue; } if (retOfFund.compareTo(retOfBmk) > 0) { winWeekCount++; } } return BigDecimal.valueOf(winWeekCount / (fundRetList.size() - 1)); } public BigDecimal calcCalMarRatio(BigDecimal retA, BigDecimal maxDrawDown) { if (retA == null || maxDrawDown == null) { return null; } if (maxDrawDown.compareTo(BigDecimal.ZERO) == 0) { return INDICATOR_MAX_VALUE; } return BigDecimalUtils.divide(retA, maxDrawDown); } }