package com.smppw.utils; import com.smppw.common.cache.CaffeineLocalCache; import com.smppw.common.pojo.dto.CompoundRet; import com.smppw.common.pojo.dto.DateValue; import com.smppw.common.pojo.dto.calc.IndicatorCalcPropertyDto; import com.smppw.common.pojo.dto.calc.IndicatorCalcTimeRangeDto; import com.smppw.common.pojo.enums.Frequency; import com.smppw.common.pojo.enums.Indicator; import com.smppw.common.pojo.enums.TimeRange; import com.smppw.common.pojo.enums.TrendType; import com.smppw.constants.DateConst; import com.smppw.constants.IndicatorConst; import com.smppw.core.reta.IndicatorFactory; import com.smppw.core.reta.Rate; import com.smppw.core.reta.calc.PerformanceConsistency; import com.smppw.core.trend.Trend; import com.smppw.core.trend.TrendFactory; import org.apache.commons.lang3.StringUtils; import org.joda.time.DateTime; import org.joda.time.format.DateTimeFormat; import java.math.BigDecimal; import java.util.*; /** * @author lzj */ public class IndicatorCalcUtil { public static List getFundRetList(List list) { List doubleList = new ArrayList<>(); for (CompoundRet value : list) { if (value.getRetOfFund() != null) { doubleList.add(value.getRetOfFund()); } } return doubleList; } public static Map calcNavIndicatorValue(List navList, List navIndicatorList) { IndicatorFactory factory = IndicatorFactory.getInstance(); Map navIndicatorValueMap = new HashMap<>(); for (Indicator indicator : navIndicatorList) { if (null == navList || navList.size() == 0) { navIndicatorValueMap.put(indicator.name(), null); continue; } Rate rate = factory.get(indicator); Double navIndicatorValue = null; try { navIndicatorValue = rate.calc(navList); } catch (Exception e) { // log.error("计算异常Exception",e.getMessage(),e); navIndicatorValue = null; } if(navIndicatorValue != null && navIndicatorValue.isNaN()){ navIndicatorValue = null; } else if( navIndicatorValue != null ) { BigDecimal bigDecimalValue = new BigDecimal(navIndicatorValue.toString()); BigDecimal maxBigDecimalValue = new BigDecimal(IndicatorConst.MAX_INDICATOR_VALUE_STRING); BigDecimal minBigDecimalValue = new BigDecimal(IndicatorConst.MIN_INDICATOR_VALUE_STRING); if (bigDecimalValue.compareTo(maxBigDecimalValue)>0) { navIndicatorValueMap.put(indicator.name(), maxBigDecimalValue.toPlainString()); continue; } else if (bigDecimalValue.compareTo(minBigDecimalValue)<0) { navIndicatorValueMap.put(indicator.name(), minBigDecimalValue.toPlainString()); continue; } } if (Indicator.INTEGER_VALUE_ARRAY.contains(indicator)) { navIndicatorValueMap.put(indicator.name(), CommonUtil.double2IntegerString(navIndicatorValue)); } else { navIndicatorValueMap.put(indicator.name(), CommonUtil.double2StringPoint6WithoutHalfUp(navIndicatorValue)); } } convertMaxDrawdownRecureDate(navIndicatorValueMap, navIndicatorList); return navIndicatorValueMap; } private static void convertMaxDrawdownRecureDate(Map dataMap, List indicators) { if (indicators.contains(Indicator.MaxDrawdownRecureDate)) { String value = dataMap.get(Indicator.MaxDrawdownRecureDate.name()); if (value != null) { String dateStr = String.valueOf(Double.valueOf(value).intValue()); dataMap.put(Indicator.MaxDrawdownRecureDate.name(), DateTime .parse(dateStr, DateTimeFormat.forPattern(DateConst.YYYYMMDD)).toString(DateConst.YYYY_MM_DD)); } } if (indicators.contains(Indicator.MaxDrawdownPeakDate)) { String value = dataMap.get(Indicator.MaxDrawdownPeakDate.name()); if (value != null) { String dateStr = String.valueOf(Double.valueOf(value).intValue()); dataMap.put(Indicator.MaxDrawdownPeakDate.name(), DateTime .parse(dateStr, DateTimeFormat.forPattern(DateConst.YYYYMMDD)).toString(DateConst.YYYY_MM_DD)); } } if (indicators.contains(Indicator.MaxDrawdownValleyDate)) { String value = dataMap.get(Indicator.MaxDrawdownValleyDate.name()); if (value != null) { String dateStr = String.valueOf(Double.valueOf(value).intValue()); dataMap.put(Indicator.MaxDrawdownValleyDate.name(), DateTime .parse(dateStr, DateTimeFormat.forPattern(DateConst.YYYYMMDD)).toString(DateConst.YYYY_MM_DD)); } } } public static Map calcRetIndicatorValue(List retList, TimeRange timeRange, Frequency frequency, boolean ifAnnualize, List retIndicatorList, boolean ifConvertPerformanceConsistencyWord, int leastRetNum) { Map retIndicatorValueMap = new HashMap<>(); IndicatorFactory factory = IndicatorFactory.getInstance(); for (Indicator indicator : retIndicatorList) { if (indicator == null) { continue; } Double value = null; if (null == retList) { retIndicatorValueMap.put(indicator.name(), null); continue; } // update by wangzaijun on 2023-04-06 超额胜率支持 if (indicator.name().startsWith("ExcessReturn") || indicator == Indicator.ExcessAriIntervalReturn || indicator == Indicator.ExcessAnnualAriIntervalReturn || indicator == Indicator.WinRate || (retList != null && retList.size() >= leastRetNum) || timeRange == TimeRange.FromSetup) { Rate rate = factory.get(indicator); try { value = rate.calc(retList, frequency, ifAnnualize); } catch (Exception e) { // log.info("计算异常Exception",e.getMessage(),e); value = null; } if (value != null && (value.isNaN() || value.isInfinite() )) { value = null; } else if (value != null) { BigDecimal bigDecimalValue = new BigDecimal(value.toString()); BigDecimal maxBigDecimalValue = new BigDecimal(IndicatorConst.MAX_INDICATOR_VALUE_STRING); BigDecimal minBigDecimalValue = new BigDecimal(IndicatorConst.MIN_INDICATOR_VALUE_STRING); if (bigDecimalValue.compareTo(maxBigDecimalValue) > 0) { retIndicatorValueMap.put(indicator.name(), maxBigDecimalValue.toPlainString()); continue; } else if (bigDecimalValue.compareTo(minBigDecimalValue) < 0) { retIndicatorValueMap.put(indicator.name(), minBigDecimalValue.toPlainString()); continue; } } retIndicatorValueMap.put(indicator.name(), CommonUtil.double2StringPoint6WithoutHalfUp(value)); } else { retIndicatorValueMap.put(indicator.name(), null); } } convertPerformanceConsistency(retIndicatorList, retIndicatorValueMap, ifConvertPerformanceConsistencyWord); return retIndicatorValueMap; } private static void convertPerformanceConsistency(List retIndicatorList, Map retIndicatorValueMap, boolean ifConvertPerformanceConsistencyWord) { if (retIndicatorList.contains(Indicator.PerformanceConsistency) && ifConvertPerformanceConsistencyWord) { String value = retIndicatorValueMap.get(Indicator.PerformanceConsistency.name()); if (value != null) { retIndicatorValueMap.put(Indicator.PerformanceConsistency.name(), PerformanceConsistency.convert2Word(Double.valueOf(value))); } } } /** * 获取标的的有效净值序列 * 截取规则 : * 开始日期 : 1, timeRange == TimeRange.FromSetup - 开始日期直接用入参的开始日期, 其他timeRange根据下方规则截取 * 2. 如果入参的开始日期有净值, 则开始日期直接用入参的开始日期. 否则先往前找四个交易日, 找不到就往后截 * @param secId 标的ID * @param indicatorCalcTimeRangeDto 时间区间 * @param allNavMap 净值map */ public static List getSecIdValidNav(String secId, IndicatorCalcTimeRangeDto indicatorCalcTimeRangeDto, Map> allNavMap, boolean isTrend, Frequency frequency) { //标的的净值序列 List secNavList = allNavMap.get(secId); //标的的净值map key-日期 value-净值 Map secNavMap = new HashMap<>(); //全部的日期序列 List dateList = new ArrayList<>(); for (DateValue dv : secNavList) { secNavMap.put(dv.getDate(),dv.getValue()); dateList.add(dv.getDate()); } boolean isValidIndicatorCalcTimeRangeDto = (null != indicatorCalcTimeRangeDto && !StringUtils.isEmpty(indicatorCalcTimeRangeDto.getStartDate()) && !StringUtils.isEmpty(indicatorCalcTimeRangeDto.getEndDate())); if (isValidIndicatorCalcTimeRangeDto) { TimeRange timeRange = indicatorCalcTimeRangeDto.getTimeRange(); String startDate = indicatorCalcTimeRangeDto.getStartDate(); String endDate = indicatorCalcTimeRangeDto.getEndDate(); //推开始日期 String resultStartDate = null; if (timeRange == TimeRange.FromSetup || timeRange == TimeRange.Custom) { resultStartDate = startDate; } else { //判断startDate是否有净值 Double startNav = secNavMap.get(startDate); if (startNav != null) { resultStartDate = startDate; } else { if (frequency == Frequency.Monthly) { List monthPreDays = indicatorCalcTimeRangeDto.getMonthPreDays(); List monthLaterDays = indicatorCalcTimeRangeDto.getMonthLaterDays(); String preDays = null; String laterDays = null; for (String monthPreDay : monthPreDays) { Double monthPreDayNav = secNavMap.get(monthPreDay); if (monthPreDayNav != null) { preDays = monthPreDay; break; } } for (String monthLaterDay : monthLaterDays) { Double monthLaterDayNav = secNavMap.get(monthLaterDay); if (monthLaterDayNav != null) { laterDays = monthLaterDay; break; } } if (null != preDays || null != laterDays) { if (null == preDays) { resultStartDate = laterDays; } else if (null == laterDays) { resultStartDate = preDays; } else { String monthLastDate = monthPreDays.get(0); //获取距离(剔除交易日) 谁近取谁, 同样近取前面的 int laterMonthDateDistance = 1; for (String monthLaterDay : monthLaterDays) { if (laterDays.equals(monthLaterDay)) { break; } else { boolean isTradingDay = CaffeineLocalCache.getIsTradingDay(monthLaterDay); if (isTradingDay) { laterMonthDateDistance ++; } } } int thisMonthDateDistance = 0; for (String monthPreDay : monthPreDays) { if (preDays.equals(monthPreDay)) { break; } else { boolean isTradingDay = CaffeineLocalCache.getIsTradingDay(monthPreDay); if (isTradingDay) { thisMonthDateDistance ++; } } } if (thisMonthDateDistance <= laterMonthDateDistance) { resultStartDate = preDays; } else { resultStartDate = laterDays; } } } } else { // 获取前四个交易日的集合 从大到小排序 List tradingDayList = indicatorCalcTimeRangeDto.getPreDays(); for (String tradingDay : tradingDayList) { startNav = secNavMap.get(tradingDay); if (startNav != null) { resultStartDate = tradingDay; break; } } } if (resultStartDate == null) { //startDate没有净值, 而且前四天的交易日都没有净值 String firstDate = null; if (secNavList != null && secNavList.size() > 0) { firstDate = secNavList.get(0).getDate(); } if (isTrend || (timeRange == TimeRange.FromThisYear && StringUtils.isNotEmpty(firstDate) && firstDate.compareTo(startDate) >= 0)) { resultStartDate = startDate; } else { return new ArrayList<>(); } } } } indicatorCalcTimeRangeDto.setStartDate(resultStartDate); List validSecNavList = new ArrayList<>(); //截取净值序列 [resultStartDate,endDate] //二分法找净值 Integer endIndex = getMostLeftLessNav(dateList, endDate); Integer startIndex = -1; if (timeRange != TimeRange.Custom) { startIndex = getMostRightThanNav(dateList, resultStartDate); } else { startIndex = getMostLeftLessNav(dateList, resultStartDate); } if (startIndex == -1 || endIndex == -1 || startIndex >= endIndex) { return new ArrayList<>(); } List dateValues = secNavList.subList(startIndex, endIndex + 1); if (dateValues.size() == 0) { return dateValues; } if ( dateValues.get(0).getIsvalid() == null || dateValues.get(0).getIsvalid() == 0 ) { dateValues.get(0).setIsvalid(1); } if (dateValues.get(dateValues.size() - 1).getIsvalid() == null || dateValues.get(dateValues.size() - 1).getIsvalid() == 0) { dateValues.get(dateValues.size() - 1).setIsvalid(1); } for (DateValue dateValue : dateValues) { if (dateValue.getIsvalid() != null && dateValue.getIsvalid() == 1) { DateValue validSecNav = new DateValue(); validSecNav.setIsvalid(dateValue.getIsvalid()); validSecNav.setValue(dateValue.getValue()); validSecNav.setDate(dateValue.getDate()); validSecNavList.add(validSecNav); } } return validSecNavList; } else { return new ArrayList<>(); } } /** * 循环净值序列, 拿出日期序列 排序, 从小到大 * @param navList 净值序列 * @return 日期序列 */ public static List getValidSecNavDateList(List navList) { List validSecNavDateList = new ArrayList<>(); for (DateValue dateValue : navList) { validSecNavDateList.add(dateValue.getDate()); } //排序, 从小到大 Collections.sort(validSecNavDateList); return validSecNavDateList; } /** * 更近入参的时间序列筛选净值序列 * @param navList 净值序列 * @param dateList 时间序列 * @return 有效净值序列 */ public static List filterOtherNav(List navList, List dateList, boolean isTrendIndex) { if (null != navList && navList.size() > 0) { Map dateNavMap = new HashMap<>(); for (DateValue nav : navList) { dateNavMap.put(nav.getDate(), nav); } List validNavList = new ArrayList<>(); for (int i = 0 ; i < dateList.size() ; i++) { DateValue dateValue = new DateValue(); dateValue.setDate(dateList.get(i)); Double value = null; if (dateNavMap.containsKey(dateList.get(i))) { value = dateNavMap.get(dateList.get(i)).getValue(); } else if (!isTrendIndex || i == 0) { //二分法获取小于等于的最接近这个日期的净值 DateValue lessDateValue = getMostLeftNoLessNav(navList, dateList.get(i)); value = lessDateValue.getValue(); } dateValue.setValue(value); dateValue.setIsvalid(1); validNavList.add(dateValue); } return validNavList; } return new ArrayList<>(); } /** * * @param navList 从小到大的净值序列 * @param date 日期 * @return 小于等于 date 的 日期最大的净值 */ private static DateValue getMostLeftNoLessNav(List navList, String date) { if (navList == null || navList.size() == 0) { return new DateValue(); } int L = 0; int R = navList.size() - 1; int ans = -1; while (L <= R) { int mid = (L + R) / 2; if (navList.get(mid).getDate() !=null && navList.get(mid).getDate().compareTo(date) <= 0) { ans = mid; L = mid + 1; } else { R = mid - 1; } } return ans == -1 ? new DateValue(date, null) : navList.get(ans); } /** * * @param dateList 从小到大的净值序列 * @param date 日期 * @return 小于等于 date 的 日期最大的净值 */ public static Integer getMostLeftLessNav(List dateList, String date) { if (dateList == null || dateList.size() == 0) { return -1; } int L = 0; int R = dateList.size() - 1; int ans = -1; while (L <= R) { int mid = (L + R) / 2; if (dateList.get(mid) !=null && dateList.get(mid).compareTo(date) <= 0) { ans = mid; L = mid + 1; } else { R = mid - 1; } } return ans; } /** * * @param dateList 从小到大的净值序列 * @param date 日期 * @return 大于等于 date 的 日期最小的净值 */ public static Integer getMostRightThanNav(List dateList, String date) { if(dateList == null || Objects.requireNonNull(dateList).size() == 0){ return -1; }else if(dateList.get(dateList.size()-1).compareTo(date) < 0){ return dateList.size() - 1; } int low = 0; int high = dateList.size() - 1; while(low < high){ //防止溢出 int mid = low + (high-low)/2; if(dateList.get(mid).compareTo(date) < 0){ low = mid + 1; }else{ high = mid; } } return low; } /** * 获取收益 * @param navList * @param benchmarkRetList * @param riskFreeDateRetMap * @param strategyDateRetMap * @return */ public static List getRet(List navList, List benchmarkRetList, Map riskFreeDateRetMap, Map strategyDateRetMap) { return getRet(navList, benchmarkRetList, riskFreeDateRetMap, strategyDateRetMap, false); } /** * 获取收益 * @param navList * @param benchmarkRetList * @param riskFreeDateRetMap * @param strategyDateRetMap * @return */ public static List getRet(List navList, List benchmarkRetList, Map riskFreeDateRetMap, Map strategyDateRetMap, Boolean isTrend) { List retList = new ArrayList<>(); if (navList == null || navList.size() == 0) { return retList; } //排序 从小到大 Collections.sort(navList, new Comparator() { @Override public int compare(DateValue o1, DateValue o2) { return o1.getDate().compareTo(o2.getDate()); } }); Map benchmarkRetMap = new HashMap<>(); if (benchmarkRetList != null) { for (CompoundRet benchmarkRet : benchmarkRetList) { benchmarkRetMap.put(benchmarkRet.getEndDate(), benchmarkRet); } } Double preNav = 0.0; for (int i = 0 ; i < navList.size() ; i++) { CompoundRet compoundRet = new CompoundRet(); Double ret = null; if (i == 0 && isTrend && navList.get(0).getValue() != null) { ret = 0.0; } String date = navList.get(i).getDate(); compoundRet.setEndDate(date); if ( i != 0 ) { Double nav = navList.get(i).getValue(); if (preNav != null && nav!= null) { BigDecimal preNavBigDecimal = new BigDecimal(preNav.toString()); BigDecimal navBigDecimal = new BigDecimal(nav.toString()); BigDecimal bigDecimalRet = BigDecimalUtils.subtract(BigDecimalUtils.divide(navBigDecimal, preNavBigDecimal), new BigDecimal("1")); if (null != bigDecimalRet) { ret = bigDecimalRet.doubleValue(); } if (null != riskFreeDateRetMap) { compoundRet.setRetOfRf(riskFreeDateRetMap.get(date) != null ? riskFreeDateRetMap.get(date).getRetOfFund() : null); } if (null != strategyDateRetMap) { compoundRet.setRetOfStg(strategyDateRetMap.get(date) != null ? strategyDateRetMap.get(date).getRetOfFund() : null); } if (benchmarkRetList != null) { compoundRet.setRetOfBmk(benchmarkRetMap.get(date) != null ? benchmarkRetMap.get(date).getRetOfFund() : null); } } } compoundRet.setRetOfFund(ret); retList.add(compoundRet); if (isTrend) { if (preNav == null || preNav.compareTo(0.0) == 0) { preNav = navList.get(i).getValue(); } } else { preNav = navList.get(i).getValue(); } } return retList; } public static List calcExtraRetGeo(List secRetList, List benchmarkRetList) { List extraRetAriList = new ArrayList<>(); Map benchmarkRetMap = new HashMap<>(); for (CompoundRet compoundRet : benchmarkRetList) { benchmarkRetMap.put(compoundRet.getEndDate(), compoundRet); } for (CompoundRet compoundRet : secRetList) { CompoundRet extraRetAri = new CompoundRet(); Double secRet = compoundRet.getRetOfFund(); CompoundRet benchmarkRetDto = benchmarkRetMap.get(compoundRet.getEndDate()); if (null == benchmarkRetDto || null ==secRet || benchmarkRetDto.getRetOfFund() == null ) { extraRetAri.setEndDate(compoundRet.getEndDate()); extraRetAri.setRetOfFund(null); } else if (benchmarkRetDto.getRetOfFund().compareTo(0.0) == 0) { extraRetAri.setEndDate(compoundRet.getEndDate()); extraRetAri.setRetOfFund(0.0); } else { Double molecule = secRet + 1; Double denominator = benchmarkRetDto.getRetOfFund() + 1; Double benchmarkRet = BigDecimalUtils.subtract(BigDecimalUtils.divide(new BigDecimal(molecule), new BigDecimal(denominator)), new BigDecimal("1")).doubleValue(); extraRetAri.setEndDate(compoundRet.getEndDate()); extraRetAri.setRetOfFund(benchmarkRet); } extraRetAriList.add(extraRetAri); } return extraRetAriList; } public static void getTrendData(IndicatorCalcPropertyDto indicatorCalcPropertyDto) { List trendTypeList = indicatorCalcPropertyDto.getIndicatorCalcReq().getTrendTypeList(); List benchmarkRetList = null; if (indicatorCalcPropertyDto.getIndicatorCalcReq().getFixedIncome() != null) { benchmarkRetList = new ArrayList<>(); List retList = indicatorCalcPropertyDto.getSecData().getRetList(); for (CompoundRet ret : retList) { CompoundRet bRet = new CompoundRet(); bRet.setEndDate(ret.getEndDate()); bRet.setRetOfFund(BigDecimalUtils.divide(indicatorCalcPropertyDto.getIndicatorCalcReq().getFixedIncome(), new BigDecimal("100")).doubleValue()); benchmarkRetList.add(bRet); } } else { benchmarkRetList = indicatorCalcPropertyDto.getBenchmarkData().getBenchmarkRetList(); } for (TrendType trendType : trendTypeList) { TrendFactory trendFactory = TrendFactory.getInstance(); Trend trend = trendFactory.get(trendType); //标的的走势数据 - start if (TrendType.Nav == trendType) { List navList = trend.getDateValueTrend(null, indicatorCalcPropertyDto.getSecData().getNavList(), null); indicatorCalcPropertyDto.getSecData().setNavList(navList); List trendList = datevalueToDouble(navList); indicatorCalcPropertyDto.getSecData().getTrendValueMap().put(trendType, trendList); } else if (TrendType.Ret == trendType) { List retList = trend.getCompoundRetTrend(indicatorCalcPropertyDto.getSecData().getNavList(), null, null); indicatorCalcPropertyDto.getSecData().setRetList(retList); List trendList = compoundRetToDouble(retList); indicatorCalcPropertyDto.getSecData().getTrendValueMap().put(trendType, trendList); } else if (TrendType.ExtraNav == trendType) { List extraNavList = trend.getDateValueTrend(null, indicatorCalcPropertyDto.getSecData().getNavList(), indicatorCalcPropertyDto.getBenchmarkData().getBenchmarkNavList()); indicatorCalcPropertyDto.getSecData().setExtraNavList(extraNavList); List trendList = datevalueToDouble(extraNavList); indicatorCalcPropertyDto.getSecData().getTrendValueMap().put(trendType, trendList); } else if (TrendType.ExtraRetAri == trendType ) { List extraRetList = trend.getCompoundRetTrend(null, indicatorCalcPropertyDto.getSecData().getRetList(), benchmarkRetList); indicatorCalcPropertyDto.getSecData().setExtraRetAriList(extraRetList); List trendList = compoundRetToDouble(extraRetList); indicatorCalcPropertyDto.getSecData().getTrendValueMap().put(trendType, trendList); } else if (TrendType.ExtraRetGeo == trendType ) { List extraRetList = trend.getCompoundRetTrend(null, indicatorCalcPropertyDto.getSecData().getRetList(), benchmarkRetList); indicatorCalcPropertyDto.getSecData().setExtraRetGeoList(extraRetList); List trendList = compoundRetToDouble(extraRetList); indicatorCalcPropertyDto.getSecData().getTrendValueMap().put(trendType, trendList); } else if (TrendType.DrawdownTrend == trendType) { List drawDownValueList = trend.getDateValueTrend(indicatorCalcPropertyDto.getDateList(), indicatorCalcPropertyDto.getSecData().getNavList(), null); indicatorCalcPropertyDto.getSecData().setDrawdownList(drawDownValueList); List trendList = datevalueToDouble(drawDownValueList); indicatorCalcPropertyDto.getSecData().getTrendValueMap().put(trendType, trendList); } else if (TrendType.ExtraDrawdownTrend == trendType) { List extraDrawDownValueList = trend.getDateValueTrend(indicatorCalcPropertyDto.getDateList(), indicatorCalcPropertyDto.getSecData().getNavList(), indicatorCalcPropertyDto.getBenchmarkData().getBenchmarkNavList()); indicatorCalcPropertyDto.getSecData().setDrawdownList(extraDrawDownValueList); List trendList = datevalueToDouble(extraDrawDownValueList); indicatorCalcPropertyDto.getSecData().getTrendValueMap().put(trendType, trendList); } else if (TrendType.NetValueChange == trendType) { List netValueChangeList = trend.getCompoundRetTrend(indicatorCalcPropertyDto.getSecData().getNavList(), null, null); List trendList = compoundRetToDouble(netValueChangeList); indicatorCalcPropertyDto.getSecData().getTrendValueMap().put(trendType, trendList); } else if (TrendType.OrigNav == trendType) { List navList = trend.getDateValueTrend(null, indicatorCalcPropertyDto.getSecData().getOriNavList(), null); indicatorCalcPropertyDto.getSecData().setNavList(navList); List trendList = datevalueToDouble(navList); indicatorCalcPropertyDto.getSecData().getTrendValueMap().put(trendType, trendList); } //标的的走势数据 - end //基准 和 指数 的走势数据 - start List indexIdList = indicatorCalcPropertyDto.getIndicatorCalcReq().getIndexIdList(); if (TrendType.Nav == trendType || TrendType.ExtraNav == trendType) { Trend navTrend = trendFactory.get(TrendType.Nav); List benchmarkNavList = navTrend.getDateValueTrend(null, indicatorCalcPropertyDto.getBenchmarkData().getBenchmarkNavList(), null); indicatorCalcPropertyDto.getBenchmarkData().setBenchmarkNavList(benchmarkNavList); List benchmarkTrendList = datevalueToDouble(benchmarkNavList); indicatorCalcPropertyDto.getBenchmarkData().getBenchmarkTrendValueMap().put(TrendType.Nav, benchmarkTrendList); Map> indexNavMap = new HashMap<>(); for (String index : indexIdList) { List indexNavList = navTrend.getDateValueTrend(null, indicatorCalcPropertyDto.getIndexData().getIndexNavMap().get(index), null); indexNavMap.put(index, indexNavList); List indexTrendList = datevalueToDouble(indexNavList); Map>> indexTrendValueMapMap = indicatorCalcPropertyDto.getIndexData().getIndexTrendValueMap(); if (indexTrendValueMapMap.containsKey(index)) { indexTrendValueMapMap.get(index).put(TrendType.Nav,indexTrendList); } else { Map> indexTrendValueMap = new HashMap<>(); indexTrendValueMap.put(TrendType.Nav, indexTrendList); indexTrendValueMapMap.put(index, indexTrendValueMap); } } indicatorCalcPropertyDto.getIndexData().setIndexNavMap(indexNavMap); } else if (TrendType.Ret == trendType || TrendType.ExtraRetAri == trendType || TrendType.ExtraRetGeo == trendType) { Trend retTrend = trendFactory.get(TrendType.Ret); List retList = retTrend.getCompoundRetTrend(indicatorCalcPropertyDto.getBenchmarkData().getBenchmarkNavList(), null, null); indicatorCalcPropertyDto.getBenchmarkData().setBenchmarkRetList(retList); List benchmarkTrendList = compoundRetToDouble(retList); indicatorCalcPropertyDto.getBenchmarkData().getBenchmarkTrendValueMap().put(TrendType.Ret, benchmarkTrendList); Map> indexRetListMap = new HashMap<>(); for (String index : indexIdList) { List indexRetList = retTrend.getCompoundRetTrend(indicatorCalcPropertyDto.getIndexData().getIndexNavMap().get(index), null, null); indexRetListMap.put(index, indexRetList); List indexTrendList = compoundRetToDouble(indexRetList); Map>> indexTrendValueMapMap = indicatorCalcPropertyDto.getIndexData().getIndexTrendValueMap(); if (indexTrendValueMapMap.containsKey(index)) { indexTrendValueMapMap.get(index).put(TrendType.Ret,indexTrendList); } else { Map> indexTrendValueMap = new HashMap<>(); indexTrendValueMap.put(TrendType.Ret, indexTrendList); indexTrendValueMapMap.put(index, indexTrendValueMap); } } indicatorCalcPropertyDto.getIndexData().setIndexRetListMap(indexRetListMap); } else if (TrendType.DrawdownTrend == trendType || TrendType.ExtraDrawdownTrend == trendType) { Trend drawdownTrendTrend = trendFactory.get(TrendType.DrawdownTrend); List benchmarkDrawDownValueList = drawdownTrendTrend.getDateValueTrend(indicatorCalcPropertyDto.getDateList(), indicatorCalcPropertyDto.getBenchmarkData().getBenchmarkNavList(), null); indicatorCalcPropertyDto.getBenchmarkData().setBenchmarkDrawdown(benchmarkDrawDownValueList); List benchmarkTrendList = datevalueToDouble(benchmarkDrawDownValueList); indicatorCalcPropertyDto.getBenchmarkData().getBenchmarkTrendValueMap().put(TrendType.DrawdownTrend, benchmarkTrendList); Map> indexDrawdownMap = new HashMap<>(); for (String index : indexIdList) { List indexDrawDownValueList = drawdownTrendTrend.getDateValueTrend(indicatorCalcPropertyDto.getDateList(), indicatorCalcPropertyDto.getIndexData().getIndexNavMap().get(index), null); indexDrawdownMap.put(index, indexDrawDownValueList); List indexTrendList = datevalueToDouble(indexDrawDownValueList); Map>> indexTrendValueMapMap = indicatorCalcPropertyDto.getIndexData().getIndexTrendValueMap(); if (indexTrendValueMapMap.containsKey(index)) { indexTrendValueMapMap.get(index).put(TrendType.DrawdownTrend,indexTrendList); } else { Map> indexTrendValueMap = new HashMap<>(); indexTrendValueMap.put(TrendType.DrawdownTrend, indexTrendList); indexTrendValueMapMap.put(index, indexTrendValueMap); } } indicatorCalcPropertyDto.getIndexData().setIndexDrawdownMap(indexDrawdownMap); } else if (TrendType.OrigNav == trendType) { Trend navTrend = trendFactory.get(TrendType.Nav); List benchmarkNavList = navTrend.getDateValueTrend(null, indicatorCalcPropertyDto.getBenchmarkData().getOriBenchmarkNavList(), null); indicatorCalcPropertyDto.getBenchmarkData().setOriBenchmarkNavList(benchmarkNavList); List benchmarkTrendList = datevalueToDouble(benchmarkNavList); indicatorCalcPropertyDto.getBenchmarkData().getBenchmarkTrendValueMap().put(TrendType.OrigNav, benchmarkTrendList); Map> indexNavMap = new HashMap<>(); for (String index : indexIdList) { List indexNavList = navTrend.getDateValueTrend(null, indicatorCalcPropertyDto.getIndexData().getOriIndexNavMap().get(index), null); indexNavMap.put(index, indexNavList); List indexTrendList = datevalueToDouble(indexNavList); Map>> indexTrendValueMapMap = indicatorCalcPropertyDto.getIndexData().getIndexTrendValueMap(); if (indexTrendValueMapMap.containsKey(index)) { indexTrendValueMapMap.get(index).put(TrendType.OrigNav,indexTrendList); } else { Map> indexTrendValueMap = new HashMap<>(); indexTrendValueMap.put(TrendType.OrigNav, indexTrendList); indexTrendValueMapMap.put(index, indexTrendValueMap); } } indicatorCalcPropertyDto.getIndexData().setOriIndexNavMap(indexNavMap); } //基准 和 指数 的走势数据 - end } } public static List navNormalize(List dateValueList) { Double firstValue = null; List navNormalizeList = new ArrayList<>(); for (DateValue dateValue : dateValueList) { DateValue navNormalize = new DateValue(); navNormalize.setDate(dateValue.getDate()); navNormalize.setIsvalid(dateValue.getIsvalid()); if (dateValue.getValue() == null || dateValue.getValue().compareTo(0.0) == 0) { navNormalize.setValue(0.0); } else { if (firstValue == null) { firstValue = dateValue.getValue(); } navNormalize.setValue(dateValue.getValue() / firstValue); } navNormalizeList.add(navNormalize); } return navNormalizeList; } private static List datevalueToDouble(List dateValueList) { List doubles = new ArrayList<>(); for (DateValue dateValue : dateValueList) { doubles.add(dateValue.getValue()); } return doubles; } private static List compoundRetToDouble(List list) { List doubles = new ArrayList<>(); for (CompoundRet compoundRet : list) { doubles.add(compoundRet.getRetOfFund()); } return doubles; } }