Forráskód Böngészése

feat:基金持仓分析请求参数支持签名校验

wangzaijun 1 éve
szülő
commit
16ba7d655c
21 módosított fájl, 418 hozzáadás és 255 törlés
  1. 20 0
      src/main/java/com/smppw/analysis/application/dto/position/AssetAllocationReq.java
  2. 29 0
      src/main/java/com/smppw/analysis/application/dto/position/BarraSensitivityReq.java
  3. 30 0
      src/main/java/com/smppw/analysis/application/dto/position/BasePositionReq.java
  4. 20 0
      src/main/java/com/smppw/analysis/application/dto/position/ChangeNumberReq.java
  5. 20 0
      src/main/java/com/smppw/analysis/application/dto/position/ConcentrationReq.java
  6. 20 0
      src/main/java/com/smppw/analysis/application/dto/position/HolderInfoReq.java
  7. 20 0
      src/main/java/com/smppw/analysis/application/dto/position/LeverageChangeReq.java
  8. 20 0
      src/main/java/com/smppw/analysis/application/dto/position/MajorChangeReq.java
  9. 20 0
      src/main/java/com/smppw/analysis/application/dto/position/MarginalRiskContributionReq.java
  10. 20 0
      src/main/java/com/smppw/analysis/application/dto/position/PositionInfoReq.java
  11. 36 0
      src/main/java/com/smppw/analysis/application/dto/position/PositionListReq.java
  12. 30 0
      src/main/java/com/smppw/analysis/application/dto/position/StockAllocationReq.java
  13. 29 0
      src/main/java/com/smppw/analysis/application/dto/position/StockPerformanceAttributionReq.java
  14. 43 0
      src/main/java/com/smppw/analysis/application/dto/style/BaseStyleReq.java
  15. 3 1
      src/main/java/com/smppw/analysis/application/service/position/FuturePositionAnalysis.java
  16. 22 42
      src/main/java/com/smppw/analysis/application/service/position/StockPositionAnalysis.java
  17. 13 7
      src/main/java/com/smppw/analysis/application/service/position/SynthesizePositionAnalysis.java
  18. 23 30
      src/main/java/com/smppw/analysis/client/FundPositionApi.java
  19. 0 15
      src/main/java/com/smppw/analysis/domain/dto/position/stock/RiskExposureParams.java
  20. 0 26
      src/main/java/com/smppw/analysis/domain/dto/position/stock/RiskExposureVO.java
  21. 0 134
      src/main/java/com/smppw/analysis/domain/manager/position/stock/RiskExposureBizHandler.java

+ 20 - 0
src/main/java/com/smppw/analysis/application/dto/position/AssetAllocationReq.java

@@ -0,0 +1,20 @@
+package com.smppw.analysis.application.dto.position;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.smppw.analysis.domain.dto.position.synthesize.AssetAllocationParams;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author wangzaijun
+ * @date 2023/6/6 11:30
+ * @description 大类资产配置,后续支持穿透
+ */
+@Setter
+@Getter
+public class AssetAllocationReq extends BasePositionReq<AssetAllocationParams> {
+    @Override
+    public AssetAllocationParams convert() {
+        return BeanUtil.copyProperties(this, AssetAllocationParams.class);
+    }
+}

+ 29 - 0
src/main/java/com/smppw/analysis/application/dto/position/BarraSensitivityReq.java

@@ -0,0 +1,29 @@
+package com.smppw.analysis.application.dto.position;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.smppw.analysis.domain.dto.position.stock.BarraSensitivityParams;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author wangzaijun
+ * @date 2023/6/6 17:13
+ * @description 股票barra敏感度分析 接口请求参数
+ */
+@Setter
+@Getter
+public class BarraSensitivityReq extends BasePositionReq<BarraSensitivityParams> {
+    /**
+     * 基准,只支持 沪深300、中证500、中证1000
+     */
+    private String benchmarkId;
+    /**
+     * 估值日期
+     */
+    private String date;
+
+    @Override
+    public BarraSensitivityParams convert() {
+        return BeanUtil.copyProperties(this, BarraSensitivityParams.class);
+    }
+}

+ 30 - 0
src/main/java/com/smppw/analysis/application/dto/position/BasePositionReq.java

@@ -0,0 +1,30 @@
+package com.smppw.analysis.application.dto.position;
+
+import com.smppw.analysis.application.dto.BaseReq;
+import com.smppw.analysis.domain.dto.position.BaseParams;
+import lombok.Getter;
+import lombok.Setter;
+
+@Setter
+@Getter
+public abstract class BasePositionReq<R extends BaseParams> extends BaseReq {
+    /**
+     * 基金id
+     */
+    private String fundId;
+    /**
+     * 开始时间
+     */
+    private String startDate;
+    /**
+     * 结束时间
+     */
+    private String endDate;
+
+    /**
+     * 把当前的对象转换为R类型的对象
+     *
+     * @return /
+     */
+    public abstract R convert();
+}

+ 20 - 0
src/main/java/com/smppw/analysis/application/dto/position/ChangeNumberReq.java

