|
@@ -4,6 +4,7 @@ import cn.hutool.core.bean.BeanUtil;
|
|
import cn.hutool.core.collection.CollUtil;
|
|
import cn.hutool.core.collection.CollUtil;
|
|
import cn.hutool.core.collection.CollectionUtil;
|
|
import cn.hutool.core.collection.CollectionUtil;
|
|
import cn.hutool.core.collection.ListUtil;
|
|
import cn.hutool.core.collection.ListUtil;
|
|
|
|
+import cn.hutool.core.date.DatePattern;
|
|
import cn.hutool.core.date.DateUtil;
|
|
import cn.hutool.core.date.DateUtil;
|
|
import cn.hutool.core.exceptions.ExceptionUtil;
|
|
import cn.hutool.core.exceptions.ExceptionUtil;
|
|
import cn.hutool.core.map.MapUtil;
|
|
import cn.hutool.core.map.MapUtil;
|
|
@@ -482,7 +483,7 @@ public class EmailParseService {
|
|
emailFundNavMapper.batchInsert(emailFundNavDOList);
|
|
emailFundNavMapper.batchInsert(emailFundNavDOList);
|
|
List<NavDO> navDOList = emailFundNavDOList.stream().filter(e -> StrUtil.isNotBlank(e.getFundId()))
|
|
List<NavDO> navDOList = emailFundNavDOList.stream().filter(e -> StrUtil.isNotBlank(e.getFundId()))
|
|
.map(e -> BeanUtil.copyProperties(e, NavDO.class)).collect(Collectors.toList());
|
|
.map(e -> BeanUtil.copyProperties(e, NavDO.class)).collect(Collectors.toList());
|
|
- saveNavDo(navDOList);
|
|
|
|
|
|
+ saveNavDo(navDOList,fileId);
|
|
}
|
|
}
|
|
// 保存规模数据
|
|
// 保存规模数据
|
|
List<EmailFundAssetDO> emailFundAssetDOList = fundNavDTOList.stream()
|
|
List<EmailFundAssetDO> emailFundAssetDOList = fundNavDTOList.stream()
|
|
@@ -497,7 +498,7 @@ public class EmailParseService {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- public void saveNavDo(List<NavDO> navDOList) {
|
|
|
|
|
|
+ public void saveNavDo(List<NavDO> navDOList,Integer fileId) {
|
|
if (CollUtil.isEmpty(navDOList)) {
|
|
if (CollUtil.isEmpty(navDOList)) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
@@ -508,21 +509,60 @@ public class EmailParseService {
|
|
List<String> dateList = navMapper.queryFundNavByDate(entry.getKey(), priceDateList);
|
|
List<String> dateList = navMapper.queryFundNavByDate(entry.getKey(), priceDateList);
|
|
List<NavDO> updateNavDoList = navDOS.stream().filter(e -> dateList.contains(DateUtil.format(e.getPriceDate(), DateConst.YYYY_MM_DD))).collect(Collectors.toList());
|
|
List<NavDO> updateNavDoList = navDOS.stream().filter(e -> dateList.contains(DateUtil.format(e.getPriceDate(), DateConst.YYYY_MM_DD))).collect(Collectors.toList());
|
|
List<NavDO> insertNavDoList = navDOS.stream().filter(e -> !dateList.contains(DateUtil.format(e.getPriceDate(), DateConst.YYYY_MM_DD))).collect(Collectors.toList());
|
|
List<NavDO> insertNavDoList = navDOS.stream().filter(e -> !dateList.contains(DateUtil.format(e.getPriceDate(), DateConst.YYYY_MM_DD))).collect(Collectors.toList());
|
|
- if (CollUtil.isNotEmpty(insertNavDoList)) {
|
|
|
|
- Map<Date, List<NavDO>> priceDateNavDoListMap = insertNavDoList.stream().collect(Collectors.groupingBy(NavDO::getPriceDate));
|
|
|
|
- boolean hasDuplicationDateData = priceDateNavDoListMap.values().stream().map(List::size).anyMatch(e -> e > 1);
|
|
|
|
- if (!hasDuplicationDateData) {
|
|
|
|
- navMapper.batchInsert(insertNavDoList);
|
|
|
|
- }
|
|
|
|
- // 要插入的数据中存在相同日期的数据 -> 只能一条一条的插入数据了
|
|
|
|
- insertNavDoList.forEach(e -> saveNavDo(ListUtil.toList(e)));
|
|
|
|
|
|
+ //按照净值日期排序,方便后面的振幅检测
|
|
|
|
+ if (CollUtil.isNotEmpty(insertNavDoList) && insertNavDoList.size() > 1) {
|
|
|
|
+ insertNavDoList = insertNavDoList.stream().sorted(Comparator.comparing(NavDO::getPriceDate)).collect(Collectors.toList());
|
|
|
|
+ }
|
|
|
|
+ if (CollUtil.isNotEmpty(updateNavDoList) && updateNavDoList.size() > 1) {
|
|
|
|
+ updateNavDoList = updateNavDoList.stream().sorted(Comparator.comparing(NavDO::getPriceDate)).collect(Collectors.toList());
|
|
}
|
|
}
|
|
- if (CollUtil.isNotEmpty(updateNavDoList)) {
|
|
|
|
- navMapper.batchUpdate(updateNavDoList);
|
|
|
|
|
|
+ //因为要做振幅检测,所以不能使用批量插入的方式
|
|
|
|
+ for(NavDO insertDO : insertNavDoList){
|
|
|
|
+ boolean amplitudeException = amplitudeNav(insertDO);
|
|
|
|
+ if(amplitudeException){
|
|
|
|
+ //超过净值振幅不能入库,同时需要修改采集库的入库状态和异常信息
|
|
|
|
+ saveAmplitudeFundNav(insertDO,fileId);
|
|
|
|
+ }else{
|
|
|
|
+ navMapper.batchInsert(ListUtil.toList(insertDO));
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+ for(NavDO updateDO : updateNavDoList){
|
|
|
|
+ boolean amplitudeException = amplitudeNav(updateDO);
|
|
|
|
+ if(amplitudeException){
|
|
|
|
+ //超过净值振幅不能入库,同时需要修改采集库的入库状态和异常信息
|
|
|
|
+ saveAmplitudeFundNav(updateDO,fileId);
|
|
|
|
+ }else{
|
|
|
|
+ navMapper.batchUpdate(ListUtil.toList(updateDO));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+// if (CollUtil.isNotEmpty(insertNavDoList)) {
|
|
|
|
+// Map<Date, List<NavDO>> priceDateNavDoListMap = insertNavDoList.stream().collect(Collectors.groupingBy(NavDO::getPriceDate));
|
|
|
|
+// boolean hasDuplicationDateData = priceDateNavDoListMap.values().stream().map(List::size).anyMatch(e -> e > 1);
|
|
|
|
+// if (!hasDuplicationDateData) {
|
|
|
|
+// navMapper.batchInsert(insertNavDoList);
|
|
|
|
+// }
|
|
|
|
+// // 要插入的数据中存在相同日期的数据 -> 只能一条一条的插入数据了
|
|
|
|
+// insertNavDoList.forEach(e -> saveNavDo(ListUtil.toList(e)));
|
|
|
|
+// }
|
|
|
|
+// if (CollUtil.isNotEmpty(updateNavDoList)) {
|
|
|
|
+// navMapper.batchUpdate(updateNavDoList);
|
|
|
|
+// }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ private void saveAmplitudeFundNav(NavDO insertDO,Integer fileId) {
|
|
|
|
+ EmailFundNavDO fundNavDO = new EmailFundNavDO();
|
|
|
|
+ fundNavDO.setFundId(insertDO.getFundId());
|
|
|
|
+ fundNavDO.setNav(insertDO.getNav());
|
|
|
|
+ fundNavDO.setPriceDate(insertDO.getPriceDate());
|
|
|
|
+ fundNavDO.setCumulativeNavWithdrawal(insertDO.getCumulativeNavWithdrawal());
|
|
|
|
+ fundNavDO.setFileId(fileId);
|
|
|
|
+ fundNavDO.setExceptionStatus(NavParseStatusConst.AMPLITUDE_EXCEPTION);
|
|
|
|
+ fundNavDO.setIsStored(0);
|
|
|
|
+ fundNavDO.setUpdateTime(new Date());
|
|
|
|
+ emailFundNavMapper.update(fundNavDO);
|
|
|
|
+ }
|
|
|
|
+
|
|
public void saveAssetDo(List<AssetDO> assetDOList) {
|
|
public void saveAssetDo(List<AssetDO> assetDOList) {
|
|
if (CollUtil.isEmpty(assetDOList)) {
|
|
if (CollUtil.isEmpty(assetDOList)) {
|
|
return;
|
|
return;
|
|
@@ -706,25 +746,19 @@ public class EmailParseService {
|
|
}
|
|
}
|
|
fundNavDTO.setParseStatus(NavParseStatusConst.SUCCESS);
|
|
fundNavDTO.setParseStatus(NavParseStatusConst.SUCCESS);
|
|
}
|
|
}
|
|
-
|
|
|
|
- private boolean amplitudeNav(EmailFundNavDTO fundNavDTO) {
|
|
|
|
- if(CollUtil.isEmpty(fundNavDTO.getFundIdList())){
|
|
|
|
|
|
+ //振幅检测
|
|
|
|
+ private boolean amplitudeNav(NavDO navDO) {
|
|
|
|
+ String fundId = navDO.getFundId();
|
|
|
|
+ String priceDate = DateUtils.format(navDO.getPriceDate(), DateUtils.YYYY_MM_DD);
|
|
|
|
+ //上一期单位净值
|
|
|
|
+ NavDO preNavDO = navMapper.queryNavByFundIdDate(fundId,priceDate);
|
|
|
|
+ if(preNavDO == null){
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
- List<String> fundIdList = fundNavDTO.getFundIdList();
|
|
|
|
- String priceDate = fundNavDTO.getPriceDate();
|
|
|
|
- for(String fundId : fundIdList){
|
|
|
|
- NavDO navDO = navMapper.queryNavByFundIdDate(fundId,priceDate);
|
|
|
|
- if(navDO == null){
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
- //|(当期-上期)/ 上期 | >= 0.2
|
|
|
|
- BigDecimal amplitudeRate = (new BigDecimal(fundNavDTO.getNav()).subtract(navDO.getNav())).divide(navDO.getNav());
|
|
|
|
- Double absAmplitudeRate = Math.abs(amplitudeRate.doubleValue());
|
|
|
|
- if(BigDecimal.valueOf(absAmplitudeRate).compareTo(new BigDecimal(0.2)) > 0 ){
|
|
|
|
- fundNavDTO.setParseStatus(NavParseStatusConst.AMPLITUDE_EXCEPTION);
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
|
|
+ //|(当期-上期)/ 上期 | >= 0.2
|
|
|
|
+ BigDecimal amplitudeRate = navDO.getNav().subtract(preNavDO.getNav()).divide(preNavDO.getNav(),4, BigDecimal.ROUND_HALF_UP);
|
|
|
|
+ if(amplitudeRate.abs().compareTo(new BigDecimal(0.2)) > 0 ){
|
|
|
|
+ return true;
|
|
}
|
|
}
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|