1
0

FundDeletionTask.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. package com.simuwang.manage.task;
  2. import cn.hutool.core.date.DateUtil;
  3. import com.simuwang.base.common.enums.DeletionType;
  4. import com.simuwang.base.common.enums.DistributeType;
  5. import com.simuwang.base.common.enums.Frequency;
  6. import com.simuwang.base.common.util.DateUtils;
  7. import com.simuwang.base.common.util.StringUtil;
  8. import com.simuwang.base.mapper.*;
  9. import com.simuwang.base.pojo.dos.*;
  10. import org.springframework.beans.factory.annotation.Autowired;
  11. import org.springframework.scheduling.annotation.EnableScheduling;
  12. import org.springframework.scheduling.annotation.Scheduled;
  13. import org.springframework.stereotype.Component;
  14. import java.util.*;
  15. import java.util.stream.Collectors;
  16. /**
  17. * FileName: FundDeletionTask
  18. * Author: chenjianhua
  19. * Date: 2024/9/18 22:43
  20. * Description: ${DESCRIPTION}
  21. */
  22. @EnableScheduling
  23. @Component
  24. public class FundDeletionTask {
  25. @Autowired
  26. private NavMapper navMapper;
  27. @Autowired
  28. private AssetMapper assetMapper;
  29. @Autowired
  30. private FundInfoMapper fundInfoMapper;
  31. @Autowired
  32. private FundReportFrequencyMapper fundReportFrequencyMapper;
  33. @Autowired
  34. private TradeDateMapper tradeDateMapper;
  35. @Autowired
  36. private DeletionInfoMapper deletionInfoMapper;
  37. @Autowired
  38. private DistributionMapper distributionMapper;
  39. @Scheduled(cron = "0 0 5,12,20 * * ?")
  40. public void computeDeletion(){
  41. List<String> fundIdList = navMapper.getAllFundId();
  42. for(String fundId : fundIdList){
  43. String inceptionDate = fundInfoMapper.getInceptionDateByFundId(fundId);
  44. if(inceptionDate == null){
  45. continue;
  46. }
  47. String today = DateUtils.getAroundToday(0);
  48. //获取基金对应的净值报送频率
  49. FundReportFrequencyDO fundReportFrequencyDO = fundReportFrequencyMapper.getFrequencyByFundId(fundId);
  50. if(StringUtil.isNull(fundReportFrequencyDO)){
  51. continue;
  52. }
  53. List<NavDO> navDOList = navMapper.selectNavByFundId(fundId);
  54. List<AssetDO> assetDOList = assetMapper.selectAssetByFundId(fundId);
  55. //查询成立日到今天为止的交易日集合
  56. List<TradeDateDO> tradeDateDOList = tradeDateMapper.selectTradeDate(inceptionDate,today);
  57. navDeletion(fundId,navDOList,tradeDateDOList,fundReportFrequencyDO);
  58. assetDeletion(fundId,assetDOList,tradeDateDOList,fundReportFrequencyDO);
  59. distributionDeletion(fundId,navDOList);
  60. }
  61. }
  62. private void distributionDeletion(String fundId, List<NavDO> navDOList) {
  63. //查询是否存在拆分
  64. List<DistributionDO> distributionDOS = distributionMapper.getDistributionByFundId(fundId, DistributeType.DIVIDENDS_SPLIT);
  65. if(distributionDOS.size() > 0){
  66. //存在拆分,不做分红缺失计算,同时吧以往的数据置为无效
  67. }
  68. }
  69. private void assetDeletion(String fundId, List<AssetDO> assetDOList, List<TradeDateDO> tradeDateDOList, FundReportFrequencyDO fundReportFrequencyDO) {
  70. if(Frequency.DAY == Frequency.getFrequencyByCode(fundReportFrequencyDO.getAssetFrequency())){
  71. Map<String,List<AssetDO>> navListMap = assetDOList.stream().collect(Collectors.groupingBy(e -> DateUtils.format(e.getPriceDate(),DateUtils.YYYY_MM_DD)));
  72. Map<String,List<TradeDateDO>> tradeListMap = tradeDateDOList.stream().collect(Collectors.groupingBy(e -> DateUtils.format(e.getTradeDate(),DateUtils.YYYY_MM_DD)));
  73. for(String tradeDate : tradeListMap.keySet()){
  74. if(navListMap.containsKey(tradeDate)){
  75. deletionInfoMapper.updateRemark(fundId,DeletionType.ASSET_DELETION.getCode(),tradeDate,DeletionType.NO_DELETION.getInfo());
  76. continue;
  77. }
  78. //写入缺失信息表
  79. saveDeletionInfoDO(fundId,tradeDate,DeletionType.ASSET_DELETION.getCode());
  80. }
  81. }
  82. if(Frequency.WEEK == Frequency.getFrequencyByCode(fundReportFrequencyDO.getAssetFrequency())){
  83. Map<String,List<AssetDO>> navListMap = assetDOList.stream().collect(Collectors.groupingBy(e -> DateUtils.format(e.getPriceDate(),DateUtils.YYYY_MM_DD)));
  84. TreeMap<Integer,List<AssetDO>> weekNavListMap = new TreeMap<>();
  85. //按周数整合
  86. for(String priceDate : navListMap.keySet()){
  87. Integer weekOfYear = DateUtil.weekOfYear(DateUtils.parse(priceDate,DateUtils.YYYY_MM_DD));
  88. if(weekNavListMap.containsKey(weekOfYear)){
  89. List<AssetDO> assetDOS = weekNavListMap.get(weekOfYear);
  90. assetDOS.addAll(navListMap.get(priceDate));
  91. weekNavListMap.put(weekOfYear,assetDOS);
  92. }else{
  93. List<AssetDO> navDOS = new ArrayList<>();
  94. navDOS.addAll(navListMap.get(priceDate));
  95. weekNavListMap.put(weekOfYear,navDOS);
  96. }
  97. }
  98. Map<Integer,List<TradeDateDO>> tradeListMap = tradeDateDOList.stream().collect(Collectors.groupingBy(e -> e.getWeekOfYear()));
  99. for(Integer weekOfYear : tradeListMap.keySet()){
  100. if(weekNavListMap.containsKey(weekOfYear)){
  101. List<AssetDO> assetDOS = weekNavListMap.get(weekOfYear);
  102. String tradeDate = DateUtils.format(assetDOS.get(assetDOS.size()-1).getPriceDate(),DateUtils.YYYY_MM_DD);
  103. deletionInfoMapper.updateRemark(fundId,DeletionType.ASSET_DELETION.getCode(),tradeDate,DeletionType.NO_DELETION.getInfo());
  104. continue;
  105. }
  106. //不包含的话,默认取每周的最后一个交易日作为周净值日期
  107. List<TradeDateDO> tradeDateDOS = tradeListMap.get(weekOfYear);
  108. String tradeDate = null;
  109. if(tradeDateDOS.size() > 0){
  110. tradeDate = DateUtils.format(tradeDateDOS.get(tradeDateDOS.size()-1).getTradeDate(),DateUtils.YYYY_MM_DD);
  111. }
  112. //写入缺失信息表
  113. saveDeletionInfoDO(fundId,tradeDate,DeletionType.NAV_DELETION.getCode());
  114. }
  115. }
  116. if(Frequency.MONTH == Frequency.getFrequencyByCode(fundReportFrequencyDO.getAssetFrequency())){
  117. Map<String,List<AssetDO>> navListMap = assetDOList.stream().collect(Collectors.groupingBy(e -> DateUtils.format(e.getPriceDate(),DateUtils.YYYY_MM_DD)));
  118. TreeMap<String,List<AssetDO>> monthNavListMap = new TreeMap<>();
  119. //按周数整合
  120. for(String priceDate : navListMap.keySet()){
  121. String yearMonth = priceDate.substring(0,7);
  122. if(monthNavListMap.containsKey(yearMonth)){
  123. List<AssetDO> navDOS = monthNavListMap.get(yearMonth);
  124. navDOS.addAll(navListMap.get(priceDate));
  125. monthNavListMap.put(yearMonth,navDOS);
  126. }else{
  127. List<AssetDO> navDOS = new ArrayList<>();
  128. navDOS.addAll(navListMap.get(priceDate));
  129. monthNavListMap.put(yearMonth,navDOS);
  130. }
  131. }
  132. Map<String,List<TradeDateDO>> tradeListMap = tradeDateDOList.stream().collect(Collectors.groupingBy(e -> e.getYearmonth()));
  133. for(String yearMonth : tradeListMap.keySet()){
  134. if(monthNavListMap.containsKey(yearMonth)){
  135. List<AssetDO> assetDOS = monthNavListMap.get(yearMonth);
  136. String tradeDate = DateUtils.format(assetDOS.get(assetDOS.size()-1).getPriceDate(),DateUtils.YYYY_MM_DD);
  137. deletionInfoMapper.updateRemark(fundId,DeletionType.ASSET_DELETION.getCode(),tradeDate,DeletionType.NO_DELETION.getInfo());
  138. continue;
  139. }
  140. //不包含的话,默认取每周的最后一个交易日作为周净值日期
  141. List<TradeDateDO> tradeDateDOS = tradeListMap.get(yearMonth);
  142. String tradeDate = null;
  143. if(tradeDateDOS.size() > 0){
  144. tradeDate = DateUtils.format(tradeDateDOS.get(tradeDateDOS.size()-1).getTradeDate(),DateUtils.YYYY_MM_DD);
  145. }
  146. //写入缺失信息表
  147. saveDeletionInfoDO(fundId,tradeDate,DeletionType.ASSET_DELETION.getCode());
  148. }
  149. }
  150. }
  151. private void navDeletion(String fundId,List<NavDO> navDOList, List<TradeDateDO> tradeDateDOList,FundReportFrequencyDO fundReportFrequencyDO) {
  152. //只处理日月季频率
  153. if(Frequency.DAY == Frequency.getFrequencyByCode(fundReportFrequencyDO.getNavFrequency())){
  154. Map<String,List<NavDO>> navListMap = navDOList.stream().collect(Collectors.groupingBy(e -> DateUtils.format(e.getPriceDate(),DateUtils.YYYY_MM_DD)));
  155. Map<String,List<TradeDateDO>> tradeListMap = tradeDateDOList.stream().collect(Collectors.groupingBy(e -> DateUtils.format(e.getTradeDate(),DateUtils.YYYY_MM_DD)));
  156. for(String tradeDate : tradeListMap.keySet()){
  157. if(navListMap.containsKey(tradeDate)){
  158. deletionInfoMapper.updateRemark(fundId,DeletionType.NAV_DELETION.getCode(),tradeDate,DeletionType.NO_DELETION.getInfo());
  159. continue;
  160. }
  161. //写入缺失信息表
  162. saveDeletionInfoDO(fundId,tradeDate,DeletionType.NAV_DELETION.getCode());
  163. }
  164. }
  165. if(Frequency.WEEK == Frequency.getFrequencyByCode(fundReportFrequencyDO.getNavFrequency())){
  166. Map<String,List<NavDO>> navListMap = navDOList.stream().collect(Collectors.groupingBy(e -> DateUtils.format(e.getPriceDate(),DateUtils.YYYY_MM_DD)));
  167. TreeMap<Integer,List<NavDO>> weekNavListMap = new TreeMap<>();
  168. //按周数整合
  169. for(String priceDate : navListMap.keySet()){
  170. Integer weekOfYear = DateUtil.weekOfYear(DateUtils.parse(priceDate,DateUtils.YYYY_MM_DD));
  171. if(weekNavListMap.containsKey(weekOfYear)){
  172. List<NavDO> navDOS = weekNavListMap.get(weekOfYear);
  173. navDOS.addAll(navListMap.get(priceDate));
  174. weekNavListMap.put(weekOfYear,navDOS);
  175. }else{
  176. List<NavDO> navDOS = new ArrayList<>();
  177. navDOS.addAll(navListMap.get(priceDate));
  178. weekNavListMap.put(weekOfYear,navDOS);
  179. }
  180. }
  181. Map<Integer,List<TradeDateDO>> tradeListMap = tradeDateDOList.stream().collect(Collectors.groupingBy(e -> e.getWeekOfYear()));
  182. for(Integer weekOfYear : tradeListMap.keySet()){
  183. if(weekNavListMap.containsKey(weekOfYear)){
  184. List<NavDO> navDOS = weekNavListMap.get(weekOfYear);
  185. String tradeDate = DateUtils.format(navDOS.get(navDOS.size()-1).getPriceDate(),DateUtils.YYYY_MM_DD);
  186. deletionInfoMapper.updateRemark(fundId,DeletionType.NAV_DELETION.getCode(),tradeDate,DeletionType.NO_DELETION.getInfo());
  187. continue;
  188. }
  189. //不包含的话,默认取每周的最后一个交易日作为周净值日期
  190. List<TradeDateDO> tradeDateDOS = tradeListMap.get(weekOfYear);
  191. String tradeDate = null;
  192. if(tradeDateDOS.size() > 0){
  193. tradeDate = DateUtils.format(tradeDateDOS.get(tradeDateDOS.size()-1).getTradeDate(),DateUtils.YYYY_MM_DD);
  194. }
  195. //写入缺失信息表
  196. saveDeletionInfoDO(fundId,tradeDate,DeletionType.NAV_DELETION.getCode());
  197. }
  198. }
  199. if(Frequency.MONTH == Frequency.getFrequencyByCode(fundReportFrequencyDO.getNavFrequency())){
  200. Map<String,List<NavDO>> navListMap = navDOList.stream().collect(Collectors.groupingBy(e -> DateUtils.format(e.getPriceDate(),DateUtils.YYYY_MM_DD)));
  201. TreeMap<String,List<NavDO>> monthNavListMap = new TreeMap<>();
  202. //按周数整合
  203. for(String priceDate : navListMap.keySet()){
  204. String yearMonth = priceDate.substring(0,7);
  205. if(monthNavListMap.containsKey(yearMonth)){
  206. List<NavDO> navDOS = monthNavListMap.get(yearMonth);
  207. navDOS.addAll(navListMap.get(priceDate));
  208. monthNavListMap.put(yearMonth,navDOS);
  209. }else{
  210. List<NavDO> navDOS = new ArrayList<>();
  211. navDOS.addAll(navListMap.get(priceDate));
  212. monthNavListMap.put(yearMonth,navDOS);
  213. }
  214. }
  215. Map<String,List<TradeDateDO>> tradeListMap = tradeDateDOList.stream().collect(Collectors.groupingBy(e -> e.getYearmonth()));
  216. for(String yearMonth : tradeListMap.keySet()){
  217. if(monthNavListMap.containsKey(yearMonth)){
  218. List<NavDO> navDOS = monthNavListMap.get(yearMonth);
  219. String tradeDate = DateUtils.format(navDOS.get(navDOS.size()-1).getPriceDate(),DateUtils.YYYY_MM_DD);
  220. deletionInfoMapper.updateRemark(fundId,DeletionType.NAV_DELETION.getCode(),tradeDate,DeletionType.NO_DELETION.getInfo());
  221. continue;
  222. }
  223. //不包含的话,默认取每周的最后一个交易日作为周净值日期
  224. List<TradeDateDO> tradeDateDOS = tradeListMap.get(yearMonth);
  225. String tradeDate = null;
  226. if(tradeDateDOS.size() > 0){
  227. tradeDate = DateUtils.format(tradeDateDOS.get(tradeDateDOS.size()-1).getTradeDate(),DateUtils.YYYY_MM_DD);
  228. }
  229. //写入缺失信息表
  230. saveDeletionInfoDO(fundId,tradeDate,DeletionType.NAV_DELETION.getCode());
  231. }
  232. }
  233. }
  234. private void saveDeletionInfoDO(String fundId, String tradeDate, Integer code) {
  235. if(tradeDate == null){
  236. return;
  237. }
  238. DeletionInfoDO deletionInfoDO = new DeletionInfoDO();
  239. deletionInfoDO.setFundId(fundId);
  240. deletionInfoDO.setDeletionDate(tradeDate);
  241. deletionInfoDO.setDeletionType(code);
  242. DeletionInfoDO oldDeletionDO = deletionInfoMapper.getDeletionInfoDO(deletionInfoDO);
  243. if(StringUtil.isNull(oldDeletionDO)){
  244. deletionInfoDO.setIsvalid(1);
  245. deletionInfoDO.setUpdateTime(DateUtils.getNowDate());
  246. deletionInfoDO.setCreateTime(DateUtils.getNowDate());
  247. deletionInfoMapper.saveDeletionInfoDO(deletionInfoDO);
  248. }
  249. }
  250. }