@@ -0,0 +1,20 @@
+package com.smppw.analysis.application.dto.position;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.smppw.analysis.domain.dto.position.stock.ChangeNumberParams;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author wangzaijun
+ * @date 2023/6/6 14:53
+ * @description 持股数量变动时序 接口请求参数
+ */
+@Setter
+@Getter
+public class ChangeNumberReq extends BasePositionReq<ChangeNumberParams> {
+    @Override
+    public ChangeNumberParams convert() {
+        return BeanUtil.copyProperties(this, ChangeNumberParams.class);
+    }
+}

+ 20 - 0
src/main/java/com/smppw/analysis/application/dto/position/ConcentrationReq.java

@@ -0,0 +1,20 @@
+package com.smppw.analysis.application.dto.position;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.smppw.analysis.domain.dto.position.stock.ConcentrationParams;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author wangzaijun
+ * @date 2023/6/6 14:53
+ * @description 股票集中度 接口请求参数
+ */
+@Setter
+@Getter
+public class ConcentrationReq extends BasePositionReq<ConcentrationParams> {
+    @Override
+    public ConcentrationParams convert() {
+        return BeanUtil.copyProperties(this, ConcentrationParams.class);
+    }
+}

+ 20 - 0
src/main/java/com/smppw/analysis/application/dto/position/HolderInfoReq.java

@@ -0,0 +1,20 @@
+package com.smppw.analysis.application.dto.position;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.smppw.analysis.domain.dto.position.synthesize.HolderInfoParams;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author wangzaijun
+ * @date 2023/6/6 14:26
+ * @description 公募基金持有人结构 请求参数
+ */
+@Setter
+@Getter
+public class HolderInfoReq extends BasePositionReq<HolderInfoParams> {
+    @Override
+    public HolderInfoParams convert() {
+        return BeanUtil.copyProperties(this, HolderInfoParams.class);
+    }
+}

+ 20 - 0
src/main/java/com/smppw/analysis/application/dto/position/LeverageChangeReq.java

@@ -0,0 +1,20 @@
+package com.smppw.analysis.application.dto.position;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.smppw.analysis.domain.dto.position.synthesize.LeverageChangeParams;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author wangzaijun
+ * @date 2023/6/6 11:30
+ * @description 杠杆变化,不需要支持穿透
+ */
+@Setter
+@Getter
+public class LeverageChangeReq extends BasePositionReq<LeverageChangeParams> {
+    @Override
+    public LeverageChangeParams convert() {
+        return BeanUtil.copyProperties(this, LeverageChangeParams.class);
+    }
+}

+ 20 - 0
src/main/java/com/smppw/analysis/application/dto/position/MajorChangeReq.java

@@ -0,0 +1,20 @@
+package com.smppw.analysis.application.dto.position;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.smppw.analysis.domain.dto.position.stock.MajorChangeParams;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author wangzaijun
+ * @date 2023/6/6 14:53
+ * @description 持仓股票重大变动 接口请求参数
+ */
+@Setter
+@Getter
+public class MajorChangeReq extends BasePositionReq<MajorChangeParams> {
+    @Override
+    public MajorChangeParams convert() {
+        return BeanUtil.copyProperties(this, MajorChangeParams.class);
+    }
+}

+ 20 - 0
src/main/java/com/smppw/analysis/application/dto/position/MarginalRiskContributionReq.java

@@ -0,0 +1,20 @@
+package com.smppw.analysis.application.dto.position;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.smppw.analysis.domain.dto.position.future.MarginalRiskContributionParams;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author wangzaijun
+ * @date 2023/6/19 11:16
+ * @description 私募基金期货的边际风险贡献接口请求参数
+ */
+@Setter
+@Getter
+public class MarginalRiskContributionReq extends BasePositionReq<MarginalRiskContributionParams> {
+    @Override
+    public MarginalRiskContributionParams convert() {
+        return BeanUtil.copyProperties(this, MarginalRiskContributionParams.class);
+    }
+}

+ 20 - 0
src/main/java/com/smppw/analysis/application/dto/position/PositionInfoReq.java

@@ -0,0 +1,20 @@
+package com.smppw.analysis.application.dto.position;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.smppw.analysis.domain.dto.position.synthesize.PositionInfoParams;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author wangzaijun
+ * @date 2023/6/6 14:10
+ * @description 持仓列表的返回参数接口的请求参数
+ */
+@Setter
+@Getter
+public class PositionInfoReq extends BasePositionReq<PositionInfoParams> {
+    @Override
+    public PositionInfoParams convert() {
+        return BeanUtil.copyProperties(this, PositionInfoParams.class);
+    }
+}

+ 36 - 0
src/main/java/com/smppw/analysis/application/dto/position/PositionListReq.java

