Explorar o código

feat:基金的全部净值序列(周频)和不参与排名的基金也输出到榜单结果表

mozuwen hai 5 meses
pai
achega
858ad8db44

+ 1 - 1
service-base/src/main/java/com/simuwang/base/mapper/FundInfoMapper.java

@@ -53,6 +53,6 @@ public interface FundInfoMapper {
 
     List<FundInfoDO> queryFundInfoByFundId(@Param("fundIdList") List<String> fundIdList);
 
-    List<FundAndCompanyInfoDO> queryFundAndTrustByFundId(@Param("competitionId")Integer competitionId, @Param("fundIdList")List<String> fundIdList);
+    List<FundAndCompanyInfoDO> queryFundAndTrustByFundId(@Param("competitionId")Integer competitionId);
 
 }

+ 1 - 1
service-base/src/main/java/com/simuwang/base/mapper/NavMapper.java

@@ -31,5 +31,5 @@ public interface NavMapper {
 
     Long countNavTotal();
 
-    List<NavDO> queryAllNav(@Param("competitionId")Integer competitionId, @Param("startDate") String startDate,@Param("endDate") String endDate);
+    List<NavDO> queryAllNav(@Param("competitionId")Integer competitionId);
 }

+ 0 - 4
service-base/src/main/resources/mapper/FundInfoMapper.xml

@@ -250,10 +250,6 @@
         join rc_competition_apply t2 on t.fund_id = t2.product_code and t2.isvalid = 1
         where t.isvalid = 1
            and t2.competition_id = #{competitionId}
-           and t.fund_id in
-              <foreach collection="fundIdList" item="fundId" index="index" open="(" separator="," close=")">
-                 #{fundId}
-              </foreach>
     </select>
 
 </mapper>

+ 0 - 2
service-base/src/main/resources/mapper/NavMapper.xml

@@ -108,7 +108,5 @@
             join rc_competition_apply t2 on t1.fund_id = t2.product_code and t2.isvalid = 1
         where t1.isvalid = 1
           and t2.competition_id = #{competitionId}
-          and t1.price_date >= #{startDate}
-          and t1.price_date <![CDATA[ <= ]]> #{endDate}
     </select>
 </mapper>

+ 37 - 34
service-calc/src/main/java/com/simuwang/task/CompetitionIndicatorCalcTask.java

@@ -84,42 +84,45 @@ public class CompetitionIndicatorCalcTask {
         List<String> periodList = taskDateDOList.stream().map(RcCompetitionTaskDateDO::getPriod).distinct().toList();
         List<RcCompetitionCalcDateDO> calcDateDOList = competitionCalcDateMapper.queryByPriod(periodList, competitionId);
         for (RcCompetitionCalcDateDO calcDateDO : calcDateDOList) {
-            String beginDate = calcDateDO.getBeginDate();
-            String endDate = calcDateDO.getEndDate();
-            // 基金净值数据
-            List<NavDO> navDOList = getSevNav(competitionId, beginDate, endDate);
-            if (CollUtil.isEmpty(navDOList)) {
-                continue;
-            }
-            List<String> fundIdList = navDOList.stream().map(NavDO::getFundId).filter(StrUtil::isNotBlank).distinct().toList();
-            Map<String, List<DateValue>> allNavMap = getSecNavMap(navDOList);
-            // 基金-基准映射关系
-            List<FundInfoDO> fundInfoDOList = fundInfoMapper.queryFundInfoByFundId(fundIdList);
-            Map<String, String> secBenchmarkIdMap = fundInfoDOList.stream().collect(Collectors.toMap(FundInfoDO::getFundId, FundInfoDO::getPrimaryBenchmarkId));
-            // 基准净值数据
-            List<String> indexIdList = fundInfoDOList.stream().map(FundInfoDO::getPrimaryBenchmarkId).distinct().toList();
-            Map<String, List<DateValue>> benchmarkIdNavMap = getBenchmarkNavMap(indexIdList, beginDate, endDate);
-            allNavMap.putAll(benchmarkIdNavMap);
-            Map<String, Frequency> secFreqMap = fundIdList.stream().collect(Collectors.toMap(k -> k, v -> Frequency.Weekly));
-            CalcMultipleSecMultipleTimeRangeIndicatorReq req = prepareIndicatorReq(fundIdList, secBenchmarkIdMap, indexIdList, beginDate, endDate);
+            calculateIndicator(competitionId, calcDateDO);
+        }
+    }
 
