FundNavService.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. package com.simuwang.manage.service.competition;
  2. import cn.hutool.core.collection.CollUtil;
  3. import cn.hutool.core.date.DateUtil;
  4. import cn.hutool.core.map.MapUtil;
  5. import com.simuwang.base.common.conts.DateConst;
  6. import com.simuwang.base.common.util.NavDataUtil;
  7. import com.simuwang.base.mapper.*;
  8. import com.simuwang.base.pojo.dos.*;
  9. import com.simuwang.base.pojo.dto.FundNavDataDTO;
  10. import com.simuwang.base.pojo.dto.FundNavDeletionDTO;
  11. import com.simuwang.base.pojo.dto.TradeDateDTO;
  12. import com.simuwang.base.pojo.dto.competition.CompetitionBaseResultDTO;
  13. import org.springframework.stereotype.Service;
  14. import java.math.BigDecimal;
  15. import java.math.RoundingMode;
  16. import java.util.Comparator;
  17. import java.util.Date;
  18. import java.util.List;
  19. import java.util.Map;
  20. import java.util.stream.Collectors;
  21. @Service
  22. public class FundNavService {
  23. private final NavMapper navMapper;
  24. private final FundInfoMapper fundInfoMapper;
  25. private final AssetMapper assetMapper;
  26. private final DeletionInfoMapper deletionInfoMapper;
  27. private final TradeDateMapper tradeDateMapper;
  28. private final CompetitionFactory competitionFactory;
  29. public FundNavService(NavMapper navMapper, FundInfoMapper fundInfoMapper,
  30. AssetMapper assetMapper, DeletionInfoMapper deletionInfoMapper,
  31. TradeDateMapper tradeDateMapper, CompetitionFactory competitionFactory) {
  32. this.navMapper = navMapper;
  33. this.fundInfoMapper = fundInfoMapper;
  34. this.assetMapper = assetMapper;
  35. this.deletionInfoMapper = deletionInfoMapper;
  36. this.tradeDateMapper = tradeDateMapper;
  37. this.competitionFactory = competitionFactory;
  38. }
  39. public List<FundNavDataDTO> getFungNavData(Integer competitionId) {
  40. List<FundNavDataDTO> navDataDTOList = CollUtil.newArrayList();
  41. List<NavDO> navDOList = navMapper.queryAllNav(competitionId);
  42. if (CollUtil.isEmpty(navDOList)) {
  43. return navDataDTOList;
  44. }
  45. // 过滤出周频的净值点
  46. String toDay = DateUtil.format(new Date(), DateConst.YYYY_MM_DD);
  47. List<TradeDateDO> tradeDateDOList = tradeDateMapper.listAllTradeDate(toDay);
  48. navDOList = NavDataUtil.filterWeekFrequencyNav(navDOList, tradeDateDOList);
  49. List<String> fundIdList = navDOList.stream().map(NavDO::getFundId).distinct().toList();
  50. List<FundAndCompanyInfoDO> fundInfoCompanyNameList = fundInfoMapper.queryFundAndTrustByFundId(competitionId);
  51. Map<String, FundAndCompanyInfoDO> fundIdCompanyNameMap = fundInfoCompanyNameList.stream().collect(Collectors.toMap(FundAndCompanyInfoDO::getFundId, v -> v));
  52. List<AssetDO> assetDOList = assetMapper.queryAssetByFundId(fundIdList);
  53. Map<String, List<AssetDO>> fundIdAssetMap = MapUtil.newHashMap();
  54. if (CollUtil.isNotEmpty(assetDOList)) {
  55. fundIdAssetMap = assetDOList.stream().collect(Collectors.groupingBy(AssetDO::getFundId));
  56. }
  57. Map<String, List<NavDO>> fundIdNavMap = navDOList.stream().collect(Collectors.groupingBy(NavDO::getFundId));
  58. for (Map.Entry<String, List<NavDO>> fundIdNavEntry : fundIdNavMap.entrySet()) {
  59. String fundId = fundIdNavEntry.getKey();
  60. List<NavDO> fundNavDoList = fundIdNavEntry.getValue();
  61. List<AssetDO> fundAssetDoList = fundIdAssetMap.get(fundId);
  62. FundAndCompanyInfoDO fundInfoDO = fundIdCompanyNameMap.get(fundId);
  63. List<FundNavDataDTO> fundNavDataDTOList = buildFundNavDataDTO(fundInfoDO, fundNavDoList, fundAssetDoList);
  64. navDataDTOList.addAll(fundNavDataDTOList);
  65. }
  66. return navDataDTOList;
  67. }
  68. public List<FundNavDeletionDTO> getFundNavDeletion(Integer competitionId, String startDate, String endDate) {
  69. List<FundNavDeletionDTO> navDeletionDTOList = CollUtil.newArrayList();
  70. // 缺失类型-1对应全部,1-净值缺失,2-对应规模缺失,3-对应分红缺失,5-估值缺失
  71. List<FundDeletionInfoDO> deletionInfoDOList = deletionInfoMapper.getFundNavDeletion(1, competitionId, startDate, endDate);
  72. if (CollUtil.isEmpty(deletionInfoDOList)) {
  73. return navDeletionDTOList;
  74. }
  75. List<FundAndCompanyInfoDO> fundInfoCompanyNameList = fundInfoMapper.queryFundAndTrustByFundId(competitionId);
  76. Map<String, FundAndCompanyInfoDO> fundIdCompanyNameMap = fundInfoCompanyNameList.stream().collect(Collectors.toMap(FundAndCompanyInfoDO::getFundId, v -> v));
  77. // 获取净值日期所在年和所在周
  78. List<String> dateList = deletionInfoDOList.stream().map(FundDeletionInfoDO::getDeletionDate).distinct().toList();
  79. Map<String, TradeDateDTO> tradeDateDoMap = getYearAndWeekOfDate(startDate, endDate, dateList);
  80. Map<String, List<FundDeletionInfoDO>> fundIdDeletionInfoMap = deletionInfoDOList.stream().collect(Collectors.groupingBy(FundDeletionInfoDO::getFundId));
  81. for (Map.Entry<String, List<FundDeletionInfoDO>> fundIdDeletionInfoEntry : fundIdDeletionInfoMap.entrySet()) {
  82. String fundId = fundIdDeletionInfoEntry.getKey();
  83. List<FundDeletionInfoDO> fundDeletionInfoDOList = fundIdDeletionInfoEntry.getValue();
  84. FundAndCompanyInfoDO fundAndCompanyInfoDO = fundIdCompanyNameMap.get(fundId);
  85. List<FundNavDeletionDTO> fundNavDataDTOList = buildFundNavDeletionDTO(fundAndCompanyInfoDO, fundDeletionInfoDOList, tradeDateDoMap);
  86. navDeletionDTOList.addAll(fundNavDataDTOList);
  87. }
  88. return navDeletionDTOList;
  89. }
  90. public List<? extends CompetitionBaseResultDTO> getCompetitionResult(Integer competitionId, String period) {
  91. List<? extends CompetitionBaseResultDTO> dataList = CollUtil.newArrayList();
  92. AbstractCompetitionResultService competitionResult = competitionFactory.getInstance(competitionId);
  93. if (competitionResult == null) {
  94. return dataList;
  95. }
  96. return competitionResult.getCompetitionResult(competitionId, period);
  97. }
  98. private List<FundNavDeletionDTO> buildFundNavDeletionDTO(FundAndCompanyInfoDO fundAndCompanyInfoDO, List<FundDeletionInfoDO> fundDeletionInfoDOList, Map<String, TradeDateDTO> tradeDateDoMap) {
  99. String fundName = fundAndCompanyInfoDO.getFundName();
  100. String trustName = fundAndCompanyInfoDO.getCompanyName();
  101. String trustRegisterNumber = fundAndCompanyInfoDO.getCompanyRegisterNumber();
  102. String registerNumber = fundAndCompanyInfoDO.getRegisterNumber();
  103. return fundDeletionInfoDOList.stream().map(e -> {
  104. FundNavDeletionDTO fundNavDeletionDTO = new FundNavDeletionDTO();
  105. fundNavDeletionDTO.setTrustName(trustName);
  106. fundNavDeletionDTO.setTrustRegisterNumber(trustRegisterNumber);
  107. fundNavDeletionDTO.setFundId(e.getFundId());
  108. fundNavDeletionDTO.setFundName(fundName);
  109. fundNavDeletionDTO.setRegisterNumber(registerNumber);
  110. TradeDateDTO tradeDateDTO = tradeDateDoMap.get(e.getDeletionDate());
  111. fundNavDeletionDTO.setYear(tradeDateDTO != null ? tradeDateDTO.getYear() + tradeDateDTO.getWeek() : null);
  112. fundNavDeletionDTO.setWeek(tradeDateDTO != null ? String.valueOf(tradeDateDTO.getWeek()) : null);
  113. // 第1周(2022-12-26至2022-12-30)
  114. String date = "第" + tradeDateDTO.getCompetitionWeek() + "周(" + tradeDateDTO.getFirstDate() + "至" + tradeDateDTO.getLastDate() + ")";
  115. fundNavDeletionDTO.setCompetitionDate(date);
  116. fundNavDeletionDTO.setDate(e.getDeletionDate());
  117. return fundNavDeletionDTO;
  118. }).sorted(Comparator.comparing(FundNavDeletionDTO::getFundName).thenComparing(FundNavDeletionDTO::getWeek)).toList();
  119. }
  120. private List<FundNavDataDTO> buildFundNavDataDTO(FundAndCompanyInfoDO fundInfoDO, List<NavDO> fundNavDoList, List<AssetDO> fundAssetDoList) {
  121. String fundName = fundInfoDO.getFundName();
  122. String registerNumber = fundInfoDO.getRegisterNumber();
  123. String trustName = fundInfoDO.getCompanyName();
  124. String trustRegisterNumber = fundInfoDO.getCompanyRegisterNumber();
  125. Map<String, BigDecimal> priceDateAssetMap = MapUtil.newHashMap();
  126. if (CollUtil.isNotEmpty(fundAssetDoList)) {
  127. priceDateAssetMap = fundAssetDoList.stream().collect(Collectors.toMap(k -> DateUtil.format(k.getPriceDate(), DateConst.YYYY_MM_DD), AssetDO::getAssetNet));
  128. }
  129. Map<String, BigDecimal> finalPriceDateAssetMap = priceDateAssetMap;
  130. return fundNavDoList.stream().map(e -> {
  131. FundNavDataDTO fundNavDataDTO = new FundNavDataDTO();
  132. fundNavDataDTO.setTrustName(trustName);
  133. fundNavDataDTO.setTrustRegisterNumber(trustRegisterNumber);
  134. fundNavDataDTO.setFundId(e.getFundId());
  135. fundNavDataDTO.setFundName(fundName);
  136. fundNavDataDTO.setRegisterNumber(registerNumber);
  137. String priceDate = e.getPriceDate() != null ? DateUtil.format(e.getPriceDate(), DateConst.YYYY_MM_DD) : null;
  138. fundNavDataDTO.setPriceDate(priceDate);
  139. fundNavDataDTO.setNav(e.getNav() != null ? String.valueOf(e.getNav()) : null);
  140. fundNavDataDTO.setCumulativeNavWithdrawal(e.getCumulativeNavWithdrawal() != null ? String.valueOf(e.getCumulativeNavWithdrawal()) : null);
  141. BigDecimal asset = finalPriceDateAssetMap.get(priceDate) != null ? finalPriceDateAssetMap.get(priceDate).setScale(2, RoundingMode.HALF_UP) : null;
  142. fundNavDataDTO.setAsset(asset != null ? String.valueOf(asset) : null);
  143. return fundNavDataDTO;
  144. }).sorted(Comparator.comparing(FundNavDataDTO::getFundName).thenComparing(FundNavDataDTO::getPriceDate)).toList();
  145. }
  146. private Map<String, TradeDateDTO> getYearAndWeekOfDate(String startDate, String endDate, List<String> dateList) {
  147. Map<String, TradeDateDTO> tradeDateDoMap = MapUtil.newHashMap();
  148. List<TradeDateDO> tradeDateDOList = tradeDateMapper.selectTradeDate(startDate, endDate);
  149. if (CollUtil.isEmpty(tradeDateDOList)) {
  150. return tradeDateDoMap;
  151. }
  152. List<Integer> yearWeekList = tradeDateDOList.stream().map(e -> e.getYearWeek()).distinct().toList();
  153. Map<String, TradeDateDO> dateMap = tradeDateDOList.stream().collect(Collectors.toMap(k -> DateUtil.format(k.getTradeDate(), DateConst.YYYY_MM_DD), v -> v));
  154. Map<Integer, List<TradeDateDO>> yearWeekDateMap = tradeDateDOList.stream().collect(Collectors.groupingBy(TradeDateDO::getYearWeek));
  155. for (String date : dateList) {
  156. TradeDateDO tradeDateDO = dateMap.get(date);
  157. Integer yearWeek = tradeDateDO.getYearWeek();
  158. TradeDateDTO tradeDateDTO = new TradeDateDTO();
  159. tradeDateDTO.setWeek(tradeDateDO.getWeekOfYear());
  160. tradeDateDTO.setYear(tradeDateDO.getEndYear());
  161. String firstDate = yearWeekDateMap.get(yearWeek).stream()
  162. .min(Comparator.comparing(TradeDateDO::getTradeDate)).map(e -> DateUtil.format(e.getTradeDate(), DateConst.YYYY_MM_DD)).orElse(null);
  163. tradeDateDTO.setFirstDate(firstDate);
  164. tradeDateDTO.setLastDate(date);
  165. int competitionWeek = (int) yearWeekList.stream().filter(e -> e.compareTo(yearWeek) < 0).count() + 1;
  166. tradeDateDTO.setCompetitionWeek(competitionWeek);
  167. tradeDateDoMap.put(date, tradeDateDTO);
  168. }
  169. return tradeDateDoMap;
  170. }
  171. }