@@ -0,0 +1,36 @@
+package com.smppw.analysis.application.dto.position;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.smppw.analysis.domain.dto.position.AssetCategoryEnum;
+import com.smppw.analysis.domain.dto.position.synthesize.PositionListParams;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author wangzaijun
+ * @date 2023/6/6 11:30
+ * @description 持仓列表,后续需要支持穿透
+ */
+@Setter
+@Getter
+public class PositionListReq extends BasePositionReq<PositionListParams> {
+    /**
+     * 数量,前10、前20、前50,-1-全部,默认前10
+     */
+    private String num;
+    /**
+     * 类别
+     *
+     * @see AssetCategoryEnum
+     */
+    private String type;
+    /**
+     * 估值日期
+     */
+    private String date;
+
+    @Override
+    public PositionListParams convert() {
+        return BeanUtil.copyProperties(this, PositionListParams.class);
+    }
+}

+ 30 - 0
src/main/java/com/smppw/analysis/application/dto/position/StockAllocationReq.java

@@ -0,0 +1,30 @@
+package com.smppw.analysis.application.dto.position;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.smppw.analysis.domain.dto.position.stock.StockAllocationParams;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author wangzaijun
+ * @date 2023/6/6 15:27
+ * @description 行业配置\风格配置或流动性 接口请求参数
+ */
+@Setter
+@Getter
+public class StockAllocationReq extends BasePositionReq<StockAllocationParams> {
+    /**
+     * 基准,只支持 沪深300、中证500、中证1000
+     */
+    private String benchmarkId;
+    /**
+     * 方向约束,默认多空,其他条件不生效
+     * 1-多头,2-空头,3-多空
+     */
+    private String constraint;
+
+    @Override
+    public StockAllocationParams convert() {
+        return BeanUtil.copyProperties(this, StockAllocationParams.class);
+    }
+}

+ 29 - 0
src/main/java/com/smppw/analysis/application/dto/position/StockPerformanceAttributionReq.java

@@ -0,0 +1,29 @@
+package com.smppw.analysis.application.dto.position;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.smppw.analysis.domain.dto.position.stock.StockPerformanceAttributionParams;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author wangzaijun
+ * @date 2023/6/6 16:31
+ * @description 股票业绩归因 接口请求参数
+ */
+@Setter
+@Getter
+public class StockPerformanceAttributionReq extends BasePositionReq<StockPerformanceAttributionParams> {
+    /**
+     * 基准,只支持 沪深300、中证500、中证1000
+     */
+    private String benchmarkId;
+    /**
+     * 是否年化,默认不年化
+     */
+    private Boolean ifAnnualized;
+
+    @Override
+    public StockPerformanceAttributionParams convert() {
+        return BeanUtil.copyProperties(this, StockPerformanceAttributionParams.class);
+    }
+}

+ 43 - 0
src/main/java/com/smppw/analysis/application/dto/style/BaseStyleReq.java

@@ -0,0 +1,43 @@
+package com.smppw.analysis.application.dto.style;
+
+import com.smppw.analysis.application.dto.BaseReq;
+import com.smppw.analysis.domain.dto.style.BaseParams;
+import com.smppw.common.pojo.enums.Frequency;
+import com.smppw.common.pojo.enums.RaiseType;
+import lombok.Getter;
+import lombok.Setter;
+
+@Setter
+@Getter
+public abstract class BaseStyleReq<R extends BaseParams> extends BaseReq {
+    /**
+     * 标的id,包括基金、机构行业经理
+     */
+    private String secId;
+    /**
+     * 开始日期
+     */
+    private String startDate;
+    /**
+     * 结束日期
+     */
+    private String endDate;
+    /**
+     * 滚动期数,默认24期
+     */
+    private String winlen;
+    /**
+     * 滚动步长,默认1
+     */
+    private String step;
+    /**
+     * 净值频率
+     */
+    private Frequency frequency;
+
+    private RaiseType raiseType;
+
+    private String strategy;
+
+    public abstract R convert();
+}

+ 3 - 1
src/main/java/com/smppw/analysis/application/service/position/FuturePositionAnalysis.java

@@ -3,6 +3,7 @@ package com.smppw.analysis.application.service.position;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.collection.ListUtil;
 import cn.hutool.core.map.MapUtil;
+import com.smppw.analysis.application.dto.position.MarginalRiskContributionReq;
 import com.smppw.analysis.domain.dto.position.RefMarketValueRatio;
 import com.smppw.analysis.domain.dto.position.future.MarginalRiskContribution;
 import com.smppw.analysis.domain.dto.position.future.MarginalRiskContributionParams;
@@ -31,7 +32,8 @@ public class FuturePositionAnalysis {
         this.factor = factor;
     }
 
