Просмотр исходного кода

强势池最高涨幅计算修改

Zhangbw 1 месяц назад
Родитель
Сommit
2684561713

+ 15 - 0
ruoyi-modules/yp-stock/src/main/java/com/yingpai/stock/mapper/StockPoolHistoryMapper.java

@@ -35,4 +35,19 @@ public interface StockPoolHistoryMapper extends BaseMapperPlus<StockPoolHistory,
             "WHERE stock_code = #{stockCode} AND record_date <= #{recordDate} " +
             "AND record_date >= DATE_SUB(#{recordDate}, INTERVAL 10 DAY)")
     BigDecimal selectTenDaysHighestPrice(@Param("stockCode") String stockCode, @Param("recordDate") LocalDate recordDate);
+
+    /**
+     * 查询指定股票在指定日期范围内的最高价(用于强势池10天跟踪)
+     * @param stockCode 股票代码
+     * @param startDate 开始日期(入池日期)
+     * @param endDate 结束日期(当前导入日期)
+     * @return 日期范围内最高价,如果没有则返回null
+     */
+    @Select("SELECT MAX(day_highest_price) FROM stock_pool_history " +
+            "WHERE stock_code = #{stockCode} " +
+            "AND record_date >= #{startDate} " +
+            "AND record_date <= #{endDate}")
+    BigDecimal selectMaxHighPriceInRange(@Param("stockCode") String stockCode,
+                                         @Param("startDate") LocalDate startDate,
+                                         @Param("endDate") LocalDate endDate);
 }

+ 9 - 0
ruoyi-modules/yp-stock/src/main/java/com/yingpai/stock/service/IStockPoolService.java

@@ -67,4 +67,13 @@ public interface IStockPoolService {
      * @return 补全结果信息
      */
     String completeHistoryData(LocalDate importDate) throws Exception;
+
+    /**
+     * 更新强势池10天最高涨幅
+     * 对入池10天内的强势池股票,从入池日到当前导入日期,计算最高涨幅并更新
+     *
+     * @param importDate 导入日期(当天日期)
+     * @return 更新结果信息
+     */
+    String updateStrongPoolTenDayGain(LocalDate importDate);
 }

+ 9 - 0
ruoyi-modules/yp-stock/src/main/java/com/yingpai/stock/service/impl/StockPoolHistoryServiceImpl.java

@@ -455,6 +455,15 @@ public class StockPoolHistoryServiceImpl implements IStockPoolHistoryService {
             log.error("[数据补全] 补全历史数据失败: {}", e.getMessage(), e);
         }
 
+        // 更新强势池10天最高涨幅
+        try {
+            log.info("[强势池10天涨幅] 开始更新强势池10天最高涨幅,导入日期: {}", parsedRecordDate);
+            String gainResult = stockPoolService.updateStrongPoolTenDayGain(parsedRecordDate);
+            log.info("[强势池10天涨幅] 更新结果: {}", gainResult);
+        } catch (Exception e) {
+            log.error("[强势池10天涨幅] 更新失败: {}", e.getMessage(), e);
+        }
+
         if (failureNum > 0) {
             String message = String.format("导入完成!成功 %d 条(其中更新 %d 条),失败 %d 条。详细错误信息请查看服务器日志。",
                 successNum, updateNum, failureNum);

+ 77 - 0
ruoyi-modules/yp-stock/src/main/java/com/yingpai/stock/service/impl/StockPoolServiceImpl.java

@@ -443,4 +443,81 @@ public class StockPoolServiceImpl implements IStockPoolService {
         log.info("[补全历史数据] {}", message);
         return message;
     }
+
+    @Override
+    public String updateStrongPoolTenDayGain(LocalDate importDate) {
+        log.info("[强势池10天涨幅] 开始更新,导入日期: {}", importDate);
+
+        // 查询10天内入池的强势池股票(poolType=2)
+        LocalDate tenDaysAgo = importDate.minusDays(10);
+        LambdaQueryWrapper<StockPool> lqw = Wrappers.lambdaQuery();
+        lqw.eq(StockPool::getPoolType, 2)
+           .ge(StockPool::getAddDate, tenDaysAgo)
+           .lt(StockPool::getAddDate, importDate)
+           .in(StockPool::getStatus, 1, 2);
+
+        List<StockPool> poolsToUpdate = baseMapper.selectList(lqw);
+
+        if (poolsToUpdate.isEmpty()) {
+            String message = "没有需要更新的强势池股票(10天内入池)";
+            log.info("[强势池10天涨幅] {}", message);
+            return message;
+        }
+
+        log.info("[强势池10天涨幅] 找到 {} 只需要更新的股票", poolsToUpdate.size());
+
+        int updatedCount = 0;
+        int skippedCount = 0;
+
+        for (StockPool pool : poolsToUpdate) {
+            try {
+                String stockCode = pool.getStockCode();
+                LocalDate addDate = pool.getAddDate();
+                BigDecimal closePrice = pool.getClosePrice();
+
+                if (closePrice == null || closePrice.compareTo(BigDecimal.ZERO) == 0) {
+                    log.warn("[强势池10天涨幅] 股票 {} 收盘价为空或为0,跳过", stockCode);
+                    skippedCount++;
+                    continue;
+                }
+
+                // 查询从入池日到当前导入日的最高价
+                BigDecimal maxHighPrice = stockPoolHistoryMapper.selectMaxHighPriceInRange(
+                    stockCode, addDate, importDate);
+
+                if (maxHighPrice == null) {
+                    log.warn("[强势池10天涨幅] 股票 {} 在 [{}, {}] 范围内没有历史数据,跳过",
+                        stockCode, addDate, importDate);
+                    skippedCount++;
+                    continue;
+                }
+
+                // 计算涨幅:(最高价 - 入池收盘价) / 入池收盘价 * 100
+                BigDecimal tenDayGain = maxHighPrice.subtract(closePrice)
+                    .divide(closePrice, 4, RoundingMode.HALF_UP)
+                    .multiply(new BigDecimal("100"))
+                    .setScale(2, RoundingMode.HALF_UP);
+
+                pool.setNextDayGain(tenDayGain);
+                pool.setNextDayHigh(maxHighPrice);
+                pool.setUpdateTime(LocalDateTime.now());
+                baseMapper.updateById(pool);
+
+                updatedCount++;
+
+                log.debug("[强势池10天涨幅] 股票 {} 更新成功,入池日: {}, 跟踪天数: {}, 最高价: {}, 涨幅: {}%",
+                    stockCode, addDate, importDate.toEpochDay() - addDate.toEpochDay() + 1,
+                    maxHighPrice, tenDayGain);
+
+            } catch (Exception e) {
+                log.error("[强势池10天涨幅] 股票 {} 更新失败: {}",
+                    pool.getStockCode(), e.getMessage(), e);
+                skippedCount++;
+            }
+        }
+
+        String message = String.format("更新完成!成功 %d 条,跳过 %d 条", updatedCount, skippedCount);
+        log.info("[强势池10天涨幅] {}", message);
+        return message;
+    }
 }