CompetitionIndicatorCalcService.java 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. package com.simuwang.calc;
  2. import cn.hutool.core.collection.CollUtil;
  3. import com.smppw.common.pojo.dto.CompoundRet;
  4. import com.smppw.utils.BigDecimalUtils;
  5. import org.springframework.stereotype.Service;
  6. import java.math.BigDecimal;
  7. import java.util.List;
  8. @Service
  9. public class CompetitionIndicatorCalcService {
  10. private static final BigDecimal INDICATOR_MAX_VALUE = new BigDecimal(999999999);
  11. /**
  12. * 计算年化收益率
  13. * 年化收益是用月年化
  14. *
  15. * @param intervalReturn 区间收益率
  16. * @param monthsBetween 区间内的月份
  17. * @return 年化收益率
  18. */
  19. public BigDecimal calcRetA(BigDecimal intervalReturn, Integer monthsBetween) {
  20. if (intervalReturn != null) {
  21. double ret = Double.parseDouble(String.valueOf(intervalReturn));
  22. double retA = Math.pow(1 + ret, 12.0 / monthsBetween) - 1;
  23. return BigDecimal.valueOf(retA);
  24. }
  25. return null;
  26. }
  27. /**
  28. * 计算周胜率
  29. * 周收益 > 0 ? 1: 0
  30. *
  31. * @param fundRetList 基金周收益率
  32. * @return 周胜率(平均周胜率)
  33. */
  34. public BigDecimal calcWinRate(List<CompoundRet> fundRetList) {
  35. if (CollUtil.isEmpty(fundRetList) || fundRetList.size() == 1) {
  36. return null;
  37. }
  38. // 第一周的收益率为null
  39. double winWeekCount = (double) fundRetList.stream().map(CompoundRet::getRetOfFund).filter(e -> e != null && e.compareTo(0.0) > 0).count();
  40. return BigDecimal.valueOf(winWeekCount / (fundRetList.size() - 1));
  41. }
  42. /**
  43. * 计算超额胜率
  44. * 基金周收益 > 基准周收益 ? 1: 0
  45. *
  46. * @param fundRetList 基金周收益率和基准的周收益率
  47. * @return 超额胜率(平均超额胜率)
  48. */
  49. public BigDecimal calcExcessWinRate(List<CompoundRet> fundRetList) {
  50. if (CollUtil.isEmpty(fundRetList) || fundRetList.size() == 1) {
  51. return null;
  52. }
  53. double winWeekCount = 0d;
  54. for (CompoundRet compoundRet : fundRetList) {
  55. Double retOfFund = compoundRet.getRetOfFund();
  56. Double retOfBmk = compoundRet.getRetOfBmk();
  57. if (retOfFund == null || retOfBmk == null) {
  58. continue;
  59. }
  60. if (retOfFund.compareTo(retOfBmk) > 0) {
  61. winWeekCount++;
  62. }
  63. }
  64. return BigDecimal.valueOf(winWeekCount / (fundRetList.size() - 1));
  65. }
  66. public BigDecimal calcCalMarRatio(BigDecimal retA, BigDecimal maxDrawDown) {
  67. if (retA == null || maxDrawDown == null) {
  68. return null;
  69. }
  70. if (maxDrawDown.compareTo(BigDecimal.ZERO) == 0) {
  71. return INDICATOR_MAX_VALUE;
  72. }
  73. return BigDecimalUtils.divide(retA, maxDrawDown);
  74. }
  75. }