|
@@ -0,0 +1,946 @@
|
|
|
+//package com.smppw.analysis.domain.manager.performance;
|
|
|
+//
|
|
|
+//import cn.hutool.core.collection.CollUtil;
|
|
|
+//import cn.hutool.core.collection.CollectionUtil;
|
|
|
+//import cn.hutool.core.collection.ListUtil;
|
|
|
+//import cn.hutool.core.date.DateUtil;
|
|
|
+//import cn.hutool.core.map.MapUtil;
|
|
|
+//import cn.hutool.core.text.CharSequenceUtil;
|
|
|
+//import cn.hutool.core.util.NumberUtil;
|
|
|
+//import cn.hutool.core.util.StrUtil;
|
|
|
+//
|
|
|
+//import com.smppw.analysis.domain.dto.performance.*;
|
|
|
+//import com.smppw.analysis.infrastructure.consts.WinRateBmk;
|
|
|
+//import com.smppw.analysis.infrastructure.exception.APIException;
|
|
|
+//import com.smppw.common.pojo.IStrategy;
|
|
|
+//import com.smppw.common.pojo.dto.CompoundRet;
|
|
|
+//import com.smppw.common.pojo.dto.DateRange;
|
|
|
+//import com.smppw.common.pojo.dto.calc.*;
|
|
|
+//import com.smppw.common.pojo.dto.indicator.CalcMultipleSecMultipleTimeRangeIndicatorReq;
|
|
|
+//import com.smppw.common.pojo.dto.indicator.DateIntervalDto;
|
|
|
+//import com.smppw.common.pojo.enums.*;
|
|
|
+//import com.smppw.common.pojo.enums.strategy.Strategy;
|
|
|
+//import com.smppw.common.rollrange.RollingSpliter;
|
|
|
+//import com.smppw.constants.Consts;
|
|
|
+//import com.smppw.utils.CalcUtils;
|
|
|
+//import com.smppw.utils.CommonUtil;
|
|
|
+//import com.smppw.utils.NavUtil;
|
|
|
+//import com.smppw.utils.StrategyHandleUtils;
|
|
|
+//import lombok.extern.slf4j.Slf4j;
|
|
|
+//import org.apache.commons.lang3.StringUtils;
|
|
|
+//import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+//import org.springframework.beans.factory.annotation.Qualifier;
|
|
|
+//import org.springframework.jdbc.core.JdbcTemplate;
|
|
|
+//import org.springframework.stereotype.Service;
|
|
|
+//
|
|
|
+//import java.io.IOException;
|
|
|
+//import java.math.BigDecimal;
|
|
|
+//import java.util.*;
|
|
|
+//import java.util.function.Function;
|
|
|
+//import java.util.stream.Collectors;
|
|
|
+//
|
|
|
+//
|
|
|
+///**
|
|
|
+// * @author wangzaijun
|
|
|
+// * @date 2023/3/3 17:22
|
|
|
+// * @description 业绩表现页面的所有接口服务,包含基金、机构和经理
|
|
|
+// */
|
|
|
+//@Service
|
|
|
+//@Slf4j
|
|
|
+//public class PerformanceServiceImpl extends AbstractPerformanceService {
|
|
|
+// /**
|
|
|
+// * 指数成分类型: 1-表示融智策略指数;2-表示融智获奖指数;
|
|
|
+// */
|
|
|
+// public static final int COMPONENT_TYPE_STRATEGY = 1;
|
|
|
+//
|
|
|
+// private static final String ONE = "1";
|
|
|
+// private static final String TWO = "2";
|
|
|
+//
|
|
|
+// private static final List<String> TYPE_LIST = ListUtil.of(ONE, TWO);
|
|
|
+//
|
|
|
+// @Autowired
|
|
|
+// @Qualifier("jdbcTemplateReportBuilder")
|
|
|
+// private JdbcTemplate jdbcTemplate;
|
|
|
+// @Autowired
|
|
|
+// private RankRatService rankRatService;
|
|
|
+// @Autowired
|
|
|
+// private IndexPerformanceBaseService indexPerformanceBaseService;
|
|
|
+// @Autowired
|
|
|
+// private FundHeadInfoBaseService fundHeadInfoBaseService;
|
|
|
+// @Autowired
|
|
|
+// private ManagerHeadInfoBaseService managerHeadInfoBaseService;
|
|
|
+// @Autowired
|
|
|
+// private CompanyHeadInfoBaseService companyHeadInfoBaseService;
|
|
|
+// @Autowired
|
|
|
+// private ManagerInfoImpl managerInfo;
|
|
|
+// @Autowired
|
|
|
+// private MonetaryFundProfitBaseService monetaryFundProfitBaseService;
|
|
|
+//
|
|
|
+// @Autowired
|
|
|
+// private CmPublicCompanyStatisHistoryDAO cmPublicCompanyStatisHistoryDAO;
|
|
|
+// private UserPermissionService userPermissionService;
|
|
|
+//
|
|
|
+// @Autowired
|
|
|
+// private FundManagerMappingDOMapper fundManagerMappingDOMapper;
|
|
|
+//
|
|
|
+// @Autowired
|
|
|
+// private MfAdvisorScaleRankMapper mfAdvisorScaleRankMapper;
|
|
|
+//
|
|
|
+// public PerformanceServiceImpl(NavService navService, InfoService infoService, SecId2NameService secId2NameService,
|
|
|
+// BaseIndicatorServiceV2 baseIndicatorServiceV2, UserPermissionService userPermissionService) {
|
|
|
+// super(navService, infoService, secId2NameService, baseIndicatorServiceV2);
|
|
|
+// this.userPermissionService = userPermissionService;
|
|
|
+// }
|
|
|
+//
|
|
|
+// /**
|
|
|
+// * 计算收益风险指标,包括部分几何指标
|
|
|
+// *
|
|
|
+// * @param params /
|
|
|
+// * @return /
|
|
|
+// */
|
|
|
+// public Map<String, Object> rateRiskIndicators(IndicatorParams params, List<Indicator> indicators, List<Indicator> geoIndicators) {
|
|
|
+// try {
|
|
|
+// // 1.参数处理
|
|
|
+// this.checkParams(params);
|
|
|
+// List<String> refIds = params.getFundId();
|
|
|
+// List<String> secIds = this.getSecIdsByParams(params);
|
|
|
+// // 差集求指数id集合,包括基�
|
|
|
+// List<String> indexIds = CollectionUtil.subtractToList(secIds, refIds);
|
|
|
+// String riskOfFreeId = params.getRiskOfFreeId();
|
|
|
+// Double riskOfFreeValue = params.getRiskOfFreeValue();
|
|
|
+// if (StrUtil.isBlank(riskOfFreeId)) {
|
|
|
+// riskOfFreeId = Consts.RISK_OF_FREE;
|
|
|
+// } else if (NumberUtil.isNumber(riskOfFreeId)) {
|
|
|
+// riskOfFreeValue = Double.parseDouble(riskOfFreeId);
|
|
|
+// riskOfFreeId = null;
|
|
|
+// }
|
|
|
+// CalcMultipleSecMultipleTimeRangeIndicatorReq req = this.buildCalcReq(params, indicators, geoIndicators, DateIntervalType.CustomInterval, null);
|
|
|
+// req.setRiskOfFreeId(riskOfFreeId);
|
|
|
+// req.setRiskOfFreeValue(riskOfFreeValue);
|
|
|
+// req.setIfExtract(params.getIsExtract() != null && params.getIsExtract());
|
|
|
+//
|
|
|
+// // 2.指标计算
|
|
|
+// Map<String, List<IndicatorCalcPropertyDto>> indicator = this.baseIndicatorServiceV2.calcMultipleSecMultipleTimeRangeIndicator(req);
|
|
|
+//
|
|
|
+// // 3.返回结果处理
|
|
|
+// Map<String, Object> valuesMap = MapUtil.newHashMap(true);
|
|
|
+// Map<String, Object> indexValuesMap = MapUtil.newHashMap(true);
|
|
|
+// for (String refId : refIds) {
|
|
|
+// IndicatorCalcPropertyDto dto = Optional.ofNullable(indicator.get(refId)).filter(e -> !e.isEmpty()).map(e -> e.get(0)).orElse(null);
|
|
|
+// // 标的指标
|
|
|
+// Map<String, String> indicatorValues = Optional.ofNullable(dto).map(IndicatorCalcPropertyDto::getSecData).map(IndicatorCalcSecDataDto::getIndicatorValueMap).orElse(MapUtil.empty());
|
|
|
+// // 标的几何指标
|
|
|
+// Map<String, String> geoIndicatorValues = Optional.ofNullable(dto).map(IndicatorCalcPropertyDto::getSecData).map(IndicatorCalcSecDataDto::getExtraGeoIndicatorValueMap).orElse(MapUtil.empty());
|
|
|
+// // 指数指标,包括基�
|
|
|
+// Map<String, Map<String, String>> indexIndicatorValuesMap = Optional.ofNullable(dto).map(IndicatorCalcPropertyDto::getIndexData).map(IndicatorCalcIndexDataDto::getIndexIndicatorValueMap).orElse(MapUtil.empty());
|
|
|
+// // 指数几何指标
|
|
|
+// Map<String, Map<String, String>> indexGeoIndicatorValuesMap = Optional.ofNullable(dto).map(IndicatorCalcPropertyDto::getIndexData).map(IndicatorCalcIndexDataDto::getIndexGeoExtraIndicatorValueMap).orElse(MapUtil.empty());
|
|
|
+// // 标的和指数分别处理最大回撤指标,并合并指标结果到一个map�
|
|
|
+// Map<String, String> values = this.handleMaxDrawdown(indicatorValues, refId, null, false);
|
|
|
+// Map<String, String> geoValues = this.handleMaxDrawdown(geoIndicatorValues, refId, null, true);
|
|
|
+// Map<String, String> unionValues = MapUtil.<String, String>builder().putAll(values).putAll(geoValues).build();
|
|
|
+// valuesMap.put(refId, unionValues);
|
|
|
+// for (String indexId : indexIds) {
|
|
|
+// if (indexValuesMap.containsKey(indexId)) {
|
|
|
+// continue;
|
|
|
+// }
|
|
|
+// Map<String, String> indexValues = this.handleMaxDrawdown(indexIndicatorValuesMap.get(indexId), indexId, null, false);
|
|
|
+// Map<String, String> indexGeoValues = this.handleMaxDrawdown(indexGeoIndicatorValuesMap.get(indexId), indexId, params.getBenchmarkId(), true);
|
|
|
+// Map<String, String> unionIndexValues = MapUtil.<String, String>builder().putAll(indexValues).putAll(indexGeoValues).build();
|
|
|
+// indexValuesMap.put(indexId, unionIndexValues);
|
|
|
+// }
|
|
|
+// }
|
|
|
+//
|
|
|
+// // 返回结果对象构建
|
|
|
+// Map<String, Object> dataset = MapUtil.builder(valuesMap).putAll(indexValuesMap).build();
|
|
|
+// Map<String, Object> extInfos = MapUtil.<String, Object>builder("endDate", params.getStartDate() + "~" + params.getEndDate()).build();
|
|
|
+// Map<String, String> productNameMapping = this.secId2NameService.query(secIds);
|
|
|
+// CommonData<Map<String, Object>> data = CommonData.<Map<String, Object>>builder().dataset(dataset).productNameMapping(productNameMapping).extInfos(extInfos).build();
|
|
|
+// return CommonUtil.covertToMap(data, "endDate");
|
|
|
+// } catch (Exception e) {
|
|
|
+// logger.error(String.format("基金收益风险指标计算错误:%s", e.getMessage()));
|
|
|
+// }
|
|
|
+// return MapUtil.newHashMap();
|
|
|
+// }
|
|
|
+//
|
|
|
+// /**
|
|
|
+// * 动态回撤接口业务,返回回撤、超额回撤、最大回撤和最大超额回撤
|
|
|
+// *
|
|
|
+// * @param params /
|
|
|
+// * @return /
|
|
|
+// */
|
|
|
+// public Map<String, Object> dynamicDown(TrendParams params, String masterId) {
|
|
|
+// try {
|
|
|
+// List<TrendType> trendTypes = ListUtil.toList(TrendType.DrawdownTrend, TrendType.ExtraDrawdownTrend);
|
|
|
+// List<TrendType> indexTrendTypes = ListUtil.toList(TrendType.DrawdownTrend);
|
|
|
+// CommonData<Map<String, List<Map<String, Object>>>> data = this.handleTrends(params, trendTypes, indexTrendTypes, masterId);
|
|
|
+// return CommonUtil.covertToMap(data, "maxDown", "maxExtraDown", "startDate", "endDate");
|
|
|
+// } catch (Exception e) {
|
|
|
+// logger.error(String.format("动态回撤错误:%s", e.getMessage()), e);
|
|
|
+// }
|
|
|
+// return MapUtil.newHashMap();
|
|
|
+// }
|
|
|
+//
|
|
|
+// /**
|
|
|
+// * 业绩排名 接口请求业务处理
|
|
|
+// *
|
|
|
+// * @param params 请求参数
|
|
|
+// * @return /
|
|
|
+// */
|
|
|
+// public Map<String, Object> rank(RankParams params) {
|
|
|
+// try {
|
|
|
+// // 1.参数处理
|
|
|
+// this.checkParams(params);
|
|
|
+// String refId = params.getFundId().get(0);
|
|
|
+// List<String> secIds = this.getSecIdsByParams(params);
|
|
|
+// List<String> indexIds = CollectionUtil.subtractToList(secIds, params.getFundId());
|
|
|
+// String rankDate = Optional.ofNullable(rankRatService.getLatestRankRat()).map(CmRankRatControlDo::getEndDate).orElse(null);
|
|
|
+// IStrategy strategy = StrategyHandleUtils.getStrategy(params.getStrategy());
|
|
|
+// List<Map<String, Object>> tempList = ListUtil.list(false);
|
|
|
+// String rankFiled = null;
|
|
|
+// CmBigDataFundRetDO cmBigDataFundRetDO = fundHeadInfoBaseService.selectFundRetByFundId(refId);
|
|
|
+// String endDate = Optional.ofNullable(cmBigDataFundRetDO).map(CmBigDataFundRetDO::getEndDate).orElse(null);
|
|
|
+// if (StringUtils.isNotEmpty(endDate) && StringUtils.isNotEmpty(rankDate)) {
|
|
|
+// rankDate = endDate.compareTo(rankDate) > 0 ? rankDate : endDate;
|
|
|
+// } else {
|
|
|
+// if (StringUtils.isEmpty(endDate)) {
|
|
|
+// rankDate = endDate;
|
|
|
+// }
|
|
|
+// }
|
|
|
+// rankFiled = "fund_rank";
|
|
|
+// Integer isInvestAdvisor = Optional.ofNullable(UserUtils.getLoginUser()).map(SysUserDto::getIsInvestAdvisor).orElse(null);
|
|
|
+// if (params.getIsExtract() != null && params.getIsExtract()) {
|
|
|
+// tempList = null;
|
|
|
+// } else {
|
|
|
+// tempList = new FundRankProDao(this.jdbcTemplate, rankDate, refId, indexIds, params.getIndicator(), isInvestAdvisor).query();
|
|
|
+// }
|
|
|
+// Map<String, String> mapper = this.secId2NameService.query(secIds);
|
|
|
+// Map<String, String> productMapper = MapUtil.<String, String>builder(MapUtil.newHashMap(true)).putAll(mapper)
|
|
|
+// .put("rank", "同策略排名")
|
|
|
+// .put("strategy_avg", "同策略平均")
|
|
|
+// .put("strategy_avg_99", "同策略平均(1%-99%)")
|
|
|
+// .put("strategy_best", "同策略最好")
|
|
|
+// .put("strategy_worst", "同策略最差")
|
|
|
+// .put("percent5", "5%分位数")
|
|
|
+// .put("percent25", "25%分位数")
|
|
|
+// .put("percent50", "50%分位数")
|
|
|
+// .put("percent75", "75%分位数")
|
|
|
+// .put("percent95", "95%分位数").build();
|
|
|
+// Map<String, Object> extInfos = MapUtil.<String, Object>builder("strategy", strategy.getStrategyNameDesc()).build();
|
|
|
+// List<Map<String, Object>> dataset = this.getRankDataset(tempList, rankFiled);
|
|
|
+// if (CollUtil.isEmpty(dataset)) {
|
|
|
+// CommonData<List<Map<String, Object>>> data = CommonData.<List<Map<String, Object>>>builder()
|
|
|
+// .dataset(dataset).productNameMapping(productMapper).extInfos(extInfos).build();
|
|
|
+// return CommonUtil.covertToMap(data);
|
|
|
+// }
|
|
|
+// CommonData<List<Map<String, Object>>> data = CommonData.<List<Map<String, Object>>>builder()
|
|
|
+// .dataset(dataset).productNameMapping(productMapper).extInfos(extInfos).build();
|
|
|
+// return CommonUtil.covertToMap(data);
|
|
|
+// } catch (Exception e) {
|
|
|
+// logger.error(String.format("业绩排名错误:%s", e.getMessage()), e);
|
|
|
+// }
|
|
|
+// return MapUtil.newHashMap();
|
|
|
+// }
|
|
|
+//
|
|
|
+// private List<Map<String, Object>> getRankDataset(List<Map<String, Object>> tempList, String rankFiled) {
|
|
|
+// Map<String, Map<String, Object>> resMap = new LinkedHashMap<>();
|
|
|
+// if (CollUtil.isEmpty(tempList)) {
|
|
|
+// return CollUtil.newArrayList();
|
|
|
+// }
|
|
|
+// for (Map<String, Object> unit : tempList) {
|
|
|
+// String classification = MapUtil.getStr(unit, "classification");
|
|
|
+// String name = MapUtil.getStr(unit, "name");
|
|
|
+// if (name == null && classification == null) {
|
|
|
+// continue;
|
|
|
+// }
|
|
|
+// List<String> keys = new ArrayList<>(unit.keySet());
|
|
|
+// keys.remove("name");
|
|
|
+// keys.remove("classification");
|
|
|
+// for (String key : keys) {
|
|
|
+// if (!resMap.containsKey(key)) {
|
|
|
+// resMap.put(key, MapUtil.newHashMap(false));
|
|
|
+// }
|
|
|
+// if (classification.startsWith("strategy") || classification.startsWith("percen") || classification.equals(rankFiled)) {
|
|
|
+// name = classification;
|
|
|
+// }
|
|
|
+// resMap.get(key).put(name, unit.get(key));
|
|
|
+// }
|
|
|
+// }
|
|
|
+// List<Map<String, Object>> dataset = ListUtil.list(false);
|
|
|
+// resMap.forEach((k, v) -> dataset.add(MapUtil.<String, Object>builder("date", k).putAll(v).build()));
|
|
|
+// dataset.forEach(e -> {
|
|
|
+// String rank = MapUtil.getStr(e, rankFiled);
|
|
|
+// String rankCnt = MapUtil.getStr(e, "strategy_rank_cnt");
|
|
|
+// String strRank = null;
|
|
|
+// if (CharSequenceUtil.isAllNotBlank(rank, rankCnt)) {
|
|
|
+// strRank = StrUtil.subBefore(rank, ".", false) + "/"
|
|
|
+// + StrUtil.subBefore(rankCnt, ".", false);
|
|
|
+// }
|
|
|
+// e.put("rank", strRank);
|
|
|
+// e.remove(rankFiled);
|
|
|
+// e.remove("strategy_rank_cnt");
|
|
|
+// });
|
|
|
+// dataset.sort((o1, o2) -> MapUtil.getStr(o2, "date").compareTo(MapUtil.getStr(o1, "date")));
|
|
|
+// return dataset;
|
|
|
+// }
|
|
|
+//
|
|
|
+// /**
|
|
|
+// * 业绩走势接口业务处理
|
|
|
+// *
|
|
|
+// * @param params 请求参数
|
|
|
+// * @return /
|
|
|
+// */
|
|
|
+// public Map<String, Object> trend(TrendParams params, List<TrendType> trendTypes, List<TrendType> indexTrendTypes) {
|
|
|
+// try {
|
|
|
+// // 1.参数处理
|
|
|
+// List<String> refIds = params.getFundId();
|
|
|
+// CommonData<Map<String, List<Map<String, Object>>>> data = this.handleTrends(params, trendTypes, indexTrendTypes, null);
|
|
|
+// List<Map<String, String>> warnings = this.infoService.getWarningInfo(refIds, params.getStartDate(), params.getEndDate());
|
|
|
+// data.getExtInfos().put("warning", warnings);
|
|
|
+// return CommonUtil.covertToMap(data, "endDate", "startDate", "warning", "annualBenchmark", "annual");
|
|
|
+// } catch (Exception e) {
|
|
|
+// logger.error(String.format("业绩走势接口业务错误:%s", e.getMessage()), e);
|
|
|
+//
|
|
|
+// }
|
|
|
+// return MapUtil.newHashMap();
|
|
|
+// }
|
|
|
+//
|
|
|
+// @Override
|
|
|
+// public Map<String, Object> imfTrend(ImfTrendParams params) {
|
|
|
+// String fundId = params.getFundId().get(0);
|
|
|
+// List<TrendType> trendTypes = ListUtil.toList(TrendType.Ret, TrendType.Nav, TrendType.ExtraNav, TrendType.OrigNav, TrendType.NetValueChange, TrendType.ExtraRetGeo);
|
|
|
+// List<TrendType> indexTrendTypes = ListUtil.toList(TrendType.Ret, TrendType.OrigNav);
|
|
|
+// CommonData<Map<String, List<Map<String, Object>>>> data = this.handleTrends(params, trendTypes, indexTrendTypes, null);
|
|
|
+// Map<String, List<Map<String, Object>>> dataset = data.getDataset();
|
|
|
+// List<MonetaryFundProfitDO> doList = this.monetaryFundProfitBaseService.queryByFundId(fundId);
|
|
|
+// dataset.forEach((k, v) -> {
|
|
|
+// if (fundId.equals(k)) {
|
|
|
+// for (Map<String, Object> map : v) {
|
|
|
+// String date = MapUtil.getStr(map, "date");
|
|
|
+// MonetaryFundProfitDO aDo = doList.stream().filter(e -> date.equals(DateUtil.formatDate(e.getPriceDate()))).findFirst().orElse(null);
|
|
|
+// map.put("profit", Optional.ofNullable(aDo).map(MonetaryFundProfitDO::getProfitPerMillion).orElse(null));
|
|
|
+// map.put("serven", Optional.ofNullable(aDo).map(MonetaryFundProfitDO::getProfitServenDayAnnual).orElse(null));
|
|
|
+// }
|
|
|
+// }
|
|
|
+// });
|
|
|
+// data.setDataset(dataset);
|
|
|
+// return CommonUtil.covertToMap(data, "endDate", "startDate", "annualBenchmark", "annual");
|
|
|
+// }
|
|
|
+//
|
|
|
+// /**
|
|
|
+// * 区间指标分析 接口请求业务处理
|
|
|
+// *
|
|
|
+// * @param params 请求参数
|
|
|
+// * @return /
|
|
|
+// */
|
|
|
+// public Map<String, Object> rangIndicator(RangIndicatorParams params, Map<TimeRange, String> rangeMap) {
|
|
|
+// try {
|
|
|
+// if (params.getIndicator() == null) {
|
|
|
+// throw new APIException("分析的指标不能为空");
|
|
|
+// }
|
|
|
+// Function<IndicatorCalcTimeRangeDto, String> function = e -> e.getTimeRange().name();
|
|
|
+// if (rangeMap != null && !rangeMap.isEmpty()) {
|
|
|
+// function = e -> rangeMap.get(e.getTimeRange());
|
|
|
+// }
|
|
|
+// boolean excess = params.getExcess() == Boolean.TRUE || Indicator.INDICATOR_EXCESS_RETURN_TYPE_ARRAY.contains(params.getIndicator());
|
|
|
+// CommonData<Map<String, Object>> data = this.analyzeMultiIndicator(params, params.getIndicator(), excess, params.getFrequency(), function);
|
|
|
+// return CommonUtil.covertToMap(data);
|
|
|
+// } catch (Exception e) {
|
|
|
+// logger.error(String.format("区间指标分析接口业务错误:%s", e.getMessage()), e);
|
|
|
+// }
|
|
|
+// return MapUtil.newHashMap();
|
|
|
+// }
|
|
|
+//
|
|
|
+// /**
|
|
|
+// * 滚动指标分析 接口请求业务处理
|
|
|
+// *
|
|
|
+// * @param params 请求参数
|
|
|
+// * @return /
|
|
|
+// */
|
|
|
+// public Map<String, Object> rollIndicator(RollIndicatorParams params) {
|
|
|
+// try {
|
|
|
+// if (params.getIndicator() == null) {
|
|
|
+// throw new APIException("分析的指标不能为空");
|
|
|
+// }
|
|
|
+// List<Frequency> frequencies = ListUtil.toList(Frequency.Monthly, Frequency.Quarterly, Frequency.Annually);
|
|
|
+// if (params.getRollingFrequency() == null || !frequencies.contains(params.getRollingFrequency())) {
|
|
|
+// logger.warn(String.format("当前滚动频率为:%s,设置为默认滚动频率:%s", params.getRollingFrequency(), Frequency.Monthly));
|
|
|
+// params.setRollingFrequency(Frequency.Monthly);
|
|
|
+// }
|
|
|
+// CommonData<Map<String, Object>> data = this.analyzeIndicator(params, params.getIndicator(), DateIntervalType.DefaultRolling,
|
|
|
+// Indicator.INDICATOR_EXCESS_RETURN_TYPE_ARRAY.contains(params.getIndicator()), params.getRollingFrequency(), IndicatorCalcTimeRangeDto::getEndDate);
|
|
|
+// return CommonUtil.covertToMap(data);
|
|
|
+// } catch (Exception e) {
|
|
|
+// logger.error(String.format("滚动指标分析接口业务错误:%s", e.getMessage()), e);
|
|
|
+//
|
|
|
+// }
|
|
|
+// return MapUtil.newHashMap();
|
|
|
+// }
|
|
|
+//
|
|
|
+// private <P extends BaseParams> CommonData<Map<String, Object>> analyzeMultiIndicator(P params, Indicator indicator, boolean excess,
|
|
|
+// Frequency rollingFrequency, Function<IndicatorCalcTimeRangeDto, String> function) {
|
|
|
+// // 1.参数处理
|
|
|
+// this.checkParams(params);
|
|
|
+// List<String> refIds = params.getFundId();
|
|
|
+// List<String> secIds = this.getSecIdsByParams(params);
|
|
|
+// List<String> indexIds = CollectionUtil.subtractToList(secIds, refIds);
|
|
|
+// List<Indicator> indicators = ListUtil.toList(Indicator.MaxDrawdown);
|
|
|
+// List<Indicator> geoIndicators = ListUtil.list(false);
|
|
|
+// if (excess) {
|
|
|
+// geoIndicators.add(indicator);
|
|
|
+// } else {
|
|
|
+// indicators.add(indicator);
|
|
|
+// }
|
|
|
+// CalcMultipleSecMultipleTimeRangeIndicatorReq req;
|
|
|
+//
|
|
|
+// req = this.buildMultiCalcReq(params, indicators, geoIndicators, rollingFrequency);
|
|
|
+//
|
|
|
+// req.setRiskOfFreeId(RetConst.RISK_OF_FREE_1Y);
|
|
|
+//
|
|
|
+// // 2、指标计�
|
|
|
+// Map<String, List<IndicatorCalcPropertyDto>> indicatorMap = this.baseIndicatorServiceV2.calcMultipleSecMultipleTimeRangeIndicator(req);
|
|
|
+//
|
|
|
+// // 3、结果处�
|
|
|
+// Map<TimeRange, Boolean> timeRangeFlag = MapUtil.newHashMap();
|
|
|
+// Map<String, Object> valuesMap = MapUtil.newHashMap(true);
|
|
|
+// Map<String, Object> indexValuesMap = MapUtil.newHashMap(true);
|
|
|
+// for (String refId : refIds) {
|
|
|
+// List<IndicatorCalcPropertyDto> dtos = Optional.ofNullable(indicatorMap.get(refId)).filter(e -> !e.isEmpty()).orElse(ListUtil.empty());
|
|
|
+// // 当前基金的数据处�
|
|
|
+// List<Map<String, Object>> fundIndicatorList = ListUtil.list(true);
|
|
|
+// for (IndicatorCalcPropertyDto dto : dtos) {
|
|
|
+// String date = Optional.ofNullable(dto.getIndicatorCalcReq()).map(IndicatorCalcReqPropertyDto::getIndicatorCalcTimeRangeDto).map(function).orElse(null);
|
|
|
+// String id = Optional.ofNullable(dto.getIndicatorCalcReq()).map(IndicatorCalcReqPropertyDto::getIndicatorCalcTimeRangeDto).map(IndicatorCalcTimeRangeDto::getId).orElse(null);
|
|
|
+// TimeRange timeRange = Optional.ofNullable(dto.getIndicatorCalcReq()).map(IndicatorCalcReqPropertyDto::getIndicatorCalcTimeRangeDto).map(IndicatorCalcTimeRangeDto::getTimeRange).orElse(null);
|
|
|
+// if (timeRange == null || (id != null && YEAR_MONTH_ROLL_LIST.contains(id)) || timeRange == TimeRange.FromSetup) {
|
|
|
+// continue;
|
|
|
+// }
|
|
|
+// String start = Optional.ofNullable(dto.getIndicatorCalcReq()).map(IndicatorCalcReqPropertyDto::getIndicatorCalcTimeRangeDto).map(IndicatorCalcTimeRangeDto::getStartDate).orElse(null);
|
|
|
+// if (params.getStartDate() != null && start != null && params.getStartDate().compareTo(start) > 0) {
|
|
|
+// timeRangeFlag.put(timeRange, true);
|
|
|
+// continue;
|
|
|
+// }
|
|
|
+// // 如果是月�需要过滤掉近一�
|
|
|
+// if (Frequency.Monthly == params.getFrequency()) {
|
|
|
+// if (timeRange == TimeRange.Last1Week) {
|
|
|
+// timeRangeFlag.put(TimeRange.Last1Week, true);
|
|
|
+// continue;
|
|
|
+// }
|
|
|
+//
|
|
|
+// }
|
|
|
+//
|
|
|
+// String value = Optional.ofNullable(dto.getSecData()).map(e -> excess ? e.getExtraGeoIndicatorValueMap() : e.getIndicatorValueMap()).map(e -> e.get(indicator.name())).orElse(null);
|
|
|
+// fundIndicatorList.add(MapUtil.<String, Object>builder("date", date).put("value", value).build());
|
|
|
+// }
|
|
|
+// valuesMap.put(refId, fundIndicatorList);
|
|
|
+// // 指数的数据处�
|
|
|
+// if (excess) {
|
|
|
+// continue;
|
|
|
+// }
|
|
|
+// for (String indexId : indexIds) {
|
|
|
+// if (indexValuesMap.containsKey(indexId)) {
|
|
|
+// continue;
|
|
|
+// }
|
|
|
+// List<Map<String, Object>> indexIndicatorList = ListUtil.list(true);
|
|
|
+// for (IndicatorCalcPropertyDto dto : dtos) {
|
|
|
+// String id = Optional.ofNullable(dto.getIndicatorCalcReq()).map(IndicatorCalcReqPropertyDto::getIndicatorCalcTimeRangeDto).map(IndicatorCalcTimeRangeDto::getId).orElse(null);
|
|
|
+// String date = Optional.ofNullable(dto.getIndicatorCalcReq()).map(IndicatorCalcReqPropertyDto::getIndicatorCalcTimeRangeDto).map(function).orElse(null);
|
|
|
+// TimeRange timeRange = Optional.ofNullable(dto.getIndicatorCalcReq()).map(IndicatorCalcReqPropertyDto::getIndicatorCalcTimeRangeDto).map(IndicatorCalcTimeRangeDto::getTimeRange).orElse(null);
|
|
|
+// if (timeRange == null || date == null || timeRangeFlag.getOrDefault(timeRange, false) || (id != null && YEAR_MONTH_ROLL_LIST.contains(id))) {
|
|
|
+// continue;
|
|
|
+// }
|
|
|
+// String value = Optional.ofNullable(dto.getIndexData()).map(IndicatorCalcIndexDataDto::getIndexIndicatorValueMap).map(e -> e.get(indexId)).map(e -> e.get(indicator.name())).orElse(null);
|
|
|
+// indexIndicatorList.add(MapUtil.<String, Object>builder("date", date).put("value", value).build());
|
|
|
+// }
|
|
|
+// indexValuesMap.put(indexId, indexIndicatorList);
|
|
|
+// }
|
|
|
+// }
|
|
|
+// Map<String, Object> dataset = MapUtil.<String, Object>builder().putAll(valuesMap).putAll(indexValuesMap).build();
|
|
|
+//
|
|
|
+// Map<String, String> productNameMapping = this.secId2NameService.query(secIds);
|
|
|
+// if (excess) {
|
|
|
+// for (String indexId : indexIds) {
|
|
|
+// productNameMapping.remove(indexId);
|
|
|
+// }
|
|
|
+// }
|
|
|
+// Map<String, Object> extInfos = MapUtil.<String, Object>builder("endDate", params.getEndDate()).put("startDate", params.getStartDate()).build();
|
|
|
+// return CommonData.<Map<String, Object>>builder().dataset(dataset).productNameMapping(productNameMapping).extInfos(extInfos).build();
|
|
|
+// }
|
|
|
+//
|
|
|
+// protected CalcMultipleSecMultipleTimeRangeIndicatorReq buildMultiCalcReq(BaseParams params, List<Indicator> indicatorList,
|
|
|
+// List<Indicator> geoIndicatorList,
|
|
|
+// Frequency frequency) {
|
|
|
+// List<String> refIds = params.getFundId();
|
|
|
+// List<DateIntervalDto> dateIntervalDtoList = new ArrayList<>();
|
|
|
+// DateIntervalDto defaultIntervalDto = new DateIntervalDto();
|
|
|
+// defaultIntervalDto.setEndDate(params.getEndDate());
|
|
|
+// defaultIntervalDto.setFrequency(frequency);
|
|
|
+// defaultIntervalDto.setDateIntervalType(DateIntervalType.DefaultInterval);
|
|
|
+// dateIntervalDtoList.add(defaultIntervalDto);
|
|
|
+//
|
|
|
+// DateIntervalDto customIntervalDto = new DateIntervalDto();
|
|
|
+// customIntervalDto.setStartDate(params.getStartDate());
|
|
|
+// customIntervalDto.setEndDate(params.getEndDate());
|
|
|
+// customIntervalDto.setTimeRange(TimeRange.Custom);
|
|
|
+// customIntervalDto.setFrequency(frequency);
|
|
|
+// customIntervalDto.setDateIntervalType(DateIntervalType.CustomInterval);
|
|
|
+// dateIntervalDtoList.add(customIntervalDto);
|
|
|
+//
|
|
|
+// Map<String, List<DateIntervalDto>> dateIntervalMap = MapUtil.newHashMap(true);
|
|
|
+// for (String refId : refIds) {
|
|
|
+// dateIntervalMap.put(refId, dateIntervalDtoList);
|
|
|
+// }
|
|
|
+//
|
|
|
+// List<String> secIds = this.getSecIdsByParams(params);
|
|
|
+// // 差集求指数id集合,包括基�
|
|
|
+// List<String> indexIds = CollectionUtil.subtractToList(secIds, refIds);
|
|
|
+// Map<String, String> benchmarkIdMap = MapUtil.newHashMap(true);
|
|
|
+// for (String refId : refIds) {
|
|
|
+// if (StrUtil.isBlank(params.getBenchmarkId())) {
|
|
|
+// continue;
|
|
|
+// }
|
|
|
+// benchmarkIdMap.put(refId, params.getBenchmarkId());
|
|
|
+// }
|
|
|
+// return CalcMultipleSecMultipleTimeRangeIndicatorReq.builder()
|
|
|
+// .mainSecIdList(refIds) // 标的id集合
|
|
|
+// .secBenchmarkIdMap(benchmarkIdMap) // 标的对应基准
|
|
|
+// .indexIdList(indexIds) // 指数id集合,包括基�
|
|
|
+// .raiseType(params.getRaiseType()) // 标的类型
|
|
|
+// .strategy(this.getOriginStrategy(params)) // 二级策略
|
|
|
+// .visibility(Visibility.Both)
|
|
|
+// .dataFrequency(params.getFrequency()) // 净值频�
|
|
|
+// .navType(params.getNavType()) // 净值类�
|
|
|
+// .secDateIntervalDtoListMap(dateIntervalMap) // 日期区间
|
|
|
+// .indicatorList(indicatorList) // 要计算的指标
|
|
|
+// .geoExtraindicatorList(geoIndicatorList) // 要计算的几何指标
|
|
|
+// .ifAnnualize(true) // 要年�
|
|
|
+// .needExtraRet(true)
|
|
|
+// .needRet(true)
|
|
|
+// .calcIndexRetIndicatorValue(true) //
|
|
|
+// .ifConvertPerformanceConsistencyWord(true).build();
|
|
|
+// }
|
|
|
+//
|
|
|
+// /**
|
|
|
+// * 收益统计/收益分布 接口请求业务处理
|
|
|
+// *
|
|
|
+// * @param params 请求参数
|
|
|
+// * @return /
|
|
|
+// */
|
|
|
+// public Map<String, Object> revenue(RevenueParams params) {
|
|
|
+// try {
|
|
|
+// // 1.参数处理
|
|
|
+// this.checkParams(params);
|
|
|
+// if (StrUtil.isBlank(params.getRevenuType()) || !TYPE_LIST.contains(params.getRevenuType())) {
|
|
|
+// params.setRevenuType(ONE);
|
|
|
+// }
|
|
|
+// List<Frequency> frequencies = ListUtil.toList(Frequency.Weekly, Frequency.Monthly, Frequency.Quarterly, Frequency.Annually);
|
|
|
+// if (params.getRollingFrequency() == null || !frequencies.contains(params.getRollingFrequency())) {
|
|
|
+// logger.warn(String.format("当前滚动频率为:%s,设置为默认滚动频率:%s", params.getRollingFrequency(), Frequency.Monthly));
|
|
|
+// params.setRollingFrequency(Frequency.Monthly);
|
|
|
+// }
|
|
|
+// //支持调整组距�-20%�
|
|
|
+// if (TWO.equals(params.getRevenuType())) {
|
|
|
+// if (!NumberUtil.isNumber(params.getSpace()) || !NumberUtil.isIn(NumberUtil.toBigDecimal(params.getSpace()), NumberUtil.toBigDecimal("1"), NumberUtil.toBigDecimal("20"))) {
|
|
|
+// throw new APIException("组距必须是大于1小于20的数");
|
|
|
+// }
|
|
|
+// }
|
|
|
+// boolean ifExcessReturn = params.getIfExcessReturn() != null && params.getIfExcessReturn();
|
|
|
+// List<String> refIds = params.getFundId();
|
|
|
+// List<String> secIds = this.getSecIdsByParams(params);
|
|
|
+// List<String> indexIds = CollectionUtil.subtractToList(secIds, refIds);
|
|
|
+// List<Indicator> indicators = ListUtil.toList(Indicator.IntervalReturn);
|
|
|
+// CalcMultipleSecMultipleTimeRangeIndicatorReq req = this.buildCalcReq(params, indicators, indicators, params.getRollingFrequency());
|
|
|
+// req.setRiskOfFreeId(Consts.RISK_OF_FREE);
|
|
|
+//
|
|
|
+// // 2、指标计�
|
|
|
+// Map<String, List<IndicatorCalcPropertyDto>> secRangIndicatorMap = this.baseIndicatorServiceV2.calcMultipleSecMultipleTimeRangeIndicator(req);
|
|
|
+//
|
|
|
+// // 3、结果处�
|
|
|
+// Map<String, Object> dataset = MapUtil.newHashMap();
|
|
|
+// if (ONE.equals(params.getRevenuType())) {
|
|
|
+// dataset = this.getRevenueDataset(refIds, indexIds, params.getRollingFrequency(), secRangIndicatorMap, ifExcessReturn);
|
|
|
+// } else if (TWO.equals(params.getRevenuType())) {
|
|
|
+// dataset = this.loadDistributionData(refIds, indexIds, secRangIndicatorMap, Double.parseDouble(params.getSpace()), ifExcessReturn);
|
|
|
+// }
|
|
|
+// Map<String, String> productNameMapping = this.secId2NameService.query(secIds);
|
|
|
+// Map<String, Object> extInfos = MapUtil.<String, Object>builder("endDate", params.getEndDate()).put("startDate", params.getStartDate()).build();
|
|
|
+// if (ONE.equals(params.getRevenuType())) {
|
|
|
+// // table
|
|
|
+// HistoryRetTableSingleResp resp = getHistoryRetTableSingleResp(refIds, indexIds, secRangIndicatorMap, Indicator.IntervalReturn, ifExcessReturn, params.getRollingFrequency());
|
|
|
+// extInfos.put("table", this.buildTableData(productNameMapping, resp, ifExcessReturn, false));
|
|
|
+// }
|
|
|
+// CommonData<Map<String, Object>> data = CommonData.<Map<String, Object>>builder().dataset(dataset).productNameMapping(productNameMapping).extInfos(extInfos).build();
|
|
|
+// return CommonUtil.covertToMap(data);
|
|
|
+// } catch (Exception e) {
|
|
|
+// logger.error(String.format("收益统计/收益分布接口业务错误:%s", e.getMessage()), e);
|
|
|
+// return MapUtil.newHashMap();
|
|
|
+// }
|
|
|
+// }
|
|
|
+//
|
|
|
+// private Map<String, Object> getRevenueDataset(List<String> refIds, List<String> indexIds, Frequency frequency, Map<String, List<IndicatorCalcPropertyDto>> secRangIndicatorMap, boolean ifExcessReturn) {
|
|
|
+// Map<String, Object> dataset = MapUtil.newHashMap();
|
|
|
+// Map<String, List<Map<String, Object>>> valuesMap = MapUtil.newHashMap(true);
|
|
|
+// Map<String, List<Map<String, Object>>> indexValuesMap = MapUtil.newHashMap(true);
|
|
|
+// List<String> dateList = ListUtil.list(false);
|
|
|
+// for (String refId : refIds) {
|
|
|
+// List<IndicatorCalcPropertyDto> dtos = Optional.ofNullable(secRangIndicatorMap.get(refId)).filter(e -> !e.isEmpty()).orElse(ListUtil.empty());
|
|
|
+// // 当前基金的数据处�
|
|
|
+// List<Map<String, Object>> fundIndicatorList = ListUtil.list(true);
|
|
|
+// for (IndicatorCalcPropertyDto dto : dtos) {
|
|
|
+// String id = Optional.ofNullable(dto.getIndicatorCalcReq()).map(IndicatorCalcReqPropertyDto::getIndicatorCalcTimeRangeDto).map(IndicatorCalcTimeRangeDto::getId).orElse(null);
|
|
|
+// String date = Optional.ofNullable(dto.getIndicatorCalcReq()).map(IndicatorCalcReqPropertyDto::getIndicatorCalcTimeRangeDto).map(IndicatorCalcTimeRangeDto::getEndDate).orElse(null);
|
|
|
+// if (id == null || YEAR_MONTH_ROLL_LIST.contains(id)) {
|
|
|
+// continue;
|
|
|
+// }
|
|
|
+// date = this.handleStrDate(date, frequency);
|
|
|
+// if (!dateList.contains(date)) {
|
|
|
+// dateList.add(date);
|
|
|
+// }
|
|
|
+// String value = Optional.ofNullable(dto.getSecData()).map(IndicatorCalcSecDataDto::getIndicatorValueMap).map(e -> e.get(Indicator.IntervalReturn.name())).orElse(null);
|
|
|
+// String extraValue = Optional.ofNullable(dto.getSecData()).map(IndicatorCalcSecDataDto::getExtraGeoIndicatorValueMap).map(e -> e.get(Indicator.IntervalReturn.name())).orElse(null);
|
|
|
+// Map<String, Object> build = MapUtil.<String, Object>builder("date", date).put("d", date).put("extraValue", extraValue).put("value", value).build();
|
|
|
+// fundIndicatorList.add(build);
|
|
|
+// }
|
|
|
+// valuesMap.put(refId, fundIndicatorList);
|
|
|
+// // 指数的数据处�
|
|
|
+// for (String indexId : indexIds) {
|
|
|
+// if (indexValuesMap.containsKey(indexId)) {
|
|
|
+// continue;
|
|
|
+// }
|
|
|
+// List<Map<String, Object>> indexIndicatorList = ListUtil.list(true);
|
|
|
+// for (IndicatorCalcPropertyDto dto : dtos) {
|
|
|
+// String id = Optional.ofNullable(dto.getIndicatorCalcReq()).map(IndicatorCalcReqPropertyDto::getIndicatorCalcTimeRangeDto).map(IndicatorCalcTimeRangeDto::getId).orElse(null);
|
|
|
+// if (id == null || YEAR_MONTH_ROLL_LIST.contains(id)) {
|
|
|
+// continue;
|
|
|
+// }
|
|
|
+// String date = Optional.ofNullable(dto.getIndicatorCalcReq()).map(IndicatorCalcReqPropertyDto::getIndicatorCalcTimeRangeDto).map(IndicatorCalcTimeRangeDto::getEndDate).orElse(null);
|
|
|
+// date = this.handleStrDate(date, frequency);
|
|
|
+// String value = Optional.ofNullable(dto.getIndexData()).map(IndicatorCalcIndexDataDto::getIndexIndicatorValueMap).map(e -> e.get(indexId)).map(e -> e.get(Indicator.IntervalReturn.name())).orElse(null);
|
|
|
+// indexIndicatorList.add(MapUtil.<String, Object>builder("date", date).put("value", value).build());
|
|
|
+// }
|
|
|
+// indexValuesMap.put(indexId, indexIndicatorList);
|
|
|
+// }
|
|
|
+// }
|
|
|
+// dateList.sort(Comparator.naturalOrder());
|
|
|
+// for (String refId : refIds) {
|
|
|
+// List<Map<String, Object>> data = ListUtil.list(true);
|
|
|
+// for (String date : dateList) {
|
|
|
+// String value = valuesMap.get(refId).stream().filter(e -> date.equals(MapUtil.getStr(e, "date")))
|
|
|
+// .findFirst().map(e -> MapUtil.getStr(e, "value")).orElse(null);
|
|
|
+// Map<String, Object> build = MapUtil.<String, Object>builder().put("date", date).put("value", value).build();
|
|
|
+// if (ifExcessReturn) {
|
|
|
+// String extraValue = valuesMap.get(refId).stream().filter(e -> date.equals(MapUtil.getStr(e, "date")))
|
|
|
+// .findFirst().map(e -> MapUtil.getStr(e, "extraValue")).orElse(null);
|
|
|
+// build.put("extraValue", extraValue);
|
|
|
+// }
|
|
|
+// data.add(build);
|
|
|
+// }
|
|
|
+// dataset.put(refId, data);
|
|
|
+// }
|
|
|
+// for (String refId : indexIds) {
|
|
|
+// List<Map<String, Object>> data = ListUtil.list(true);
|
|
|
+// for (String date : dateList) {
|
|
|
+// String value = indexValuesMap.get(refId).stream().filter(e -> date.equals(MapUtil.getStr(e, "date")))
|
|
|
+// .findFirst().map(e -> MapUtil.getStr(e, "value")).orElse(null);
|
|
|
+// data.add(MapUtil.<String, Object>builder().put("date", date).put("value", value).build());
|
|
|
+// }
|
|
|
+// dataset.put(refId, data);
|
|
|
+// }
|
|
|
+// return dataset;
|
|
|
+// }
|
|
|
+//
|
|
|
+// /**
|
|
|
+// * 胜率分析 业务处理
|
|
|
+// *
|
|
|
+// * @param params /
|
|
|
+// * @return /
|
|
|
+// */
|
|
|
+// public Map<String, Object> win(WinParams params) {
|
|
|
+// try {
|
|
|
+// // 1.参数处理
|
|
|
+// this.checkParams(params);
|
|
|
+// List<String> refIds = params.getFundId();
|
|
|
+// if (refIds.size() > 1) {
|
|
|
+// logger.warn("多标的不支持胜率分析!");
|
|
|
+// }
|
|
|
+// String fundId = refIds.get(0);
|
|
|
+// Indicator indicator = Indicator.WinRate;
|
|
|
+// boolean winZero = params.getWinRateBmk() == WinRateBmk.Zero;
|
|
|
+// List<Indicator> indicators = ListUtil.toList(Indicator.IntervalReturn, indicator);
|
|
|
+//
|
|
|
+// CalcMultipleSecMultipleTimeRangeIndicatorReq req = this.buildCalcReq(params, indicators, ListUtil.list(false), DateIntervalType.CustomInterval, null);
|
|
|
+// req.setRiskOfFreeId(Consts.RISK_OF_FREE);
|
|
|
+// req.setIndexIdList(ListUtil.empty());
|
|
|
+// req.setNeedRet(true);
|
|
|
+// req.setNeedExtraRet(true);
|
|
|
+// if (!winZero) {
|
|
|
+// req.setGeoExtraindicatorList(ListUtil.toList(indicator));
|
|
|
+// }
|
|
|
+//
|
|
|
+// // 2、指标计�
|
|
|
+// Map<String, List<IndicatorCalcPropertyDto>> secIndicatorMap = this.baseIndicatorServiceV2.calcMultipleSecMultipleTimeRangeIndicator(req);
|
|
|
+//
|
|
|
+// // 3、结果处�
|
|
|
+// IndicatorCalcSecDataDto secData = Optional.ofNullable(secIndicatorMap.get(fundId)).filter(e -> !e.isEmpty()).map(e -> e.get(0))
|
|
|
+// .map(IndicatorCalcPropertyDto::getSecData).orElseThrow(() -> new APIException("计算错误"));
|
|
|
+// String winRate = winZero ? secData.getIndicatorValueMap().get(indicator.name()) : secData.getExtraGeoIndicatorValueMap().get(indicator.name());
|
|
|
+// List<CompoundRet> retList = secData.getRetList();
|
|
|
+// // 返回结果对象构建
|
|
|
+// Map<String, String> winData = this.prepareWinRateData("allTime", winRate, retList, winZero);
|
|
|
+// Double lower = Optional.ofNullable(params.getLower()).map(Double::parseDouble).map(e -> e / 100).orElse(-0.03d);
|
|
|
+// Double upper = Optional.ofNullable(params.getUpper()).map(Double::parseDouble).map(e -> e / 100).orElse(0.03d);
|
|
|
+// List<CompoundRet> riseRetList = retList.stream().filter(e -> e.getRetOfBmk() != null && e.getRetOfBmk() >= upper).collect(Collectors.toList());
|
|
|
+// List<CompoundRet> fallRetList = retList.stream().filter(e -> e.getRetOfBmk() != null && e.getRetOfBmk() <= lower).collect(Collectors.toList());
|
|
|
+// List<CompoundRet> shockRetList = retList.stream().filter(e -> e.getRetOfBmk() != null && e.getRetOfBmk() <= upper && e.getRetOfBmk() >= lower).collect(Collectors.toList());
|
|
|
+// List<Map<String, String>> marketWinData = ListUtil.list(true);
|
|
|
+// Map<String, List<CompoundRet>> timeMap = MapUtil.<String, List<CompoundRet>>builder(MapUtil.newHashMap(true))
|
|
|
+// .put("allTime", retList).put("riseTime", riseRetList).put("shockTime", shockRetList).put("fallTime", fallRetList).build();
|
|
|
+// if (winZero) {
|
|
|
+// timeMap.remove("shockTime");
|
|
|
+// }
|
|
|
+// timeMap.forEach((k, v) -> marketWinData.add(this.prepareWinRateData(k, winRate, v, winZero)));
|
|
|
+//
|
|
|
+// Map<String, Object> dataset = MapUtil.<String, Object>builder("win", winData).put("marketWin", marketWinData).build();
|
|
|
+// CommonData<Map<String, Object>> data = CommonData.<Map<String, Object>>builder().dataset(dataset).build();
|
|
|
+// return CommonUtil.covertToMap(data);
|
|
|
+// } catch (Exception e) {
|
|
|
+// logger.error(String.format("胜率计算错误:%s", e.getMessage()), e);
|
|
|
+// return MapUtil.newHashMap();
|
|
|
+// }
|
|
|
+// }
|
|
|
+//
|
|
|
+// @Override
|
|
|
+// public Map<String, Object> analyzeIndicatorNew(RangIndicatorParams params) {
|
|
|
+// // 1.参数处理
|
|
|
+// this.checkParams(params);
|
|
|
+// List<String> refIds = params.getFundId();
|
|
|
+// List<String> secIds = this.getSecIdsByParams(params);
|
|
|
+// List<String> indexIds = CollectionUtil.subtractToList(secIds, refIds);
|
|
|
+// Indicator indicator = params.getIndicator();
|
|
|
+// List<Indicator> indicators = ListUtil.toList(Indicator.MaxDrawdown);
|
|
|
+// List<Indicator> geoIndicators = ListUtil.list(false);
|
|
|
+// boolean excess = params.getExcess() != null && params.getExcess() || Indicator.INDICATOR_EXCESS_RETURN_TYPE_ARRAY.contains(params.getIndicator());
|
|
|
+// if (excess) {
|
|
|
+// geoIndicators.add(indicator);
|
|
|
+// } else {
|
|
|
+// indicators.add(indicator);
|
|
|
+// }
|
|
|
+//
|
|
|
+// CalcMultipleSecMultipleTimeRangeIndicatorReq req = this.buildCalcReq(params, indicators, geoIndicators, DateIntervalType.DefaultInterval, null);
|
|
|
+// req.setRiskOfFreeId(Consts.RISK_OF_FREE);
|
|
|
+//
|
|
|
+// // 2、指标计�
|
|
|
+// Map<String, List<IndicatorCalcPropertyDto>> indicatorMap = this.baseIndicatorServiceV2.calcMultipleSecMultipleTimeRangeIndicator(req);
|
|
|
+//
|
|
|
+// // 3、结果处�
|
|
|
+// Map<TimeRange, Boolean> timeRangeFlag = MapUtil.newHashMap();
|
|
|
+// Map<String, Object> valuesMap = MapUtil.newHashMap(true);
|
|
|
+// Map<String, Object> indexValuesMap = MapUtil.newHashMap(true);
|
|
|
+// for (String refId : refIds) {
|
|
|
+// List<IndicatorCalcPropertyDto> dtos = Optional.ofNullable(indicatorMap.get(refId)).filter(e -> !e.isEmpty()).orElse(ListUtil.empty());
|
|
|
+// // 当前基金的数据处�
|
|
|
+// List<Map<String, Object>> fundIndicatorList = ListUtil.list(true);
|
|
|
+// for (IndicatorCalcPropertyDto dto : dtos) {
|
|
|
+// TimeRange timeRange = Optional.ofNullable(dto.getIndicatorCalcReq()).map(IndicatorCalcReqPropertyDto::getIndicatorCalcTimeRangeDto)
|
|
|
+// .map(IndicatorCalcTimeRangeDto::getTimeRange).orElse(null);
|
|
|
+// if (timeRange == null) {
|
|
|
+// continue;
|
|
|
+// }
|
|
|
+// if (params.getTimeRange() != null) {
|
|
|
+// String start = Optional.ofNullable(dto.getIndicatorCalcReq()).map(IndicatorCalcReqPropertyDto::getIndicatorCalcTimeRangeDto).map(IndicatorCalcTimeRangeDto::getStartDate).orElse(null);
|
|
|
+// boolean isFrom = timeRange != TimeRange.FromSetup && timeRange != TimeRange.FromThisYear;
|
|
|
+// boolean isDate = CharSequenceUtil.compare(params.getStartDate(), start, true) > 0;
|
|
|
+// if (isFrom && isDate) {
|
|
|
+// timeRangeFlag.put(timeRange, true);
|
|
|
+// continue;
|
|
|
+// }
|
|
|
+// }
|
|
|
+// String value = Optional.ofNullable(dto.getSecData()).map(e -> excess ? e.getExtraGeoIndicatorValueMap() : e.getIndicatorValueMap())
|
|
|
+// .map(e -> e.get(indicator.name())).orElse(null);
|
|
|
+// fundIndicatorList.add(MapUtil.<String, Object>builder("date", this.handleStrDate(timeRange.name(), null)).put("value", value).build());
|
|
|
+// }
|
|
|
+// valuesMap.put(refId, fundIndicatorList);
|
|
|
+// // 指数的数据处�
|
|
|
+// for (String indexId : indexIds) {
|
|
|
+// boolean excessBench = (excess && indexId.equals(params.getBenchmarkId()));
|
|
|
+// if (indexValuesMap.containsKey(indexId) || excessBench) {
|
|
|
+// continue;
|
|
|
+// }
|
|
|
+// List<Map<String, Object>> indexIndicatorList = ListUtil.list(true);
|
|
|
+// for (IndicatorCalcPropertyDto dto : dtos) {
|
|
|
+// TimeRange timeRange = Optional.ofNullable(dto.getIndicatorCalcReq()).map(IndicatorCalcReqPropertyDto::getIndicatorCalcTimeRangeDto)
|
|
|
+// .map(IndicatorCalcTimeRangeDto::getTimeRange).orElse(null);
|
|
|
+// if (timeRange == null || timeRangeFlag.getOrDefault(timeRange, false)) {
|
|
|
+// continue;
|
|
|
+// }
|
|
|
+// String value = Optional.ofNullable(dto.getIndexData()).map(IndicatorCalcIndexDataDto::getIndexIndicatorValueMap).map(e -> e.get(indexId)).map(e -> e.get(indicator.name())).orElse(null);
|
|
|
+// indexIndicatorList.add(MapUtil.<String, Object>builder("date", this.handleStrDate(timeRange.name(), null)).put("value", value).build());
|
|
|
+// }
|
|
|
+// indexValuesMap.put(indexId, indexIndicatorList);
|
|
|
+// }
|
|
|
+// }
|
|
|
+// Map<String, Object> dataset = MapUtil.<String, Object>builder().putAll(valuesMap).putAll(indexValuesMap).build();
|
|
|
+//
|
|
|
+// Map<String, String> productNameMapping = this.secId2NameService.query(secIds);
|
|
|
+// if (excess) {
|
|
|
+// for (String indexId : indexIds) {
|
|
|
+// productNameMapping.remove(indexId);
|
|
|
+// }
|
|
|
+// }
|
|
|
+// Map<String, Object> extInfos = MapUtil.<String, Object>builder("endDate", params.getEndDate()).put("startDate", params.getStartDate()).build();
|
|
|
+// CommonData<Map<String, Object>> data = CommonData.<Map<String, Object>>builder().dataset(dataset).productNameMapping(productNameMapping).extInfos(extInfos).build();
|
|
|
+// return CommonUtil.covertToMap(data);
|
|
|
+// }
|
|
|
+//
|
|
|
+// @Override
|
|
|
+// public Map<String, Object> analyzeCovNew(AnalyzeCovParams params) {
|
|
|
+// try {
|
|
|
+// // 1.参数处理
|
|
|
+// this.checkParams(params);
|
|
|
+// String startDate = params.getStartDate();
|
|
|
+// String endDate = params.getEndDate();
|
|
|
+// List<String> refIds = params.getFundId();
|
|
|
+// String fundId = refIds.get(0);
|
|
|
+// List<Map<String, String>> secTimeRanges = this.baseIndicatorServiceV2.getSecTimeRanges(fundId, params.getRaiseType(), Strategy.All, Visibility.Both);
|
|
|
+// List<String> secIds = this.getSecIdsByParams(params);
|
|
|
+// List<String> indexIds = CollectionUtil.subtractToList(secIds, refIds);
|
|
|
+// List<DateRange> dateRangeList = new RollingSpliter(startDate, endDate, params.getRollingWindow(), params.getRollingWindow(), false, Frequency.Monthly).split();
|
|
|
+// if (dateRangeList.isEmpty()) {
|
|
|
+// throw new APIException("净值数量小于窗口期,请尝试调整取值区间");
|
|
|
+// }
|
|
|
+// Map<String, List<Double>> corrData = MapUtil.newHashMap();
|
|
|
+// List<String> dates = ListUtil.list(true);
|
|
|
+// List<Map<String, Object>> corRetList = ListUtil.list(false);
|
|
|
+// List<List<Map<String, Object>>> matrixList = this.getMatrixList(params, dateRangeList, dates, corrData, corRetList);
|
|
|
+// List<Map<String, Object>> dataList = ListUtil.list(true);
|
|
|
+// for (int i = 0; i < dates.size(); i++) {
|
|
|
+// Object values = matrixList.get(i).get(0).get("values");
|
|
|
+// dataList.add(MapUtil.<String, Object>builder("date", dates.get(i))
|
|
|
+// .put("matrix", values).build());
|
|
|
+// }
|
|
|
+// Map<String, Object> dataset = MapUtil.<String, Object>builder(fundId, dataList).build();
|
|
|
+// for (String indexId : indexIds) {
|
|
|
+// List<Map<String, Object>> indexDataList = ListUtil.list(true);
|
|
|
+// for (int i = 0; i < dates.size(); i++) {
|
|
|
+// Object values = matrixList.get(i).stream().filter(e -> Objects.equals(indexId, e.get("id"))).findFirst()
|
|
|
+// .map(e -> e.get("values")).orElse(null);
|
|
|
+// indexDataList.add(MapUtil.<String, Object>builder("date", dates.get(i))
|
|
|
+// .put("value", corrData.get(indexId).get(i))
|
|
|
+// .put("matrix", values).build());
|
|
|
+// }
|
|
|
+// dataset.put(indexId, indexDataList);
|
|
|
+// }
|
|
|
+// String endDate1 = null;
|
|
|
+// Map<String, String> timeRangeMap = MapUtil.newHashMap();
|
|
|
+// for (Map<String, String> timeRange : secTimeRanges) {
|
|
|
+// if (StrUtil.isBlank(endDate1)) {
|
|
|
+// endDate1 = timeRange.get("endDate");
|
|
|
+// }
|
|
|
+// timeRangeMap.put(timeRange.get("name"), timeRange.get("startDate"));
|
|
|
+// }
|
|
|
+// List<Map<String, Object>> resultList = ListUtil.list(true);
|
|
|
+// Map<TimeRange, String> yearOptions = TimeRange.COR_DATES;
|
|
|
+// yearOptions.forEach((k, v) -> {
|
|
|
+// Map<String, Object> result = MapUtil.newHashMap();
|
|
|
+// result.put("id", v);
|
|
|
+// result.put("range", k);
|
|
|
+// result.put("startDate", timeRangeMap.get(k.name()) == null ? null : timeRangeMap.get(k.name()));
|
|
|
+// resultList.add(result);
|
|
|
+// });
|
|
|
+// List<Map<String, Object>> dataset2 = getDataset(params, refIds, indexIds, corRetList, endDate1, resultList);
|
|
|
+//
|
|
|
+// // 直接把原数据转换一�
|
|
|
+// Map<String, String> productNameMapping = this.secId2NameService.query(secIds);
|
|
|
+// Map<String, Object> extInfos = MapUtil.<String, Object>builder().put("table", dataset2).build();
|
|
|
+// CommonData<Map<String, Object>> data = CommonData.<Map<String, Object>>builder()
|
|
|
+// .dataset(dataset).productNameMapping(productNameMapping).extInfos(extInfos).build();
|
|
|
+// return CommonUtil.covertToMap(data);
|
|
|
+// } catch (Exception e) {
|
|
|
+// logger.error(String.format("相关性分析错误:%s", e.getMessage()), e);
|
|
|
+// return MapUtil.newHashMap();
|
|
|
+// }
|
|
|
+// }
|
|
|
+//
|
|
|
+// private List<List<Map<String, Object>>> getMatrixList(AnalyzeCovParams params, List<DateRange> dateRangeList, List<String> dates, Map<String,
|
|
|
+// List<Double>> corrData, List<Map<String, Object>> corRetList) {
|
|
|
+// List<List<Map<String, Object>>> matrixList = ListUtil.list(false);
|
|
|
+// List<String> refIds = params.getFundId();
|
|
|
+// String fundId = refIds.get(0);
|
|
|
+// List<String> secIds = this.getSecIdsByParams(params);
|
|
|
+// List<String> indexIds = CollectionUtil.subtractToList(secIds, refIds);
|
|
|
+// IStrategy strategy = StrategyHandleUtils.getStrategy(params.getStrategy());
|
|
|
+// List<Map<String, String>> secTimeRanges = this.baseIndicatorServiceV2.getSecTimeRanges(fundId, params.getRaiseType(), strategy, Visibility.Both);
|
|
|
+// String incepStart = null;
|
|
|
+// String incepEnd = null;
|
|
|
+// if (CollUtil.isNotEmpty(secTimeRanges)) {
|
|
|
+// for (Map<String, String> secTimeRange : secTimeRanges) {
|
|
|
+// if (secTimeRange.get("name").equals(TimeRange.FromSetup.name())) {
|
|
|
+// incepStart = secTimeRange.get("startDate");
|
|
|
+// incepEnd = secTimeRange.get("endDate");
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// Frequency frequency = params.getFrequency();
|
|
|
+// if (frequency == null || frequency == Frequency.Default) {
|
|
|
+// frequency = Frequency.Daily;
|
|
|
+// }
|
|
|
+// Map<String, List<IndicatorCalcPropertyDto>> multiSecRetListNew = this.baseIndicatorServiceV2.getMultiSecRetListNew(
|
|
|
+// secIds, ListUtil.empty(), frequency, Frequency.Daily, incepStart, incepEnd, false, params.getBenchmarkId(),
|
|
|
+// params.getRaiseType(), strategy, Visibility.Visible, params.getNavType(), isExtract, params.getUserId());
|
|
|
+// if (CollectionUtil.isEmpty(indexIds)) {
|
|
|
+// throw new APIException("指数不能为空");
|
|
|
+// }
|
|
|
+// List<Map<String, Object>> mapList = NavUtil.handleNextStepNew(secIds, indexIds, multiSecRetListNew, false);
|
|
|
+// corRetList.addAll(mapList);
|
|
|
+// for (DateRange dr : dateRangeList) {
|
|
|
+// String start = dr.getStartDate();
|
|
|
+// String end = dr.getEndDate();
|
|
|
+// dates.add(end);
|
|
|
+// Map<String, Map<String, Double>> retMap = findRetData(corRetList, start, end);
|
|
|
+// Double[][] correlationMatrix = CalcUtils.getCorrelationMatrix(retMap, refIds, indexIds);
|
|
|
+// Double[] values = correlationMatrix[0];
|
|
|
+// for (int i = 0; i < values.length; i++) {
|
|
|
+// String idx = indexIds.get(i);
|
|
|
+// List<Double> cList = corrData.getOrDefault(idx, new ArrayList<>());
|
|
|
+// cList.add(values[i]);
|
|
|
+// corrData.put(idx, cList);
|
|
|
+// }
|
|
|
+// // 相关性矩�
|
|
|
+// Double[][] matrix = CalcUtils.getCorrelationMatrix(retMap, secIds, secIds);
|
|
|
+// List<Map<String, Object>> rowList = new ArrayList<>(matrix.length);
|
|
|
+// for (int i = 0; i < matrix.length; i++) {
|
|
|
+// rowList.add(MapUtil.<String, Object>builder("id", secIds.get(i)).put("values", matrix[i]).build());
|
|
|
+// }
|
|
|
+// matrixList.add(rowList);
|
|
|
+// }
|
|
|
+// return matrixList;
|
|
|
+// }
|
|
|
+//
|
|
|
+// private List<Map<String, Object>> getDataset(AnalyzeCovParams params, List<String> refIds, List<String> indexIds, List<Map<String, Object>> corRetList,
|
|
|
+// String endDate1, List<Map<String, Object>> resultList) {
|
|
|
+// // 除了成立以来 今年以来 其他都需要加上过滤条�只要开始日期大于等�前端传参的开始日�
|
|
|
+// List<Map<String, Object>> dataset2 = ListUtil.list(true);
|
|
|
+// for (Map<String, Object> timeRange : resultList) {
|
|
|
+// Map<String, Object> temp = MapUtil.newHashMap();
|
|
|
+// String start = MapUtil.getStr(timeRange, "startDate");
|
|
|
+// if (StrUtil.isBlank(start)) {
|
|
|
+// continue;
|
|
|
+// }
|
|
|
+// TimeRange range = (TimeRange) timeRange.get("range");
|
|
|
+// boolean isTime = range != TimeRange.FromSetup && range != TimeRange.FromThisYear;
|
|
|
+// if (isTime && params.getStartDate().compareTo(start) > 0) {
|
|
|
+// continue;
|
|
|
+// }
|
|
|
+//
|
|
|
+// Map<String, Map<String, Double>> retMap = findRetData(corRetList, start, endDate1);
|
|
|
+// Double[][] correlationMatrix = CalcUtils.getCorrelationMatrix(retMap, refIds, indexIds);
|
|
|
+// Double[] values = correlationMatrix[0];
|
|
|
+// temp.put("timeRange", timeRange.get("id"));
|
|
|
+// for (int i = 0; i < indexIds.size(); i++) {
|
|
|
+// temp.put(indexIds.get(i), values[i]);
|
|
|
+// }
|
|
|
+// dataset2.add(temp);
|
|
|
+// }
|
|
|
+// return dataset2;
|
|
|
+// }
|
|
|
+//}
|