-            // 计算指标
-            IndicatorService indicatorService = IndicatorService.getInstance();
-            Map<String, List<IndicatorCalcPropertyDto>> secMultipleTimeRangeIndicator = indicatorService.calcMultipleSecMultipleTimeRangeIndicator(req, allNavMap, secFreqMap);
-            if (MapUtil.isEmpty(secMultipleTimeRangeIndicator)) {
-                continue;
-            }
-            // 资产规模
-            Map<String, BigDecimal> fundIdAssetMap = getFundAsset(fundIdList, beginDate, endDate, calcDateDO.getEndMonth());
-            // 绘制到指标结果表:fund_indicator
-            List<FundIndicatorDO> fundIndicatorDOList = convertToFundIndicatorDo(competitionId, calcDateDO, fundIdAssetMap, secMultipleTimeRangeIndicator);
-            if (CollUtil.isNotEmpty(fundIndicatorDOList)) {
-                fundIndicatorMapper.batchInsertOrUpdate(fundIndicatorDOList);
-            }
+    public void calculateIndicator(Integer competitionId, RcCompetitionCalcDateDO calcDateDO) {
+        String beginDate = calcDateDO.getBeginDate();
+        String endDate = calcDateDO.getEndDate();
+        // 基金净值数据
+        List<NavDO> navDOList = getSevNav(competitionId, beginDate, endDate);
+        if (CollUtil.isEmpty(navDOList)) {
+            return;
+        }
+        List<String> fundIdList = navDOList.stream().map(NavDO::getFundId).filter(StrUtil::isNotBlank).distinct().toList();
+        Map<String, List<DateValue>> allNavMap = getSecNavMap(navDOList);
+        // 基金-基准映射关系
+        List<FundInfoDO> fundInfoDOList = fundInfoMapper.queryFundInfoByFundId(fundIdList);
+        Map<String, String> secBenchmarkIdMap = fundInfoDOList.stream().collect(Collectors.toMap(FundInfoDO::getFundId, FundInfoDO::getPrimaryBenchmarkId));
+        // 基准净值数据
+        List<String> indexIdList = fundInfoDOList.stream().map(FundInfoDO::getPrimaryBenchmarkId).distinct().toList();
+        Map<String, List<DateValue>> benchmarkIdNavMap = getBenchmarkNavMap(indexIdList, beginDate, endDate);
+        allNavMap.putAll(benchmarkIdNavMap);
+        Map<String, Frequency> secFreqMap = fundIdList.stream().collect(Collectors.toMap(k -> k, v -> Frequency.Weekly));
+        CalcMultipleSecMultipleTimeRangeIndicatorReq req = prepareIndicatorReq(fundIdList, secBenchmarkIdMap, indexIdList, beginDate, endDate);
 
-            // 发布计算排名事件
-            calcFundRankPublisher.publishEvent(new CalcFundRankEventDO(competitionId, calcDateDO.getPriod(), allNavMap));
+        // 计算指标
+        IndicatorService indicatorService = IndicatorService.getInstance();
+        Map<String, List<IndicatorCalcPropertyDto>> secMultipleTimeRangeIndicator = indicatorService.calcMultipleSecMultipleTimeRangeIndicator(req, allNavMap, secFreqMap);
+        if (MapUtil.isEmpty(secMultipleTimeRangeIndicator)) {
+            return;
+        }
+        // 资产规模
+        Map<String, BigDecimal> fundIdAssetMap = getFundAsset(fundIdList, beginDate, endDate, calcDateDO.getEndMonth());
+        // 绘制到指标结果表:fund_indicator
+        List<FundIndicatorDO> fundIndicatorDOList = convertToFundIndicatorDo(competitionId, calcDateDO, fundIdAssetMap, secMultipleTimeRangeIndicator);
+        if (CollUtil.isNotEmpty(fundIndicatorDOList)) {
+            fundIndicatorMapper.batchInsertOrUpdate(fundIndicatorDOList);
         }
+        // 发布计算排名事件
+        calcFundRankPublisher.publishEvent(new CalcFundRankEventDO(competitionId, calcDateDO.getPriod(), allNavMap));
     }
 
     private List<FundIndicatorDO> convertToFundIndicatorDo(Integer competitionId, RcCompetitionCalcDateDO calcDateDO, Map<String, BigDecimal> fundIdAssetMap,
@@ -328,7 +331,7 @@ public class CompetitionIndicatorCalcTask {
     }
 
     private List<NavDO> getSevNav(Integer competitionId, String beginDate, String endDate) {
-        List<NavDO> navDOList = navMapper.queryAllNav(competitionId, beginDate, endDate);
+        List<NavDO> navDOList = navMapper.queryAllNav(competitionId);
         // 过滤掉净值缺失的基金
         List<FundDeletionInfoDO> fundNavDeletionList = deletionInfoMapper.getFundNavDeletion(1, competitionId, beginDate, endDate);
         if (CollUtil.isNotEmpty(fundNavDeletionList)) {

+ 4 - 0
service-manage/pom.xml

@@ -23,6 +23,10 @@
             <groupId>com.simuwang</groupId>
             <artifactId>service-daq</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.simuwang</groupId>
+            <artifactId>service-calc</artifactId>
+        </dependency>
     </dependencies>
 
 <!--    <build>-->

+ 11 - 6
service-manage/src/main/java/com/simuwang/manage/service/competition/CalcFundRankService.java

@@ -74,8 +74,7 @@ public class CalcFundRankService {
     private void saveCompetitionResult(Integer competitionId, String period, List<FundIndicatorDO> fundIndicatorList, List<FundScoreRankDTO> fundScoreRankDTOList,
                                        List<RcCompetitionApplyDO> competitionApplyDOList, Map<String, List<DateValue>> fundIdNavMap) {
         // 基金信息和机构信息
-        List<String> fundIdList = competitionApplyDOList.stream().map(RcCompetitionApplyDO::getFundId).toList();
-        List<FundAndCompanyInfoDO> fundCompanyInfoDOList = fundInfoMapper.queryFundAndTrustByFundId(competitionId, fundIdList);
+        List<FundAndCompanyInfoDO> fundCompanyInfoDOList = fundInfoMapper.queryFundAndTrustByFundId(competitionId);
         Map<String, FundAndCompanyInfoDO> fundIdInfoMap = fundCompanyInfoDOList.stream().collect(Collectors.toMap(FundAndCompanyInfoDO::getFundId, v -> v));
         // 基金的期初期末净值信息
         Map<String, FundInitAndEndNavDTO> fundIdInitAndEndNavMap = getFundInitAndEndNav(fundIdNavMap);
@@ -171,13 +170,12 @@ public class CalcFundRankService {
     private List<RcCompetitionResultDO> convertToCompetitionResultDO(Integer competitionId, String period, Map<String, FundIndicatorDO> fundIdIndicatorMap, Map<String, FundAndCompanyInfoDO> fundIdInfoMap,
                                                                      Map<String, FundInitAndEndNavDTO> fundIdInitAndEndNavMap, Map<String, FundScoreRankDTO> fundIdScoreRankMap) {
         List<RcCompetitionResultDO> competitionResultDOList = CollUtil.newArrayList();
-        for (Map.Entry<String, FundIndicatorDO> fundIdIndicatorEntry : fundIdIndicatorMap.entrySet()) {
-            String fundId = fundIdIndicatorEntry.getKey();
-            FundIndicatorDO fundIndicatorDO = fundIdIndicatorEntry.getValue();
+        for (Map.Entry<String, FundAndCompanyInfoDO> fundCompanyInfoEntry : fundIdInfoMap.entrySet()) {
+            String fundId = fundCompanyInfoEntry.getKey();
             RcCompetitionResultDO resultDO = new RcCompetitionResultDO();
             resultDO.setCompetitionId(competitionId);
             resultDO.setPriod(period);
-            FundAndCompanyInfoDO fundAndCompanyInfoDO = fundIdInfoMap.get(fundId);
+            FundAndCompanyInfoDO fundAndCompanyInfoDO = fundCompanyInfoEntry.getValue();
             resultDO.setFundId(fundId);
             resultDO.setStrategy(fundAndCompanyInfoDO.getStrategyId());
             resultDO.setFundRegisterNumber(fundAndCompanyInfoDO.getRegisterNumber());
@@ -195,6 +193,9 @@ public class CalcFundRankService {
             if (fundScoreRankDTO != null) {
                 resultDO.setRank(fundScoreRankDTO.getRank());
                 resultDO.setScore(fundScoreRankDTO.getScore());
+            } else {
+                resultDO.setRank(999999);
+                resultDO.setScore(null);
             }
             FundInitAndEndNavDTO initAndEndNavDTO = fundIdInitAndEndNavMap.get(fundId);
             if (initAndEndNavDTO != null) {
@@ -203,6 +204,7 @@ public class CalcFundRankService {
                 resultDO.setPriceDate(StrUtil.isNotBlank(initAndEndNavDTO.getEndDate()) ? DateUtil.parse(initAndEndNavDTO.getEndDate(), DateConst.YYYY_MM_DD) : null);
                 resultDO.setCumulativeNavWithdrawal(initAndEndNavDTO.getEndCumulativeNavWithdrawal());
             }
+            FundIndicatorDO fundIndicatorDO = fundIdIndicatorMap.get(fundId);
             if (fundIndicatorDO != null) {
                 resultDO.setRet(fundIndicatorDO.getRet());
                 resultDO.setRetA(fundIndicatorDO.getRetA());
@@ -220,6 +222,9 @@ public class CalcFundRankService {
                 resultDO.setExcessSharperatio(fundIndicatorDO.getExcessSharperatio());
                 resultDO.setExcessStddev(fundIndicatorDO.getExcessStddev());
                 resultDO.setProductScale(fundIndicatorDO.getProductScale());
+            } else {
+                resultDO.setRank(999999);
+                resultDO.setScore(null);
             }
             resultDO.setIsvalid(1);
             resultDO.setCreateTime(new Date());

+ 6 - 5
service-manage/src/main/java/com/simuwang/manage/service/competition/FundNavService.java

@@ -48,18 +48,19 @@ public class FundNavService {
     }
 
 
-    public List<FundNavDataDTO> getFungNavData(Integer competitionId, String startDate, String endDate) {
+    public List<FundNavDataDTO> getFungNavData(Integer competitionId) {
         List<FundNavDataDTO> navDataDTOList = CollUtil.newArrayList();
-        List<NavDO> navDOList = navMapper.queryAllNav(competitionId, startDate, endDate);
+        List<NavDO> navDOList = navMapper.queryAllNav(competitionId);
         if (CollUtil.isEmpty(navDOList)) {
             return navDataDTOList;
         }
         // 过滤出周频的净值点
-        List<TradeDateDO> tradeDateDOList = tradeDateMapper.selectTradeDate(startDate, endDate);
+        String toDay = DateUtil.format(new Date(),DateConst.YYYY_MM_DD);
+        List<TradeDateDO> tradeDateDOList = tradeDateMapper.listAllTradeDate(toDay);
         navDOList = NavDataUtil.filterWeekFrequencyNav(navDOList, tradeDateDOList);
 
         List<String> fundIdList = navDOList.stream().map(NavDO::getFundId).distinct().toList();
-        List<FundAndCompanyInfoDO> fundInfoCompanyNameList = fundInfoMapper.queryFundAndTrustByFundId(competitionId, fundIdList);
+        List<FundAndCompanyInfoDO> fundInfoCompanyNameList = fundInfoMapper.queryFundAndTrustByFundId(competitionId);
         Map<String, FundAndCompanyInfoDO> fundIdCompanyNameMap = fundInfoCompanyNameList.stream().collect(Collectors.toMap(FundAndCompanyInfoDO::getFundId, v -> v));
         List<AssetDO> assetDOList = assetMapper.queryAssetByFundId(fundIdList);
         Map<String, List<AssetDO>> fundIdAssetMap = MapUtil.newHashMap();
@@ -86,7 +87,7 @@ public class FundNavService {
             return navDeletionDTOList;
         }
         List<String> fundIdList = deletionInfoDOList.stream().map(FundDeletionInfoDO::getFundId).distinct().toList();
-        List<FundAndCompanyInfoDO> fundInfoCompanyNameList = fundInfoMapper.queryFundAndTrustByFundId(competitionId, fundIdList);
+        List<FundAndCompanyInfoDO> fundInfoCompanyNameList = fundInfoMapper.queryFundAndTrustByFundId(competitionId);
         Map<String, FundAndCompanyInfoDO> fundIdCompanyNameMap = fundInfoCompanyNameList.stream().collect(Collectors.toMap(FundAndCompanyInfoDO::getFundId, v -> v));
         // 获取净值日期所在年和所在周
         List<String> dateList = deletionInfoDOList.stream().map(FundDeletionInfoDO::getDeletionDate).distinct().toList();

+ 16 - 7
service-manage/src/main/java/com/simuwang/manage/task/CompetitionTask.java

@@ -18,6 +18,7 @@ import com.simuwang.base.pojo.dto.MailboxInfoDTO;
 import com.simuwang.base.pojo.dto.competition.CompetitionBaseResultDTO;
 import com.simuwang.manage.service.EmailSystemConfigService;
 import com.simuwang.manage.service.competition.FundNavService;
+import com.simuwang.task.CompetitionIndicatorCalcTask;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.scheduling.annotation.Scheduled;
@@ -39,15 +40,19 @@ public class CompetitionTask {
     private final EmailSystemConfigService emailSystemConfigService;
     private final RcCompetitionTaskDateMapper competitionTaskDateMapper;
     private final RcCompetitionCalcDateMapper competitionCalcDateMapper;
+    private final FundDeletionTask fundDeletionTask;
+    private final CompetitionIndicatorCalcTask competitionIndicatorCalcTask;
 
     public CompetitionTask(FundNavService fundNavService, CompetitionConfig competitionConfig,
                            EmailSystemConfigService emailSystemConfigService, RcCompetitionTaskDateMapper competitionTaskDateMapper,
-                           RcCompetitionCalcDateMapper competitionCalcDateMapper) {
+                           RcCompetitionCalcDateMapper competitionCalcDateMapper, FundDeletionTask fundDeletionTask, CompetitionIndicatorCalcTask competitionIndicatorCalcTask) {
         this.fundNavService = fundNavService;
         this.competitionConfig = competitionConfig;
         this.emailSystemConfigService = emailSystemConfigService;
         this.competitionTaskDateMapper = competitionTaskDateMapper;
         this.competitionCalcDateMapper = competitionCalcDateMapper;
+        this.fundDeletionTask = fundDeletionTask;
+        this.competitionIndicatorCalcTask = competitionIndicatorCalcTask;
     }
 
     /**
@@ -62,14 +67,9 @@ public class CompetitionTask {
         if (CollUtil.isEmpty(taskDateDOList)) {
             return;
         }
-        List<String> periodList = taskDateDOList.stream().map(RcCompetitionTaskDateDO::getPriod).distinct().toList();
-        List<RcCompetitionCalcDateDO> calcDateDOList = competitionCalcDateMapper.queryByPriod(periodList, competitionId);
-        Map<String, RcCompetitionCalcDateDO> periodCalcDataDoMap = calcDateDOList.stream().collect(Collectors.toMap(RcCompetitionCalcDateDO::getPriod, v -> v));
-
         for (RcCompetitionTaskDateDO taskDateDO : taskDateDOList) {
             String period = taskDateDO.getPriod();
-            RcCompetitionCalcDateDO calcDateDO = periodCalcDataDoMap.get(period);
-            List<FundNavDataDTO> navDataDTOList = fundNavService.getFungNavData(competitionId, calcDateDO.getBeginDate(), calcDateDO.getEndDate());
+            List<FundNavDataDTO> navDataDTOList = fundNavService.getFungNavData(competitionId);
             if (CollUtil.isEmpty(navDataDTOList)) {
                 return;
             }
@@ -151,8 +151,17 @@ public class CompetitionTask {
         if (CollUtil.isEmpty(taskDateDOList)) {
             return;
         }
+        // 输出榜单之前 -> 执行净值缺失检测(确保净值不全的基金不参与榜单)
+        fundDeletionTask.computeDeletion();
+        List<String> periodList = taskDateDOList.stream().map(RcCompetitionTaskDateDO::getPriod).distinct().collect(Collectors.toList());
+        List<RcCompetitionCalcDateDO> calcDateDOList = competitionCalcDateMapper.queryByPriod(periodList, competitionId);
+        Map<String, RcCompetitionCalcDateDO> periodCalcDataDoMap = calcDateDOList.stream().collect(Collectors.toMap(RcCompetitionCalcDateDO::getPriod, v -> v));
         for (RcCompetitionTaskDateDO taskDateDO : taskDateDOList) {
             String period = taskDateDO.getPriod();
+            RcCompetitionCalcDateDO calcDateDO = periodCalcDataDoMap.get(period);
+            // 输出榜单之前 -> 执行基金净值指标计算
+            competitionIndicatorCalcTask.calculateIndicator(competitionId, calcDateDO);
+
             List<? extends CompetitionBaseResultDTO> competitionResultDTOList = fundNavService.getCompetitionResult(competitionId, period);
             if (CollUtil.isEmpty(competitionResultDTOList)) {
                 return;