123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810 |
- 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<Double> getFundRetList(List<CompoundRet> list) {
- List<Double> doubleList = new ArrayList<>();
- for (CompoundRet value : list) {
- if (value.getRetOfFund() != null) {
- doubleList.add(value.getRetOfFund());
- }
- }
- return doubleList;
- }
- public static Map<String, String> calcNavIndicatorValue(List<DateValue> navList, List<Indicator> navIndicatorList) {
- IndicatorFactory factory = IndicatorFactory.getInstance();
- Map<String, String> 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<String, String> dataMap, List<Indicator> 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<String, String> calcRetIndicatorValue(List<CompoundRet> retList, TimeRange timeRange,
- Frequency frequency, boolean ifAnnualize, List<Indicator> retIndicatorList, boolean ifConvertPerformanceConsistencyWord, int leastRetNum) {
- Map<String,String> 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<Indicator> retIndicatorList, Map<String, String> 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<DateValue> getSecIdValidNav(String secId, IndicatorCalcTimeRangeDto indicatorCalcTimeRangeDto, Map<String, List<DateValue>> allNavMap, boolean isTrend, Frequency frequency) {
- //标的的净值序列
- List<DateValue> secNavList = allNavMap.get(secId);
- //标的的净值map key-日期 value-净值
- Map<String,Double> secNavMap = new HashMap<>();
- //全部的日期序列
- List<String> 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<String> monthPreDays = indicatorCalcTimeRangeDto.getMonthPreDays();
- List<String> 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<String> 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<DateValue> 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<DateValue> 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<String> getValidSecNavDateList(List<DateValue> navList) {
- List<String> validSecNavDateList = new ArrayList<>();
- for (DateValue dateValue : navList) {
- validSecNavDateList.add(dateValue.getDate());
- }
- //排序, 从小到大
- Collections.sort(validSecNavDateList);
- return validSecNavDateList;
- }
- /**
- * 更近入参的时间序列筛选净值序列
- * @param navList 净值序列
- * @param dateList 时间序列
- * @return 有效净值序列
- */
- public static List<DateValue> filterOtherNav(List<DateValue> navList, List<String> dateList, boolean isTrendIndex) {
- if (null != navList && navList.size() > 0) {
- Map<String, DateValue> dateNavMap = new HashMap<>();
- for (DateValue nav : navList) {
- dateNavMap.put(nav.getDate(), nav);
- }
- List<DateValue> 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<DateValue> 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<String> 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<String> 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<CompoundRet> getRet(List<DateValue> navList, List<CompoundRet> benchmarkRetList, Map<String, CompoundRet> riskFreeDateRetMap, Map<String, CompoundRet> strategyDateRetMap) {
- return getRet(navList, benchmarkRetList, riskFreeDateRetMap, strategyDateRetMap, false);
- }
- /**
- * 获取收益
- * @param navList
- * @param benchmarkRetList
- * @param riskFreeDateRetMap
- * @param strategyDateRetMap
- * @return
- */
- public static List<CompoundRet> getRet(List<DateValue> navList, List<CompoundRet> benchmarkRetList, Map<String, CompoundRet> riskFreeDateRetMap, Map<String, CompoundRet> strategyDateRetMap, Boolean isTrend) {
- List<CompoundRet> retList = new ArrayList<>();
- if (navList == null || navList.size() == 0) {
- return retList;
- }
- //排序 从小到大
- Collections.sort(navList, new Comparator<DateValue>() {
- @Override
- public int compare(DateValue o1, DateValue o2) {
- return o1.getDate().compareTo(o2.getDate());
- }
- });
- Map<String, CompoundRet> 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<CompoundRet> calcExtraRetGeo(List<CompoundRet> secRetList, List<CompoundRet> benchmarkRetList) {
- List<CompoundRet> extraRetAriList = new ArrayList<>();
- Map<String, CompoundRet> 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<TrendType> trendTypeList = indicatorCalcPropertyDto.getIndicatorCalcReq().getTrendTypeList();
- List<CompoundRet> benchmarkRetList = null;
- if (indicatorCalcPropertyDto.getIndicatorCalcReq().getFixedIncome() != null) {
- benchmarkRetList = new ArrayList<>();
- List<CompoundRet> 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<DateValue> navList = trend.getDateValueTrend(null, indicatorCalcPropertyDto.getSecData().getNavList(), null);
- indicatorCalcPropertyDto.getSecData().setNavList(navList);
- List<Double> trendList = datevalueToDouble(navList);
- indicatorCalcPropertyDto.getSecData().getTrendValueMap().put(trendType, trendList);
- } else if (TrendType.Ret == trendType) {
- List<CompoundRet> retList = trend.getCompoundRetTrend(indicatorCalcPropertyDto.getSecData().getNavList(), null, null);
- indicatorCalcPropertyDto.getSecData().setRetList(retList);
- List<Double> trendList = compoundRetToDouble(retList);
- indicatorCalcPropertyDto.getSecData().getTrendValueMap().put(trendType, trendList);
- } else if (TrendType.ExtraNav == trendType) {
- List<DateValue> extraNavList = trend.getDateValueTrend(null, indicatorCalcPropertyDto.getSecData().getNavList(), indicatorCalcPropertyDto.getBenchmarkData().getBenchmarkNavList());
- indicatorCalcPropertyDto.getSecData().setExtraNavList(extraNavList);
- List<Double> trendList = datevalueToDouble(extraNavList);
- indicatorCalcPropertyDto.getSecData().getTrendValueMap().put(trendType, trendList);
- } else if (TrendType.ExtraRetAri == trendType ) {
- List<CompoundRet> extraRetList = trend.getCompoundRetTrend(null, indicatorCalcPropertyDto.getSecData().getRetList(), benchmarkRetList);
- indicatorCalcPropertyDto.getSecData().setExtraRetAriList(extraRetList);
- List<Double> trendList = compoundRetToDouble(extraRetList);
- indicatorCalcPropertyDto.getSecData().getTrendValueMap().put(trendType, trendList);
- } else if (TrendType.ExtraRetGeo == trendType ) {
- List<CompoundRet> extraRetList = trend.getCompoundRetTrend(null, indicatorCalcPropertyDto.getSecData().getRetList(), benchmarkRetList);
- indicatorCalcPropertyDto.getSecData().setExtraRetGeoList(extraRetList);
- List<Double> trendList = compoundRetToDouble(extraRetList);
- indicatorCalcPropertyDto.getSecData().getTrendValueMap().put(trendType, trendList);
- } else if (TrendType.DrawdownTrend == trendType) {
- List<DateValue> drawDownValueList = trend.getDateValueTrend(indicatorCalcPropertyDto.getDateList(), indicatorCalcPropertyDto.getSecData().getNavList(), null);
- indicatorCalcPropertyDto.getSecData().setDrawdownList(drawDownValueList);
- List<Double> trendList = datevalueToDouble(drawDownValueList);
- indicatorCalcPropertyDto.getSecData().getTrendValueMap().put(trendType, trendList);
- } else if (TrendType.ExtraDrawdownTrend == trendType) {
- List<DateValue> extraDrawDownValueList = trend.getDateValueTrend(indicatorCalcPropertyDto.getDateList(),
- indicatorCalcPropertyDto.getSecData().getNavList(), indicatorCalcPropertyDto.getBenchmarkData().getBenchmarkNavList());
- indicatorCalcPropertyDto.getSecData().setDrawdownList(extraDrawDownValueList);
- List<Double> trendList = datevalueToDouble(extraDrawDownValueList);
- indicatorCalcPropertyDto.getSecData().getTrendValueMap().put(trendType, trendList);
- } else if (TrendType.NetValueChange == trendType) {
- List<CompoundRet> netValueChangeList = trend.getCompoundRetTrend(indicatorCalcPropertyDto.getSecData().getNavList(), null, null);
- List<Double> trendList = compoundRetToDouble(netValueChangeList);
- indicatorCalcPropertyDto.getSecData().getTrendValueMap().put(trendType, trendList);
- } else if (TrendType.OrigNav == trendType) {
- List<DateValue> navList = trend.getDateValueTrend(null, indicatorCalcPropertyDto.getSecData().getOriNavList(), null);
- indicatorCalcPropertyDto.getSecData().setNavList(navList);
- List<Double> trendList = datevalueToDouble(navList);
- indicatorCalcPropertyDto.getSecData().getTrendValueMap().put(trendType, trendList);
- }
- //标的的走势数据 - end
- //基准 和 指数 的走势数据 - start
- List<String> indexIdList = indicatorCalcPropertyDto.getIndicatorCalcReq().getIndexIdList();
- if (TrendType.Nav == trendType || TrendType.ExtraNav == trendType) {
- Trend navTrend = trendFactory.get(TrendType.Nav);
- List<DateValue> benchmarkNavList = navTrend.getDateValueTrend(null, indicatorCalcPropertyDto.getBenchmarkData().getBenchmarkNavList(), null);
- indicatorCalcPropertyDto.getBenchmarkData().setBenchmarkNavList(benchmarkNavList);
- List<Double> benchmarkTrendList = datevalueToDouble(benchmarkNavList);
- indicatorCalcPropertyDto.getBenchmarkData().getBenchmarkTrendValueMap().put(TrendType.Nav, benchmarkTrendList);
- Map<String, List<DateValue>> indexNavMap = new HashMap<>();
- for (String index : indexIdList) {
- List<DateValue> indexNavList = navTrend.getDateValueTrend(null, indicatorCalcPropertyDto.getIndexData().getIndexNavMap().get(index), null);
- indexNavMap.put(index, indexNavList);
- List<Double> indexTrendList = datevalueToDouble(indexNavList);
- Map<String, Map<TrendType, List<Double>>> indexTrendValueMapMap = indicatorCalcPropertyDto.getIndexData().getIndexTrendValueMap();
- if (indexTrendValueMapMap.containsKey(index)) {
- indexTrendValueMapMap.get(index).put(TrendType.Nav,indexTrendList);
- } else {
- Map<TrendType, List<Double>> 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<CompoundRet> retList = retTrend.getCompoundRetTrend(indicatorCalcPropertyDto.getBenchmarkData().getBenchmarkNavList(), null, null);
- indicatorCalcPropertyDto.getBenchmarkData().setBenchmarkRetList(retList);
- List<Double> benchmarkTrendList = compoundRetToDouble(retList);
- indicatorCalcPropertyDto.getBenchmarkData().getBenchmarkTrendValueMap().put(TrendType.Ret, benchmarkTrendList);
- Map<String, List<CompoundRet>> indexRetListMap = new HashMap<>();
- for (String index : indexIdList) {
- List<CompoundRet> indexRetList = retTrend.getCompoundRetTrend(indicatorCalcPropertyDto.getIndexData().getIndexNavMap().get(index), null, null);
- indexRetListMap.put(index, indexRetList);
- List<Double> indexTrendList = compoundRetToDouble(indexRetList);
- Map<String, Map<TrendType, List<Double>>> indexTrendValueMapMap = indicatorCalcPropertyDto.getIndexData().getIndexTrendValueMap();
- if (indexTrendValueMapMap.containsKey(index)) {
- indexTrendValueMapMap.get(index).put(TrendType.Ret,indexTrendList);
- } else {
- Map<TrendType, List<Double>> 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<DateValue> benchmarkDrawDownValueList = drawdownTrendTrend.getDateValueTrend(indicatorCalcPropertyDto.getDateList(), indicatorCalcPropertyDto.getBenchmarkData().getBenchmarkNavList(), null);
- indicatorCalcPropertyDto.getBenchmarkData().setBenchmarkDrawdown(benchmarkDrawDownValueList);
- List<Double> benchmarkTrendList = datevalueToDouble(benchmarkDrawDownValueList);
- indicatorCalcPropertyDto.getBenchmarkData().getBenchmarkTrendValueMap().put(TrendType.DrawdownTrend, benchmarkTrendList);
- Map<String, List<DateValue>> indexDrawdownMap = new HashMap<>();
- for (String index : indexIdList) {
- List<DateValue> indexDrawDownValueList = drawdownTrendTrend.getDateValueTrend(indicatorCalcPropertyDto.getDateList(), indicatorCalcPropertyDto.getIndexData().getIndexNavMap().get(index), null);
- indexDrawdownMap.put(index, indexDrawDownValueList);
- List<Double> indexTrendList = datevalueToDouble(indexDrawDownValueList);
- Map<String, Map<TrendType, List<Double>>> indexTrendValueMapMap = indicatorCalcPropertyDto.getIndexData().getIndexTrendValueMap();
- if (indexTrendValueMapMap.containsKey(index)) {
- indexTrendValueMapMap.get(index).put(TrendType.DrawdownTrend,indexTrendList);
- } else {
- Map<TrendType, List<Double>> 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<DateValue> benchmarkNavList = navTrend.getDateValueTrend(null, indicatorCalcPropertyDto.getBenchmarkData().getOriBenchmarkNavList(), null);
- indicatorCalcPropertyDto.getBenchmarkData().setOriBenchmarkNavList(benchmarkNavList);
- List<Double> benchmarkTrendList = datevalueToDouble(benchmarkNavList);
- indicatorCalcPropertyDto.getBenchmarkData().getBenchmarkTrendValueMap().put(TrendType.OrigNav, benchmarkTrendList);
- Map<String, List<DateValue>> indexNavMap = new HashMap<>();
- for (String index : indexIdList) {
- List<DateValue> indexNavList = navTrend.getDateValueTrend(null, indicatorCalcPropertyDto.getIndexData().getOriIndexNavMap().get(index), null);
- indexNavMap.put(index, indexNavList);
- List<Double> indexTrendList = datevalueToDouble(indexNavList);
- Map<String, Map<TrendType, List<Double>>> indexTrendValueMapMap = indicatorCalcPropertyDto.getIndexData().getIndexTrendValueMap();
- if (indexTrendValueMapMap.containsKey(index)) {
- indexTrendValueMapMap.get(index).put(TrendType.OrigNav,indexTrendList);
- } else {
- Map<TrendType, List<Double>> indexTrendValueMap = new HashMap<>();
- indexTrendValueMap.put(TrendType.OrigNav, indexTrendList);
- indexTrendValueMapMap.put(index, indexTrendValueMap);
- }
- }
- indicatorCalcPropertyDto.getIndexData().setOriIndexNavMap(indexNavMap);
- }
- //基准 和 指数 的走势数据 - end
- }
- }
- public static List<DateValue> navNormalize(List<DateValue> dateValueList) {
- Double firstValue = null;
- List<DateValue> 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<Double> datevalueToDouble(List<DateValue> dateValueList) {
- List<Double> doubles = new ArrayList<>();
- for (DateValue dateValue : dateValueList) {
- doubles.add(dateValue.getValue());
- }
- return doubles;
- }
- private static List<Double> compoundRetToDouble(List<CompoundRet> list) {
- List<Double> doubles = new ArrayList<>();
- for (CompoundRet compoundRet : list) {
- doubles.add(compoundRet.getRetOfFund());
- }
- return doubles;
- }
- }
|