-    public Map<String, Object> riskCont(MarginalRiskContributionParams params) {
+    public Map<String, Object> riskCont(MarginalRiskContributionReq req) {
+        MarginalRiskContributionParams params = req.convert();
         BizHandler<MarginalRiskContributionParams, List<MarginalRiskContributionVO>> bizHandler = this.factor.getBizHandlerInstance(BizHandlerConstants.MARGINAL_RISK_CONTRIBUTION);
         List<MarginalRiskContributionVO> dataList = bizHandler.bizHandle(params);
         if (CollUtil.isEmpty(dataList)) {

+ 22 - 42
src/main/java/com/smppw/analysis/application/service/position/StockPositionAnalysis.java

@@ -4,15 +4,16 @@ 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.dao.PubliclyFundPositionDao;
-import com.smppw.analysis.domain.dataobject.PubliclyFundStockChangeDO;
-import com.smppw.analysis.domain.dataobject.SwSecIndustryInfoDO;
 import com.smppw.analysis.domain.persistence.BaseUnderlyingMapper;
 import com.smppw.common.pojo.ValueLabelVO;
 import com.smppw.common.pojo.dto.NewDateValue;
@@ -60,7 +61,8 @@ public class StockPositionAnalysis {
         this.industryAllocationPreference = industryAllocationPreference;
     }
 
-    public List<MajorChangeVO> getMajorChangeList(MajorChangeParams params) {
+    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(),
@@ -83,7 +85,8 @@ public class StockPositionAnalysis {
         return resultList;
     }
 
-    public Map<String, Object> getConcentration(ConcentrationParams params) {
+    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);
@@ -119,7 +122,8 @@ public class StockPositionAnalysis {
                 .put("productNameMapping", POSITION_NAME).put("table", dataList).build();
     }
 
-    public List<ChangeNumberVO> getChangeNumber(ChangeNumberParams params) {
+    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)) {
@@ -128,13 +132,15 @@ public class StockPositionAnalysis {
         return dataList;
     }
 
-    public Map<String, Object> getIndustryAllocation(StockAllocationParams params) {
+    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(StockAllocationParams params) {
+    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();
@@ -153,13 +159,15 @@ public class StockPositionAnalysis {
         return MapUtil.<String, Object>builder().put("dataset", dataset).put("productNameMapping", industryList).build();
     }
 
-    public Map<String, Object> getStyleAllocation(StockAllocationParams params) {
+    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(StockAllocationParams params) {
+    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())
@@ -167,41 +175,13 @@ public class StockPositionAnalysis {
         return this.convertDataset(dataList, categoryList);
     }
 
-    public Map<String, Object> getBarraSensitivity(BarraSensitivityParams params) {
+    public Map<String, Object> getBarraSensitivity(BarraSensitivityReq req) {
+        BarraSensitivityParams params = req.convert();
         return this.barraSensitivity.bizHandle(params);
     }
 
-    public Map<String, Object> getRiskExposure(RiskExposureParams params) {
-        BizHandler<RiskExposureParams, List<RiskExposureVO>> bizHandler = this.factor.getBizHandlerInstance(RISK_EXPOSURE);
-        List<RiskExposureVO> dataList = bizHandler.bizHandle(params);
-        if (CollUtil.isEmpty(dataList)) {
-            return MapUtil.empty();
-        }
-        Map<String, Object> dataset = MapUtil.newHashMap();
-        for (RiskExposureEnum value : RiskExposureEnum.values()) {
-            List<MarketValueRatio> tempList = ListUtil.list(true);
-            for (RiskExposureVO temp : dataList) {
-                RefMarketValueRatio ratio = temp.getMvr().stream().filter(e -> value.name()
-                        .equals(e.getRef().getValue())).findFirst().orElse(null);
-                if (ratio == null) {
-                    continue;
-                }
-                MarketValueRatio mvr = new MarketValueRatio();
-                mvr.setDate(temp.getDate());
-                mvr.setMarketValue(ratio.getMarketValue());
-                mvr.setRatio(ratio.getRatio());
-                tempList.add(mvr);
-            }
-            tempList.sort(Comparator.comparing(MarketValueRatio::getDate));
-            dataset.put(value.name(), tempList);
-        }
-        List<ValueLabelVO> collect = Arrays.stream(RiskExposureEnum.values()).map(e -> new ValueLabelVO(e.name(), e.getDesc()))
-                .collect(Collectors.toList());
-        return MapUtil.<String, Object>builder().put("dataset", dataset)
-                .put("productNameMapping", collect).put("table", dataList).build();
-    }
-
-    public Map<String, Object> getPerformanceAttribution(StockPerformanceAttributionParams 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", "配置效应"));

+ 13 - 7
src/main/java/com/smppw/analysis/application/service/position/SynthesizePositionAnalysis.java

@@ -5,6 +5,9 @@ import cn.hutool.core.collection.ListUtil;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.util.NumberUtil;
+import com.smppw.analysis.application.dto.position.*;
+import com.smppw.analysis.domain.dao.PubliclyFundPositionDao;
+import com.smppw.analysis.domain.dataobject.PubliclyFundHolderInfoDO;
 import com.smppw.analysis.domain.dto.position.AssetCategoryEnum;
 import com.smppw.analysis.domain.dto.position.MarketValueRatio;
 import com.smppw.analysis.domain.dto.position.PositionConstants;
@@ -12,8 +15,6 @@ import com.smppw.analysis.domain.dto.position.RefMarketValueRatio;
 import com.smppw.analysis.domain.dto.position.synthesize.*;
 import com.smppw.analysis.domain.manager.position.BizHandler;
 import com.smppw.analysis.domain.manager.position.BizHandlerFactory;
-import com.smppw.analysis.domain.dao.PubliclyFundPositionDao;
-import com.smppw.analysis.domain.dataobject.PubliclyFundHolderInfoDO;
 import com.smppw.common.pojo.ValueLabelVO;
 import org.springframework.stereotype.Component;
 
@@ -53,7 +54,8 @@ public class SynthesizePositionAnalysis {
         this.fundPositionBaseService = fundPositionBaseService;
     }
 
-    public Map<String, Object> getAssetAllocation(AssetAllocationParams params) {
+    public Map<String, Object> getAssetAllocation(AssetAllocationReq req) {
+        AssetAllocationParams params = req.convert();
         BizHandler<AssetAllocationParams, List<AssetAllocationVO>> bizHandler = this.factor.getBizHandlerInstance(ASSET_ALLOCATION);
         List<AssetAllocationVO> dataList = bizHandler.bizHandle(params);
         if (CollUtil.isEmpty(dataList)) {
@@ -77,7 +79,8 @@ public class SynthesizePositionAnalysis {
         return MapUtil.<String, Object>builder().put("dataset", dataset).put("productNameMapping", mapping).put("table", dataList).build();
     }
 
-    public List<LeverageChangeVO> getLeverageChange(LeverageChangeParams params) {
+    public List<LeverageChangeVO> getLeverageChange(LeverageChangeReq req) {
+        LeverageChangeParams params = req.convert();
         BizHandler<LeverageChangeParams, List<LeverageChangeVO>> bizHandler = this.factor.getBizHandlerInstance(LEVERAGE_CHANGE);
         List<LeverageChangeVO> dataList = bizHandler.bizHandle(params);
         if (CollUtil.isEmpty(dataList)) {
@@ -86,12 +89,14 @@ public class SynthesizePositionAnalysis {
         return dataList;
     }
 
-    public PositionInfoVO getPositionParams(PositionInfoParams params) {
+    public PositionInfoVO getPositionParams(PositionInfoReq req) {
+        PositionInfoParams params = req.convert();
         BizHandler<PositionInfoParams, PositionInfoVO> bizHandler = this.factor.getBizHandlerInstance(POSITION_PARAMS);
         return bizHandler.bizHandle(params);
     }
 
-    public List<PositionListVO> getPosition(PositionListParams params) {
+    public List<PositionListVO> getPosition(PositionListReq req) {
+        PositionListParams params = req.convert();
         BizHandler<PositionListParams, List<PositionListVO>> bizHandler = this.factor.getBizHandlerInstance(POSITION_LIST);
         List<PositionListVO> dataList = bizHandler.bizHandle(params);
         if (CollUtil.isEmpty(dataList)) {
@@ -100,7 +105,8 @@ public class SynthesizePositionAnalysis {
         return dataList;
     }
 
-    public List<HolderInfoVO> getHolderInfo(HolderInfoParams params) {
+    public List<HolderInfoVO> getHolderInfo(HolderInfoReq req) {
+        HolderInfoParams params = req.convert();
         List<HolderInfoVO> resultList = ListUtil.list(true);
         List<PubliclyFundHolderInfoDO> dataList = this.fundPositionBaseService.mfHolderInfoList(params.getFundId(), params.getStartDate(), params.getEndDate());
         for (PubliclyFundHolderInfoDO data : dataList) {

+ 23 - 30
src/main/java/com/smppw/analysis/client/FundPositionApi.java

@@ -1,13 +1,17 @@
 package com.smppw.analysis.client;
 
-import com.smppw.analysis.domain.dto.position.bond.BondSortAllocationParam;
-import com.smppw.analysis.domain.dto.position.future.MarginalRiskContributionParams;
-import com.smppw.analysis.domain.dto.position.stock.*;
-import com.smppw.analysis.domain.dto.position.synthesize.*;
+import com.smppw.analysis.application.dto.position.*;
 import com.smppw.analysis.application.service.position.FundFuturesOptionService;
 import com.smppw.analysis.application.service.position.FuturePositionAnalysis;
 import com.smppw.analysis.application.service.position.StockPositionAnalysis;
 import com.smppw.analysis.application.service.position.SynthesizePositionAnalysis;
+import com.smppw.analysis.domain.dto.position.bond.BondSortAllocationParam;
+import com.smppw.analysis.domain.dto.position.stock.ChangeNumberVO;
+import com.smppw.analysis.domain.dto.position.stock.MajorChangeVO;
+import com.smppw.analysis.domain.dto.position.synthesize.HolderInfoVO;
+import com.smppw.analysis.domain.dto.position.synthesize.LeverageChangeVO;
+import com.smppw.analysis.domain.dto.position.synthesize.PositionInfoVO;
+import com.smppw.analysis.domain.dto.position.synthesize.PositionListVO;
 import com.smppw.analysis.domain.manager.position.bond.BondPositionService;
 import com.smppw.common.pojo.ResultVo;
 import org.springframework.web.bind.annotation.*;
@@ -47,7 +51,7 @@ public class FundPositionApi {
      * @return /
      */
     @GetMapping("asset-allocation")
-    public ResultVo<Map<String, Object>> getAssetAllocation(AssetAllocationParams params) {
+    public ResultVo<Map<String, Object>> getAssetAllocation(AssetAllocationReq params) {
         return ResultVo.ok(this.synthesize.getAssetAllocation(params));
     }
 
@@ -58,7 +62,7 @@ public class FundPositionApi {
      * @return /
      */
     @GetMapping("leverage-change")
-    public ResultVo<List<LeverageChangeVO>> getLeverageChange(LeverageChangeParams params) {
+    public ResultVo<List<LeverageChangeVO>> getLeverageChange(LeverageChangeReq params) {
         return ResultVo.ok(this.synthesize.getLeverageChange(params));
     }
 
@@ -69,7 +73,7 @@ public class FundPositionApi {
      * @return /
      */
     @GetMapping("position-param")
-    public ResultVo<PositionInfoVO> getPositionParams(PositionInfoParams params) {
+    public ResultVo<PositionInfoVO> getPositionParams(PositionInfoReq params) {
         return ResultVo.ok(this.synthesize.getPositionParams(params));
     }
 
@@ -80,7 +84,7 @@ public class FundPositionApi {
      * @return /
      */
     @GetMapping("position-list")
-    public ResultVo<List<PositionListVO>> getPosition(PositionListParams params) {
+    public ResultVo<List<PositionListVO>> getPosition(PositionListReq params) {
         return ResultVo.ok(this.synthesize.getPosition(params));
     }
 
@@ -91,7 +95,7 @@ public class FundPositionApi {
      * @return /
      */
     @GetMapping("holder-info")
-    public ResultVo<List<HolderInfoVO>> getHolderInfo(HolderInfoParams params) {
+    public ResultVo<List<HolderInfoVO>> getHolderInfo(HolderInfoReq params) {
         return ResultVo.ok(this.synthesize.getHolderInfo(params));
     }
 
@@ -102,7 +106,7 @@ public class FundPositionApi {
      * @return /
      */
     @GetMapping("stock/major-change")
-    public ResultVo<List<MajorChangeVO>> getMajorChange(MajorChangeParams params) {
+    public ResultVo<List<MajorChangeVO>> getMajorChange(MajorChangeReq params) {
         return ResultVo.ok(this.stock.getMajorChangeList(params));
     }
 
@@ -113,7 +117,7 @@ public class FundPositionApi {
      * @return /
      */
     @GetMapping("stock/crn")
-    public ResultVo<Map<String, Object>> getStockConcentration(ConcentrationParams params) {
+    public ResultVo<Map<String, Object>> getStockConcentration(ConcentrationReq params) {
         return ResultVo.ok(this.stock.getConcentration(params));
     }
 
@@ -124,7 +128,7 @@ public class FundPositionApi {
      * @return /
      */
     @GetMapping("stock/change-num")
-    public ResultVo<List<ChangeNumberVO>> getStockChangeNumber(ChangeNumberParams params) {
+    public ResultVo<List<ChangeNumberVO>> getStockChangeNumber(ChangeNumberReq params) {
         return ResultVo.ok(this.stock.getChangeNumber(params));
     }
 
@@ -135,7 +139,7 @@ public class FundPositionApi {
      * @return /
      */
     @GetMapping("stock/industry-allocation")
-    public ResultVo<Map<String, Object>> getStockIndustryAllocation(StockAllocationParams params) {
+    public ResultVo<Map<String, Object>> getStockIndustryAllocation(StockAllocationReq params) {
         return ResultVo.ok(this.stock.getIndustryAllocation(params));
     }
 
@@ -146,7 +150,7 @@ public class FundPositionApi {
      * @return /
      */
     @GetMapping("stock/industry-allocation-preference")
-    public ResultVo<Map<String, Object>> getStockIndustryAllocationPreference(StockAllocationParams params) {
+    public ResultVo<Map<String, Object>> getStockIndustryAllocationPreference(StockAllocationReq params) {
         return ResultVo.ok(this.stock.getIndustryAllocationPreference(params));
     }
 
@@ -157,7 +161,7 @@ public class FundPositionApi {
      * @return /
      */
     @GetMapping("stock/style-allocation")
-    public ResultVo<Map<String, Object>> getStockStyleAllocation(StockAllocationParams params) {
+    public ResultVo<Map<String, Object>> getStockStyleAllocation(StockAllocationReq params) {
         return ResultVo.ok(this.stock.getStyleAllocation(params));
     }
 
@@ -168,7 +172,7 @@ public class FundPositionApi {
      * @return /
      */
     @GetMapping("stock/liquidity-allocation")
-    public ResultVo<Map<String, Object>> getStockLiquidityAllocation(StockAllocationParams params) {
+    public ResultVo<Map<String, Object>> getStockLiquidityAllocation(StockAllocationReq params) {
         return ResultVo.ok(this.stock.getLiquidityAllocation(params));
     }
 
@@ -179,7 +183,7 @@ public class FundPositionApi {
      * @return /
      */
     @GetMapping("stock/performance-attribution")
-    public ResultVo<Map<String, Object>> getStockPerformanceAttribution(StockPerformanceAttributionParams params) {
+    public ResultVo<Map<String, Object>> getStockPerformanceAttribution(StockPerformanceAttributionReq params) {
         return ResultVo.ok(this.stock.getPerformanceAttribution(params));
     }
 
@@ -190,22 +194,11 @@ public class FundPositionApi {
      * @return /
      */
     @GetMapping("stock/barra-sensitivity")
-    public ResultVo<Map<String, Object>> getStockBarraSensitivity(BarraSensitivityParams params) {
+    public ResultVo<Map<String, Object>> getStockBarraSensitivity(BarraSensitivityReq params) {
         return ResultVo.ok(this.stock.getBarraSensitivity(params));
     }
 
     /**
-     * 私募,股票-股票风险敞口走势
-     *
-     * @param params /
-     * @return /
-     */
-    @GetMapping("stock/risk-exposure")
-    public ResultVo<Map<String, Object>> getStockRiskExposure(RiskExposureParams params) {
-        return ResultVo.ok(this.stock.getRiskExposure(params));
-    }
-
-    /**
      * 债券分类配置及明细  公募私募
      *
      * @param param /
@@ -312,7 +305,7 @@ public class FundPositionApi {
      * @return
      */
     @RequestMapping(value = "/fund-marginal-risk-contribution", method = RequestMethod.GET)
-    public ResultVo<Map<String, Object>> getFutureRiskCont(MarginalRiskContributionParams params) {
+    public ResultVo<Map<String, Object>> getFutureRiskCont(MarginalRiskContributionReq params) {
         return ResultVo.ok(this.future.riskCont(params));
     }
 

+ 0 - 15
src/main/java/com/smppw/analysis/domain/dto/position/stock/RiskExposureParams.java

@@ -1,15 +0,0 @@
-package com.smppw.analysis.domain.dto.position.stock;
-
-import com.smppw.analysis.domain.dto.position.BaseParams;
-import lombok.Getter;
-import lombok.Setter;
-
-/**
- * @author wangzaijun
- * @date 2023/6/6 14:53
- * @description 股票风险敞口走势 接口请求参数
- */
-@Setter
-@Getter
-public class RiskExposureParams extends BaseParams {
-}

+ 0 - 26
src/main/java/com/smppw/analysis/domain/dto/position/stock/RiskExposureVO.java

@@ -1,26 +0,0 @@
-package com.smppw.analysis.domain.dto.position.stock;
-
-import com.smppw.analysis.domain.dto.position.RefMarketValueRatio;
-import lombok.Getter;
-import lombok.Setter;
-
-import java.util.List;
-
-/**
- * @author wangzaijun
- * @date 2023/6/6 17:36
- * @description 股票风险敞口走势 接口返回结构
- */
-@Setter
-@Getter
-public class RiskExposureVO {
-    /**
-     * 估值日期
-     */
-    private String date;
-    /**
-     * 类型、市值和占比,包括风险敞口
-     * 风险敞口=股票多头+股指多头-股票空头-股指空头-ETF融券
-     */
-    private List<RefMarketValueRatio> mvr;
-}

+ 0 - 134
src/main/java/com/smppw/analysis/domain/manager/position/stock/RiskExposureBizHandler.java

@@ -1,134 +0,0 @@
-package com.smppw.analysis.domain.manager.position.stock;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.collection.ListUtil;
-import com.smppw.analysis.domain.dto.position.*;
-import com.smppw.analysis.domain.dto.position.stock.RiskExposureParams;
-import com.smppw.analysis.domain.dto.position.stock.RiskExposureVO;
-import com.smppw.analysis.domain.manager.position.AbstractNonSynthesizeBizHandler;
-import com.smppw.analysis.domain.manager.position.BizHandlerConstants;
-import com.smppw.analysis.domain.manager.position.PositionLoadFactory;
-import com.smppw.analysis.domain.gateway.CacheFactory;
-import com.smppw.analysis.infrastructure.config.AnalysisProperty;
-import com.smppw.analysis.infrastructure.exception.APIException;
-import com.smppw.constants.SecType;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import org.springframework.stereotype.Component;
-
-import java.math.BigDecimal;
-import java.math.RoundingMode;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
-
-/**
- * @author wangzaijun
- * @date 2023/6/13 8:49
- * @description 私募基金股票风险敞口走势
- */
-@Component(BizHandlerConstants.RISK_EXPOSURE)
-public class RiskExposureBizHandler extends AbstractNonSynthesizeBizHandler<RiskExposureParams, List<RiskExposureVO>> {
-    private static final List<RiskExposure> RISK_EXPOSURES = ListUtil.list(true);
-
-    static {
-        // 个股多头
-        RISK_EXPOSURES.add(new RiskExposure(RiskExposureEnum.STOCK_BULL, true,
-                e -> AssetCategoryEnum.STOCK.name().equals(e.getAsset().getValue())
-                        && e.getSharesNature() == 1 && e.getLevel() >= 4));
-        // 个股空头
-        RISK_EXPOSURES.add(new RiskExposure(RiskExposureEnum.STOCK_BEAR, false,
-                e -> AssetCategoryEnum.STOCK.name().equals(e.getAsset().getValue())
-                        && e.getSharesNature() == 2 && e.getLevel() >= 4));
-        // 股指多头
-        RISK_EXPOSURES.add(new RiskExposure(RiskExposureEnum.FUTURE_BULL, true,
-                e -> AssetCategoryEnum.FUTURE.name().equals(e.getAsset().getValue())
-                        && e.getSharesNature() == 1
-                        && e.getSubType() == 31
-                        && e.getLevel() >= 4));
-        // 股指空头
-        RISK_EXPOSURES.add(new RiskExposure(RiskExposureEnum.FUTURE_BEAR, false,
-                e -> AssetCategoryEnum.FUTURE.name().equals(e.getAsset().getValue())
-                        && e.getSharesNature() == 2
-                        && e.getSubType() == 31
-                        && e.getLevel() >= 4));
-        // ETF融券
-        RISK_EXPOSURES.add(new RiskExposure(RiskExposureEnum.ETF, false,
-                e -> e.getSubjectCode() != null && e.getSubjectCode().contains("2101")
-                        && e.getLevel() == 3
-                        && e.getRef() != null && e.getRef().getLabel() != null && e.getRef().getLabel().contains("ETF")));
-    }
-
-    public RiskExposureBizHandler(AnalysisProperty property, CacheFactory cacheFactory, PositionLoadFactory factory) {
-        super(property, cacheFactory, factory);
-    }
-
-    @Override
-    protected List<RiskExposureVO> afterNonSynthesizeLoadData(RiskExposureParams params, List<FundPositionBaseInfo> baseInfos, List<FundPositionDetail> positionInfos) {
-        if (CollUtil.isEmpty(positionInfos)) {
-            return ListUtil.empty();
-        }
-        List<String> types = ListUtil.of(SecType.PRIVATE_FUND, SecType.PRIVATELY_OFFERED_FUND);
-        String fundType = positionInfos.get(0).getFundType();
-        if (!types.contains(fundType)) {
-            throw new APIException("股票风险敞口接口仅支持私募基金和自建基金!");
-        }
-        List<RiskExposureVO> resultList = ListUtil.list(false);
-        // 按日期分组处理
-        Map<String, List<FundPositionDetail>> collect = positionInfos.stream().collect(Collectors.groupingBy(FundPositionDetail::getDate));
-        collect.forEach((k, v) -> {
-            BigDecimal total = baseInfos.stream().filter(e -> k.equals(e.getDate())).map(FundPositionBaseInfo::getAssetNv)
-                    .filter(Objects::nonNull).findFirst().map(BigDecimal::abs).orElse(null);
-            if (total != null && total.abs().compareTo(BigDecimal.ZERO) > 0) {
-                List<RefMarketValueRatio> mvrs = ListUtil.list(true);
-                BigDecimal exposureMv = BigDecimal.ZERO;
-                // 是否全部都null,
-                boolean allNullFlag = true;
-                for (RiskExposure riskExposure : RISK_EXPOSURES) {
-                    BigDecimal mv = v.stream().filter(riskExposure.getPredicate()).map(FundPositionDetail::getMarketValue)
-                            .filter(Objects::nonNull).reduce(BigDecimal::add).orElse(null);
-                    BigDecimal ratio = null;
-                    if (mv != null) {
-                        ratio = mv.divide(total, 4, RoundingMode.HALF_UP);
-                        exposureMv = riskExposure.operatePlus ? exposureMv.add(mv.abs()) : exposureMv.subtract(mv.abs());
-                        allNullFlag = false;
-                    }
-                    mvrs.add(new RefMarketValueRatio(RiskExposureEnum.getValueLabel(riskExposure.exposureEnum), mv, ratio));
-                }
-                // 敞口 市值不为null才添加到结果集中
-                if (!allNullFlag) {
-                    BigDecimal exposureRatio = exposureMv.divide(total, 4, RoundingMode.HALF_UP);
-                    mvrs.add(new RefMarketValueRatio(RiskExposureEnum.getValueLabel(RiskExposureEnum.EXPOSURE), null, exposureRatio));
-                    RiskExposureVO vo = new RiskExposureVO();
-                    vo.setDate(k);
-                    vo.setMvr(mvrs);
-                    resultList.add(vo);
-                }
-            }
-        });
-        if (CollUtil.isNotEmpty(resultList)) {
-            resultList.sort(Comparator.comparing(RiskExposureVO::getDate).reversed());
-        }
-        return resultList;
-    }
-
-    @Getter
-    @AllArgsConstructor
-    private static class RiskExposure {
-        /**
-         * 类型
-         */
-        private final RiskExposureEnum exposureEnum;
-        /**
-         * 是否加法
-         */
-        private final boolean operatePlus;
-        /**
-         * 数据过滤条件
-         */
-        private final Predicate<FundPositionDetail> predicate;
-    }
-}