|
@@ -1,284 +1,283 @@
|
|
-package com.smppw.analysis.application.service.position;
|
|
|
|
-
|
|
|
|
-import cn.hutool.core.collection.CollUtil;
|
|
|
|
-import cn.hutool.core.collection.ListUtil;
|
|
|
|
-import cn.hutool.core.date.DateUtil;
|
|
|
|
-import cn.hutool.core.map.MapUtil;
|
|
|
|
-import com.smppw.analysis.application.dto.position.*;
|
|
|
|
-import com.smppw.analysis.domain.dao.PubliclyFundPositionDao;
|
|
|
|
-import com.smppw.analysis.domain.dataobject.PubliclyFundStockChangeDO;
|
|
|
|
-import com.smppw.analysis.domain.dataobject.SwSecIndustryInfoDO;
|
|
|
|
-import com.smppw.analysis.domain.dto.position.*;
|
|
|
|
-import com.smppw.analysis.domain.dto.position.stock.*;
|
|
|
|
-import com.smppw.analysis.domain.manager.position.BizHandler;
|
|
|
|
-import com.smppw.analysis.domain.manager.position.BizHandlerFactory;
|
|
|
|
-import com.smppw.analysis.domain.manager.position.stock.BarraSensitivityComponent;
|
|
|
|
-import com.smppw.analysis.domain.manager.position.stock.IndustryAllocationPreferenceComponent;
|
|
|
|
-import com.smppw.analysis.domain.mapper.core.BaseUnderlyingMapper;
|
|
|
|
-import com.smppw.common.pojo.ValueLabelVO;
|
|
|
|
-import com.smppw.common.pojo.dto.NewDateValue;
|
|
|
|
-import org.springframework.stereotype.Component;
|
|
|
|
-
|
|
|
|
-import java.math.BigDecimal;
|
|
|
|
-import java.util.*;
|
|
|
|
-import java.util.function.Function;
|
|
|
|
-import java.util.stream.Collectors;
|
|
|
|
-
|
|
|
|
-import static com.smppw.analysis.domain.manager.position.BizHandlerConstants.*;
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
- * @author wangzaijun
|
|
|
|
- * @date 2023/6/6 14:41
|
|
|
|
- * @description 基金持仓分析-股票tab
|
|
|
|
- */
|
|
|
|
-@Component
|
|
|
|
-public class StockPositionAnalysis {
|
|
|
|
- private static final Map<Long, String> POSITION_NAME = MapUtil.newHashMap(true);
|
|
|
|
-
|
|
|
|
- static {
|
|
|
|
- POSITION_NAME.put(1L, "最大持仓");
|
|
|
|
- POSITION_NAME.put(3L, "前三大持仓");
|
|
|
|
- POSITION_NAME.put(5L, "前五大持仓");
|
|
|
|
- POSITION_NAME.put(10L, "前十大持仓");
|
|
|
|
- POSITION_NAME.put(-1L, "股票持仓");
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private final BizHandlerFactory factor;
|
|
|
|
- private final BaseUnderlyingMapper baseUnderlyingMapper;
|
|
|
|
- private final BarraSensitivityComponent barraSensitivity;
|
|
|
|
- private final PubliclyFundPositionDao fundPositionBaseService;
|
|
|
|
- private final IndustryAllocationPreferenceComponent industryAllocationPreference;
|
|
|
|
-
|
|
|
|
- public StockPositionAnalysis(BizHandlerFactory factor,
|
|
|
|
- BaseUnderlyingMapper baseUnderlyingMapper,
|
|
|
|
- BarraSensitivityComponent barraSensitivity,
|
|
|
|
- PubliclyFundPositionDao fundPositionBaseService,
|
|
|
|
- IndustryAllocationPreferenceComponent industryAllocationPreference) {
|
|
|
|
- this.factor = factor;
|
|
|
|
- this.barraSensitivity = barraSensitivity;
|
|
|
|
- this.baseUnderlyingMapper = baseUnderlyingMapper;
|
|
|
|
- this.fundPositionBaseService = fundPositionBaseService;
|
|
|
|
- this.industryAllocationPreference = industryAllocationPreference;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public List<MajorChangeVO> getMajorChangeList(MajorChangeReq req) {
|
|
|
|
- MajorChangeParams params = req.convert();
|
|
|
|
- List<SwSecIndustryInfoDO> industryList = this.baseUnderlyingMapper.querySecIndustryInfo();
|
|
|
|
- List<MajorChangeVO> resultList = ListUtil.list(false);
|
|
|
|
- List<PubliclyFundStockChangeDO> dataList = this.fundPositionBaseService.mfStockChangeList(params.getFundId(),
|
|
|
|
- params.getStartDate(), params.getEndDate());
|
|
|
|
- for (PubliclyFundStockChangeDO data : dataList) {
|
|
|
|
- String industryName = industryList.stream().filter(e -> data.getSecCode().equals(e.getSecCode())).findFirst()
|
|
|
|
- .map(SwSecIndustryInfoDO::getIndustryName).orElse(null);
|
|
|
|
- MajorChangeVO vo = new MajorChangeVO();
|
|
|
|
- vo.setDate(DateUtil.formatDate(data.getReportDate()));
|
|
|
|
- vo.setStockCode(data.getSecCode());
|
|
|
|
- vo.setStockName(data.getSecName());
|
|
|
|
- vo.setChangeType(Optional.ofNullable(data.getChangeType()).map(Object::toString).orElse(null));
|
|
|
|
- vo.setAccumulatedTradeSum(Optional.ofNullable(data.getAccumulatedTradeSum()).map(BigDecimal::toPlainString).orElse(null));
|
|
|
|
- vo.setRatioInNvAtBegin(Optional.ofNullable(data.getRatioInNvAtBegin()).map(BigDecimal::toPlainString).orElse(null));
|
|
|
|
- vo.setIndustry(industryName);
|
|
|
|
- resultList.add(vo);
|
|
|
|
- }
|
|
|
|
- // 按报告期降序
|
|
|
|
- resultList.sort((o1, o2) -> o2.getDate().compareTo(o1.getDate()));
|
|
|
|
- return resultList;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public Map<String, Object> getConcentration(ConcentrationReq req) {
|
|
|
|
- ConcentrationParams params = req.convert();
|
|
|
|
- Map<String, Object> dataset = MapUtil.newHashMap();
|
|
|
|
- BizHandler<ConcentrationParams, List<ConcentrationVO>> bizHandler = this.factor.getBizHandlerInstance(STOCK_CONCENTRATION);
|
|
|
|
- List<ConcentrationVO> dataList = bizHandler.bizHandle(params);
|
|
|
|
- if (CollUtil.isEmpty(dataList)) {
|
|
|
|
- return MapUtil.empty();
|
|
|
|
- }
|
|
|
|
- for (Long integer : POSITION_NAME.keySet()) {
|
|
|
|
- List<MarketValueRatio> tempList = ListUtil.list(true);
|
|
|
|
- for (ConcentrationVO vo : dataList) {
|
|
|
|
- MarketValueRatio mvr = new MarketValueRatio();
|
|
|
|
- mvr.setDate(vo.getDate());
|
|
|
|
- List<RefMarketValueRatio> resList = vo.getPosition();
|
|
|
|
- if (integer != -1L) {
|
|
|
|
- // 不为-1时取前n条记录求和
|
|
|
|
- resList = vo.getPosition().stream().limit(integer).collect(Collectors.toList());
|
|
|
|
- }
|
|
|
|
- BigDecimal marketValue = resList.stream().map(RefMarketValueRatio::getMarketValue)
|
|
|
|
- .filter(Objects::nonNull).reduce(BigDecimal::add).orElse(null);
|
|
|
|
- BigDecimal ratio = resList.stream().map(RefMarketValueRatio::getRatio).filter(Objects::nonNull)
|
|
|
|
- .reduce(BigDecimal::add).orElse(null);
|
|
|
|
- mvr.setMarketValue(marketValue);
|
|
|
|
- mvr.setRatio(ratio);
|
|
|
|
- tempList.add(mvr);
|
|
|
|
- }
|
|
|
|
- dataset.put(integer.toString(), tempList);
|
|
|
|
- }
|
|
|
|
- for (ConcentrationVO vo : dataList) {
|
|
|
|
- List<RefMarketValueRatio> collect = vo.getPosition().stream().sorted((o1, o2) -> o2.getRatio().compareTo(o1.getRatio()))
|
|
|
|
- .limit(10).collect(Collectors.toList());
|
|
|
|
- vo.setPosition(collect);
|
|
|
|
- }
|
|
|
|
- return MapUtil.<String, Object>builder().put("dataset", dataset)
|
|
|
|
- .put("productNameMapping", POSITION_NAME).put("table", dataList).build();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public List<ChangeNumberVO> getChangeNumber(ChangeNumberReq req) {
|
|
|
|
- ChangeNumberParams params = req.convert();
|
|
|
|
- BizHandler<ChangeNumberParams, List<ChangeNumberVO>> bizHandler = this.factor.getBizHandlerInstance(CHANGE_NUMBER);
|
|
|
|
- List<ChangeNumberVO> dataList = bizHandler.bizHandle(params);
|
|
|
|
- if (CollUtil.isEmpty(dataList)) {
|
|
|
|
- return ListUtil.empty();
|
|
|
|
- }
|
|
|
|
- return dataList;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public Map<String, Object> getIndustryAllocation(StockAllocationReq req) {
|
|
|
|
- StockAllocationParams params = req.convert();
|
|
|
|
- BizHandler<StockAllocationParams, List<StockAllocationVO>> bizHandler = this.factor.getBizHandlerInstance(INDUSTRY_ALLOCATION);
|
|
|
|
- List<StockAllocationVO> dataList = bizHandler.bizHandle(params);
|
|
|
|
- return this.convertDataset(dataList);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public Map<String, Object> getIndustryAllocationPreference(StockAllocationReq req) {
|
|
|
|
- StockAllocationParams params = req.convert();
|
|
|
|
- List<IndustryAllocationPreferenceVO> dataList = this.industryAllocationPreference.bizHandle(params);
|
|
|
|
- if (CollUtil.isEmpty(dataList)) {
|
|
|
|
- return MapUtil.empty();
|
|
|
|
- }
|
|
|
|
- List<ValueLabelVO> industryList = dataList.get(0).getIndustryList();
|
|
|
|
- // 倒序,其他排最后面
|
|
|
|
- industryList.sort((o1, o2) -> o2.getValue().compareTo(o1.getValue()));
|
|
|
|
- List<Map<String, Object>> dataset = ListUtil.list(true);
|
|
|
|
- for (IndustryAllocationPreferenceVO temp : dataList) {
|
|
|
|
- Map<String, Object> data = MapUtil.newHashMap(true);
|
|
|
|
- data.put("date", temp.getDate());
|
|
|
|
- data.putAll(temp.getIndustryPreference());
|
|
|
|
- data.put("avg", temp.getAvg());
|
|
|
|
- dataset.add(data);
|
|
|
|
- }
|
|
|
|
- return MapUtil.<String, Object>builder().put("dataset", dataset).put("productNameMapping", industryList).build();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public Map<String, Object> getStyleAllocation(StockAllocationReq req) {
|
|
|
|
- StockAllocationParams params = req.convert();
|
|
|
|
- BizHandler<StockAllocationParams, List<StockAllocationVO>> bizHandler = this.factor.getBizHandlerInstance(STYLE_ALLOCATION);
|
|
|
|
- List<StockAllocationVO> dataList = bizHandler.bizHandle(params);
|
|
|
|
- return this.convertDataset(dataList);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public Map<String, Object> getLiquidityAllocation(StockAllocationReq req) {
|
|
|
|
- StockAllocationParams params = req.convert();
|
|
|
|
- BizHandler<StockAllocationParams, List<StockAllocationVO>> bizHandler = this.factor.getBizHandlerInstance(LIQUIDITY_ALLOCATION);
|
|
|
|
- List<StockAllocationVO> dataList = bizHandler.bizHandle(params);
|
|
|
|
- List<ValueLabelVO> categoryList = Arrays.stream(PositionLiquidityEnum.values())
|
|
|
|
- .map(e -> new ValueLabelVO(e.name(), e.getDesc())).collect(Collectors.toList());
|
|
|
|
- return this.convertDataset(dataList, categoryList);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public Map<String, Object> getBarraSensitivity(BarraSensitivityReq req) {
|
|
|
|
- BarraSensitivityParams params = req.convert();
|
|
|
|
- return this.barraSensitivity.bizHandle(params);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public Map<String, Object> getPerformanceAttribution(StockPerformanceAttributionReq req) {
|
|
|
|
- StockPerformanceAttributionParams params = req.convert();
|
|
|
|
- boolean ifAnnualized = params.getIfAnnualized() != null && params.getIfAnnualized();
|
|
|
|
- List<ValueLabelVO> effects = ListUtil.list(true);
|
|
|
|
- effects.add(new ValueLabelVO("allocation", "配置效应"));
|
|
|
|
- effects.add(new ValueLabelVO("stock", "选股效应"));
|
|
|
|
- effects.add(new ValueLabelVO("timing", "择时效应"));
|
|
|
|
- effects.add(new ValueLabelVO("total", "超额收益"));
|
|
|
|
- BizHandler<StockPerformanceAttributionParams, List<StockPerformanceAttributionVO>> bizHandler =
|
|
|
|
- this.factor.getBizHandlerInstance(STOCK_PERFORMANCE_ATTRIBUTION);
|
|
|
|
- List<StockPerformanceAttributionVO> dataList = bizHandler.bizHandle(params);
|
|
|
|
- if (CollUtil.isEmpty(dataList)) {
|
|
|
|
- return MapUtil.empty();
|
|
|
|
- }
|
|
|
|
- Map<String, Object> dataset = MapUtil.newHashMap();
|
|
|
|
- for (ValueLabelVO effect : effects) {
|
|
|
|
- List<NewDateValue> tempList = ListUtil.list(false);
|
|
|
|
- Function<StockPerformanceAttributionVO.Effect, Double> function = e -> {
|
|
|
|
- if ("allocation".equals(effect.getValue())) {
|
|
|
|
- return e.getAllocation();
|
|
|
|
- } else if ("stock".equals(effect.getValue())) {
|
|
|
|
- return e.getStock();
|
|
|
|
- } else if ("timing".equals(effect.getValue())) {
|
|
|
|
- return e.getTiming();
|
|
|
|
- } else if ("total".equals(effect.getValue())) {
|
|
|
|
- return e.getExactRet();
|
|
|
|
- }
|
|
|
|
- return null;
|
|
|
|
- };
|
|
|
|
- String prevDate = dataList.get(0).getDate();
|
|
|
|
- for (StockPerformanceAttributionVO vo : dataList) {
|
|
|
|
- String date = vo.getDate();
|
|
|
|
- double eff = vo.getEffect().stream().map(function).filter(Objects::nonNull).reduce(Double::sum).orElse(0d);
|
|
|
|
- // 需要年化时才年化
|
|
|
|
- if (ifAnnualized) {
|
|
|
|
- int dayCount = com.smppw.utils.DateUtil.getDateDistance(prevDate, date);
|
|
|
|
- eff = Math.pow(1 + eff, 365.0d / dayCount) - 1;
|
|
|
|
- }
|
|
|
|
- tempList.add(new NewDateValue(date, String.valueOf(eff)));
|
|
|
|
- prevDate = date;
|
|
|
|
- }
|
|
|
|
- dataset.put(effect.getValue(), tempList);
|
|
|
|
- }
|
|
|
|
- return MapUtil.<String, Object>builder().put("dataset", dataset)
|
|
|
|
- .put("productNameMapping", effects).put("table", dataList).build();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 配置数据转换为前端需要的dataset和table数据结构
|
|
|
|
- *
|
|
|
|
- * @param dataList 配置结构
|
|
|
|
- * @return /
|
|
|
|
- */
|
|
|
|
- private Map<String, Object> convertDataset(List<StockAllocationVO> dataList) {
|
|
|
|
- if (CollUtil.isEmpty(dataList)) {
|
|
|
|
- return MapUtil.empty();
|
|
|
|
- }
|
|
|
|
- List<ValueLabelVO> categoryList = ListUtil.list(false);
|
|
|
|
- for (StockAllocationVO vo : dataList) {
|
|
|
|
- List<ValueLabelVO> collect = vo.getIndustries().stream().map(CategoryConstraint::getCategory)
|
|
|
|
- .distinct().collect(Collectors.toList());
|
|
|
|
- CollUtil.addAllIfNotContains(categoryList, collect);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //修正为统计原有分组列表数量,先过滤其它字段后进行对比,当出现值不一致时追加其它字段,保证其它永远在最后
|
|
|
|
- int count = categoryList.size();
|
|
|
|
- categoryList = categoryList.stream().filter(e -> !PositionConstants.ASSET_OTHER.equalsIgnoreCase(e.getValue())).collect(Collectors.toList());
|
|
|
|
- if (count > categoryList.size()) {
|
|
|
|
- categoryList.add(PositionConstants.OTHER_ASSET);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return this.convertDataset(dataList, categoryList);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 配置数据转换为前端需要的dataset和table数据结构
|
|
|
|
- *
|
|
|
|
- * @param dataList 配置结构
|
|
|
|
- * @param categoryList 分类映射关系
|
|
|
|
- * @return /
|
|
|
|
- */
|
|
|
|
- private Map<String, Object> convertDataset(List<StockAllocationVO> dataList, List<ValueLabelVO> categoryList) {
|
|
|
|
- Map<String, Object> dataset = MapUtil.newHashMap(false);
|
|
|
|
- for (ValueLabelVO category : categoryList) {
|
|
|
|
- List<Map<String, Object>> tempList = ListUtil.list(true);
|
|
|
|
- for (StockAllocationVO vo : dataList) {
|
|
|
|
- Map<String, Object> temp = MapUtil.newHashMap();
|
|
|
|
- temp.put("date", vo.getDate());
|
|
|
|
- CategoryConstraint s = vo.getIndustries().stream().filter(e -> category.equals(e.getCategory()))
|
|
|
|
- .findFirst().orElse(null);
|
|
|
|
- temp.put("bull", Optional.ofNullable(s).map(CategoryConstraint::getBull).orElse(BigDecimal.ZERO));
|
|
|
|
- temp.put("bear", Optional.ofNullable(s).map(CategoryConstraint::getBear).orElse(BigDecimal.ZERO));
|
|
|
|
- temp.put("pupil", Optional.ofNullable(s).map(CategoryConstraint::getPupil).orElse(BigDecimal.ZERO));
|
|
|
|
- temp.put("benchmark", Optional.ofNullable(s).map(CategoryConstraint::getBenchmark).orElse(BigDecimal.ZERO));
|
|
|
|
- tempList.add(temp);
|
|
|
|
- }
|
|
|
|
- dataset.put(category.getValue(), tempList);
|
|
|
|
- }
|
|
|
|
- return MapUtil.<String, Object>builder().put("dataset", dataset).put("productNameMapping", categoryList)
|
|
|
|
- .put("table", dataList).build();
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
|
|
+//package com.smppw.analysis.application.service.position;
|
|
|
|
+//
|
|
|
|
+//import cn.hutool.core.collection.CollUtil;
|
|
|
|
+//import cn.hutool.core.collection.ListUtil;
|
|
|
|
+//import cn.hutool.core.date.DateUtil;
|
|
|
|
+//import cn.hutool.core.map.MapUtil;
|
|
|
|
+//import com.smppw.analysis.application.dto.position.*;
|
|
|
|
+//import com.smppw.analysis.domain.dao.PubliclyFundPositionDao;
|
|
|
|
+//import com.smppw.analysis.domain.dataobject.PubliclyFundStockChangeDO;
|
|
|
|
+//import com.smppw.analysis.domain.dataobject.SwSecIndustryInfoDO;
|
|
|
|
+//import com.smppw.analysis.domain.dto.position.*;
|
|
|
|
+//import com.smppw.analysis.domain.dto.position.stock.*;
|
|
|
|
+//import com.smppw.analysis.domain.manager.position.BizHandler;
|
|
|
|
+//import com.smppw.analysis.domain.manager.position.BizHandlerFactory;
|
|
|
|
+//import com.smppw.analysis.domain.manager.position.stock.IndustryAllocationPreferenceComponent;
|
|
|
|
+//import com.smppw.analysis.domain.mapper.core.BaseUnderlyingMapper;
|
|
|
|
+//import com.smppw.common.pojo.ValueLabelVO;
|
|
|
|
+//import com.smppw.common.pojo.dto.NewDateValue;
|
|
|
|
+//import org.springframework.stereotype.Component;
|
|
|
|
+//
|
|
|
|
+//import java.math.BigDecimal;
|
|
|
|
+//import java.util.*;
|
|
|
|
+//import java.util.function.Function;
|
|
|
|
+//import java.util.stream.Collectors;
|
|
|
|
+//
|
|
|
|
+//import static com.smppw.analysis.domain.manager.position.BizHandlerConstants.*;
|
|
|
|
+//
|
|
|
|
+///**
|
|
|
|
+// * @author wangzaijun
|
|
|
|
+// * @date 2023/6/6 14:41
|
|
|
|
+// * @description 基金持仓分析-股票tab
|
|
|
|
+// */
|
|
|
|
+//@Component
|
|
|
|
+//public class StockPositionAnalysis {
|
|
|
|
+// private static final Map<Long, String> POSITION_NAME = MapUtil.newHashMap(true);
|
|
|
|
+//
|
|
|
|
+// static {
|
|
|
|
+// POSITION_NAME.put(1L, "最大持仓");
|
|
|
|
+// POSITION_NAME.put(3L, "前三大持仓");
|
|
|
|
+// POSITION_NAME.put(5L, "前五大持仓");
|
|
|
|
+// POSITION_NAME.put(10L, "前十大持仓");
|
|
|
|
+// POSITION_NAME.put(-1L, "股票持仓");
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// private final BizHandlerFactory factor;
|
|
|
|
+// private final BaseUnderlyingMapper baseUnderlyingMapper;
|
|
|
|
+//// private final BarraSensitivityComponent barraSensitivity;
|
|
|
|
+// private final PubliclyFundPositionDao fundPositionBaseService;
|
|
|
|
+// private final IndustryAllocationPreferenceComponent industryAllocationPreference;
|
|
|
|
+//
|
|
|
|
+// public StockPositionAnalysis(BizHandlerFactory factor,
|
|
|
|
+// BaseUnderlyingMapper baseUnderlyingMapper,
|
|
|
|
+//// BarraSensitivityComponent barraSensitivity,
|
|
|
|
+// PubliclyFundPositionDao fundPositionBaseService,
|
|
|
|
+// IndustryAllocationPreferenceComponent industryAllocationPreference) {
|
|
|
|
+// this.factor = factor;
|
|
|
|
+//// this.barraSensitivity = barraSensitivity;
|
|
|
|
+// this.baseUnderlyingMapper = baseUnderlyingMapper;
|
|
|
|
+// this.fundPositionBaseService = fundPositionBaseService;
|
|
|
|
+// this.industryAllocationPreference = industryAllocationPreference;
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// public List<MajorChangeVO> getMajorChangeList(MajorChangeReq req) {
|
|
|
|
+// MajorChangeParams params = req.convert();
|
|
|
|
+// List<SwSecIndustryInfoDO> industryList = this.baseUnderlyingMapper.querySecIndustryInfo();
|
|
|
|
+// List<MajorChangeVO> resultList = ListUtil.list(false);
|
|
|
|
+// List<PubliclyFundStockChangeDO> dataList = this.fundPositionBaseService.mfStockChangeList(params.getFundId(),
|
|
|
|
+// params.getStartDate(), params.getEndDate());
|
|
|
|
+// for (PubliclyFundStockChangeDO data : dataList) {
|
|
|
|
+// String industryName = industryList.stream().filter(e -> data.getSecCode().equals(e.getSecCode())).findFirst()
|
|
|
|
+// .map(SwSecIndustryInfoDO::getIndustryName).orElse(null);
|
|
|
|
+// MajorChangeVO vo = new MajorChangeVO();
|
|
|
|
+// vo.setDate(DateUtil.formatDate(data.getReportDate()));
|
|
|
|
+// vo.setStockCode(data.getSecCode());
|
|
|
|
+// vo.setStockName(data.getSecName());
|
|
|
|
+// vo.setChangeType(Optional.ofNullable(data.getChangeType()).map(Object::toString).orElse(null));
|
|
|
|
+// vo.setAccumulatedTradeSum(Optional.ofNullable(data.getAccumulatedTradeSum()).map(BigDecimal::toPlainString).orElse(null));
|
|
|
|
+// vo.setRatioInNvAtBegin(Optional.ofNullable(data.getRatioInNvAtBegin()).map(BigDecimal::toPlainString).orElse(null));
|
|
|
|
+// vo.setIndustry(industryName);
|
|
|
|
+// resultList.add(vo);
|
|
|
|
+// }
|
|
|
|
+// // 按报告期降序
|
|
|
|
+// resultList.sort((o1, o2) -> o2.getDate().compareTo(o1.getDate()));
|
|
|
|
+// return resultList;
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// public Map<String, Object> getConcentration(ConcentrationReq req) {
|
|
|
|
+// ConcentrationParams params = req.convert();
|
|
|
|
+// Map<String, Object> dataset = MapUtil.newHashMap();
|
|
|
|
+// BizHandler<ConcentrationParams, List<ConcentrationVO>> bizHandler = this.factor.getBizHandlerInstance(STOCK_CONCENTRATION);
|
|
|
|
+// List<ConcentrationVO> dataList = bizHandler.bizHandle(params);
|
|
|
|
+// if (CollUtil.isEmpty(dataList)) {
|
|
|
|
+// return MapUtil.empty();
|
|
|
|
+// }
|
|
|
|
+// for (Long integer : POSITION_NAME.keySet()) {
|
|
|
|
+// List<MarketValueRatio> tempList = ListUtil.list(true);
|
|
|
|
+// for (ConcentrationVO vo : dataList) {
|
|
|
|
+// MarketValueRatio mvr = new MarketValueRatio();
|
|
|
|
+// mvr.setDate(vo.getDate());
|
|
|
|
+// List<RefMarketValueRatio> resList = vo.getPosition();
|
|
|
|
+// if (integer != -1L) {
|
|
|
|
+// // 不为-1时取前n条记录求和
|
|
|
|
+// resList = vo.getPosition().stream().limit(integer).collect(Collectors.toList());
|
|
|
|
+// }
|
|
|
|
+// BigDecimal marketValue = resList.stream().map(RefMarketValueRatio::getMarketValue)
|
|
|
|
+// .filter(Objects::nonNull).reduce(BigDecimal::add).orElse(null);
|
|
|
|
+// BigDecimal ratio = resList.stream().map(RefMarketValueRatio::getRatio).filter(Objects::nonNull)
|
|
|
|
+// .reduce(BigDecimal::add).orElse(null);
|
|
|
|
+// mvr.setMarketValue(marketValue);
|
|
|
|
+// mvr.setRatio(ratio);
|
|
|
|
+// tempList.add(mvr);
|
|
|
|
+// }
|
|
|
|
+// dataset.put(integer.toString(), tempList);
|
|
|
|
+// }
|
|
|
|
+// for (ConcentrationVO vo : dataList) {
|
|
|
|
+// List<RefMarketValueRatio> collect = vo.getPosition().stream().sorted((o1, o2) -> o2.getRatio().compareTo(o1.getRatio()))
|
|
|
|
+// .limit(10).collect(Collectors.toList());
|
|
|
|
+// vo.setPosition(collect);
|
|
|
|
+// }
|
|
|
|
+// return MapUtil.<String, Object>builder().put("dataset", dataset)
|
|
|
|
+// .put("productNameMapping", POSITION_NAME).put("table", dataList).build();
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// public List<ChangeNumberVO> getChangeNumber(ChangeNumberReq req) {
|
|
|
|
+// ChangeNumberParams params = req.convert();
|
|
|
|
+// BizHandler<ChangeNumberParams, List<ChangeNumberVO>> bizHandler = this.factor.getBizHandlerInstance(CHANGE_NUMBER);
|
|
|
|
+// List<ChangeNumberVO> dataList = bizHandler.bizHandle(params);
|
|
|
|
+// if (CollUtil.isEmpty(dataList)) {
|
|
|
|
+// return ListUtil.empty();
|
|
|
|
+// }
|
|
|
|
+// return dataList;
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// public Map<String, Object> getIndustryAllocation(StockAllocationReq req) {
|
|
|
|
+// StockAllocationParams params = req.convert();
|
|
|
|
+// BizHandler<StockAllocationParams, List<StockAllocationVO>> bizHandler = this.factor.getBizHandlerInstance(INDUSTRY_ALLOCATION);
|
|
|
|
+// List<StockAllocationVO> dataList = bizHandler.bizHandle(params);
|
|
|
|
+// return this.convertDataset(dataList);
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// public Map<String, Object> getIndustryAllocationPreference(StockAllocationReq req) {
|
|
|
|
+// StockAllocationParams params = req.convert();
|
|
|
|
+// List<IndustryAllocationPreferenceVO> dataList = this.industryAllocationPreference.bizHandle(params);
|
|
|
|
+// if (CollUtil.isEmpty(dataList)) {
|
|
|
|
+// return MapUtil.empty();
|
|
|
|
+// }
|
|
|
|
+// List<ValueLabelVO> industryList = dataList.get(0).getIndustryList();
|
|
|
|
+// // 倒序,其他排最后面
|
|
|
|
+// industryList.sort((o1, o2) -> o2.getValue().compareTo(o1.getValue()));
|
|
|
|
+// List<Map<String, Object>> dataset = ListUtil.list(true);
|
|
|
|
+// for (IndustryAllocationPreferenceVO temp : dataList) {
|
|
|
|
+// Map<String, Object> data = MapUtil.newHashMap(true);
|
|
|
|
+// data.put("date", temp.getDate());
|
|
|
|
+// data.putAll(temp.getIndustryPreference());
|
|
|
|
+// data.put("avg", temp.getAvg());
|
|
|
|
+// dataset.add(data);
|
|
|
|
+// }
|
|
|
|
+// return MapUtil.<String, Object>builder().put("dataset", dataset).put("productNameMapping", industryList).build();
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// public Map<String, Object> getStyleAllocation(StockAllocationReq req) {
|
|
|
|
+// StockAllocationParams params = req.convert();
|
|
|
|
+// BizHandler<StockAllocationParams, List<StockAllocationVO>> bizHandler = this.factor.getBizHandlerInstance(STYLE_ALLOCATION);
|
|
|
|
+// List<StockAllocationVO> dataList = bizHandler.bizHandle(params);
|
|
|
|
+// return this.convertDataset(dataList);
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// public Map<String, Object> getLiquidityAllocation(StockAllocationReq req) {
|
|
|
|
+// StockAllocationParams params = req.convert();
|
|
|
|
+// BizHandler<StockAllocationParams, List<StockAllocationVO>> bizHandler = this.factor.getBizHandlerInstance(LIQUIDITY_ALLOCATION);
|
|
|
|
+// List<StockAllocationVO> dataList = bizHandler.bizHandle(params);
|
|
|
|
+// List<ValueLabelVO> categoryList = Arrays.stream(PositionLiquidityEnum.values())
|
|
|
|
+// .map(e -> new ValueLabelVO(e.name(), e.getDesc())).collect(Collectors.toList());
|
|
|
|
+// return this.convertDataset(dataList, categoryList);
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+//// public Map<String, Object> getBarraSensitivity(BarraSensitivityReq req) {
|
|
|
|
+//// BarraSensitivityParams params = req.convert();
|
|
|
|
+//// return this.barraSensitivity.bizHandle(params);
|
|
|
|
+//// }
|
|
|
|
+//
|
|
|
|
+// public Map<String, Object> getPerformanceAttribution(StockPerformanceAttributionReq req) {
|
|
|
|
+// StockPerformanceAttributionParams params = req.convert();
|
|
|
|
+// boolean ifAnnualized = params.getIfAnnualized() != null && params.getIfAnnualized();
|
|
|
|
+// List<ValueLabelVO> effects = ListUtil.list(true);
|
|
|
|
+// effects.add(new ValueLabelVO("allocation", "配置效应"));
|
|
|
|
+// effects.add(new ValueLabelVO("stock", "选股效应"));
|
|
|
|
+// effects.add(new ValueLabelVO("timing", "择时效应"));
|
|
|
|
+// effects.add(new ValueLabelVO("total", "超额收益"));
|
|
|
|
+// BizHandler<StockPerformanceAttributionParams, List<StockPerformanceAttributionVO>> bizHandler =
|
|
|
|
+// this.factor.getBizHandlerInstance(STOCK_PERFORMANCE_ATTRIBUTION);
|
|
|
|
+// List<StockPerformanceAttributionVO> dataList = bizHandler.bizHandle(params);
|
|
|
|
+// if (CollUtil.isEmpty(dataList)) {
|
|
|
|
+// return MapUtil.empty();
|
|
|
|
+// }
|
|
|
|
+// Map<String, Object> dataset = MapUtil.newHashMap();
|
|
|
|
+// for (ValueLabelVO effect : effects) {
|
|
|
|
+// List<NewDateValue> tempList = ListUtil.list(false);
|
|
|
|
+// Function<StockPerformanceAttributionVO.Effect, Double> function = e -> {
|
|
|
|
+// if ("allocation".equals(effect.getValue())) {
|
|
|
|
+// return e.getAllocation();
|
|
|
|
+// } else if ("stock".equals(effect.getValue())) {
|
|
|
|
+// return e.getStock();
|
|
|
|
+// } else if ("timing".equals(effect.getValue())) {
|
|
|
|
+// return e.getTiming();
|
|
|
|
+// } else if ("total".equals(effect.getValue())) {
|
|
|
|
+// return e.getExactRet();
|
|
|
|
+// }
|
|
|
|
+// return null;
|
|
|
|
+// };
|
|
|
|
+// String prevDate = dataList.get(0).getDate();
|
|
|
|
+// for (StockPerformanceAttributionVO vo : dataList) {
|
|
|
|
+// String date = vo.getDate();
|
|
|
|
+// double eff = vo.getEffect().stream().map(function).filter(Objects::nonNull).reduce(Double::sum).orElse(0d);
|
|
|
|
+// // 需要年化时才年化
|
|
|
|
+// if (ifAnnualized) {
|
|
|
|
+// int dayCount = com.smppw.utils.DateUtil.getDateDistance(prevDate, date);
|
|
|
|
+// eff = Math.pow(1 + eff, 365.0d / dayCount) - 1;
|
|
|
|
+// }
|
|
|
|
+// tempList.add(new NewDateValue(date, String.valueOf(eff)));
|
|
|
|
+// prevDate = date;
|
|
|
|
+// }
|
|
|
|
+// dataset.put(effect.getValue(), tempList);
|
|
|
|
+// }
|
|
|
|
+// return MapUtil.<String, Object>builder().put("dataset", dataset)
|
|
|
|
+// .put("productNameMapping", effects).put("table", dataList).build();
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 配置数据转换为前端需要的dataset和table数据结构
|
|
|
|
+// *
|
|
|
|
+// * @param dataList 配置结构
|
|
|
|
+// * @return /
|
|
|
|
+// */
|
|
|
|
+// private Map<String, Object> convertDataset(List<StockAllocationVO> dataList) {
|
|
|
|
+// if (CollUtil.isEmpty(dataList)) {
|
|
|
|
+// return MapUtil.empty();
|
|
|
|
+// }
|
|
|
|
+// List<ValueLabelVO> categoryList = ListUtil.list(false);
|
|
|
|
+// for (StockAllocationVO vo : dataList) {
|
|
|
|
+// List<ValueLabelVO> collect = vo.getIndustries().stream().map(CategoryConstraint::getCategory)
|
|
|
|
+// .distinct().collect(Collectors.toList());
|
|
|
|
+// CollUtil.addAllIfNotContains(categoryList, collect);
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// //修正为统计原有分组列表数量,先过滤其它字段后进行对比,当出现值不一致时追加其它字段,保证其它永远在最后
|
|
|
|
+// int count = categoryList.size();
|
|
|
|
+// categoryList = categoryList.stream().filter(e -> !PositionConstants.ASSET_OTHER.equalsIgnoreCase(e.getValue())).collect(Collectors.toList());
|
|
|
|
+// if (count > categoryList.size()) {
|
|
|
|
+// categoryList.add(PositionConstants.OTHER_ASSET);
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// return this.convertDataset(dataList, categoryList);
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// /**
|
|
|
|
+// * 配置数据转换为前端需要的dataset和table数据结构
|
|
|
|
+// *
|
|
|
|
+// * @param dataList 配置结构
|
|
|
|
+// * @param categoryList 分类映射关系
|
|
|
|
+// * @return /
|
|
|
|
+// */
|
|
|
|
+// private Map<String, Object> convertDataset(List<StockAllocationVO> dataList, List<ValueLabelVO> categoryList) {
|
|
|
|
+// Map<String, Object> dataset = MapUtil.newHashMap(false);
|
|
|
|
+// for (ValueLabelVO category : categoryList) {
|
|
|
|
+// List<Map<String, Object>> tempList = ListUtil.list(true);
|
|
|
|
+// for (StockAllocationVO vo : dataList) {
|
|
|
|
+// Map<String, Object> temp = MapUtil.newHashMap();
|
|
|
|
+// temp.put("date", vo.getDate());
|
|
|
|
+// CategoryConstraint s = vo.getIndustries().stream().filter(e -> category.equals(e.getCategory()))
|
|
|
|
+// .findFirst().orElse(null);
|
|
|
|
+// temp.put("bull", Optional.ofNullable(s).map(CategoryConstraint::getBull).orElse(BigDecimal.ZERO));
|
|
|
|
+// temp.put("bear", Optional.ofNullable(s).map(CategoryConstraint::getBear).orElse(BigDecimal.ZERO));
|
|
|
|
+// temp.put("pupil", Optional.ofNullable(s).map(CategoryConstraint::getPupil).orElse(BigDecimal.ZERO));
|
|
|
|
+// temp.put("benchmark", Optional.ofNullable(s).map(CategoryConstraint::getBenchmark).orElse(BigDecimal.ZERO));
|
|
|
|
+// tempList.add(temp);
|
|
|
|
+// }
|
|
|
|
+// dataset.put(category.getValue(), tempList);
|
|
|
|
+// }
|
|
|
|
+// return MapUtil.<String, Object>builder().put("dataset", dataset).put("productNameMapping", categoryList)
|
|
|
|
+// .put("table", dataList).build();
|
|
|
|
+// }
|
|
|
|
+//}
|