Sfoglia il codice sorgente

超短池参考数据修正

Zhangbw 1 mese fa
parent
commit
c5f0ab29e2

+ 8 - 13
src/main/java/com/yingpai/gupiao/controller/StockHistoryController.java

@@ -77,23 +77,18 @@ public class StockHistoryController {
      */
     @GetMapping("/stats")
     public Result<Map<String, Object>> getHistoryStats(
-            @RequestParam("startDate") @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
-            @RequestParam("endDate") @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate,
+            @RequestParam(value = "startDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
+            @RequestParam(value = "endDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate,
             @RequestParam("poolType") Integer poolType) {
-        
-        // 参数校验
-        if (startDate == null || endDate == null) {
-            return Result.error(400, "开始日期和结束日期不能为空");
-        }
-        
-        if (startDate.isAfter(endDate)) {
-            return Result.error(400, "开始日期不能晚于结束日期");
-        }
-        
+
         if (poolType == null || (poolType != 1 && poolType != 2)) {
             return Result.error(400, "池类型无效,1=超短池,2=强势池");
         }
-        
+
+        if (startDate != null && endDate != null && startDate.isAfter(endDate)) {
+            return Result.error(400, "开始日期不能晚于结束日期");
+        }
+
         try {
             Map<String, Object> result = stockHistoryService.queryHistoryStats(startDate, endDate, poolType);
             return Result.success(result);

+ 19 - 0
src/main/java/com/yingpai/gupiao/mapper/StockPoolMapper.java

@@ -7,6 +7,7 @@ import org.apache.ibatis.annotations.Select;
 
 import java.time.LocalDate;
 import java.util.List;
+import java.util.Map;
 
 /**
  * 股票池Mapper
@@ -69,4 +70,22 @@ public interface StockPoolMapper extends BaseMapper<StockPool> {
             "WHERE stock_code = #{stockCode} AND record_date = #{recordDate} " +
             "LIMIT 1")
     java.math.BigDecimal selectClosePriceFromHistory(String stockCode, LocalDate recordDate);
+
+    @Select("<script>" +
+            "SELECT " +
+            "COUNT(CASE WHEN next_day_gain IS NOT NULL THEN 1 END) as totalCount, " +
+            "SUM(CASE WHEN next_day_gain >= 2 THEN 1 ELSE 0 END) as successCount, " +
+            "SUM(CASE WHEN next_day_gain &lt;= -3 THEN 1 ELSE 0 END) as failCount, " +
+            "AVG(CASE WHEN next_day_gain IS NOT NULL THEN next_day_gain END) as avgTrend " +
+            "FROM stock_pool " +
+            "WHERE pool_type = #{poolType} " +
+            "<if test='startDate != null and endDate != null'>" +
+            "AND add_date BETWEEN #{startDate} AND #{endDate} " +
+            "</if>" +
+            "AND ((#{poolType} = 1 AND (status = 1 OR (status = 2 AND add_date &lt; CURDATE()))) OR (#{poolType} = 2 AND status IN (1, 2)))" +
+            "</script>")
+    Map<String, Object> selectPoolHistoryStats(
+        @org.apache.ibatis.annotations.Param("startDate") LocalDate startDate,
+        @org.apache.ibatis.annotations.Param("endDate") LocalDate endDate,
+        @org.apache.ibatis.annotations.Param("poolType") Integer poolType);
 }

+ 18 - 35
src/main/java/com/yingpai/gupiao/service/impl/StockHistoryServiceImpl.java

@@ -47,7 +47,12 @@ public class StockHistoryServiceImpl implements StockHistoryService {
             }
         }
 
-        // 查询总数
+        // 查询全量统计(分母统一为有隔日数据的记录)
+        Map<String, Object> stats = stockPoolMapper.selectPoolHistoryStats(startDate, endDate, poolType);
+        long successCount = stats != null && stats.get("successCount") != null ? ((Number) stats.get("successCount")).longValue() : 0;
+        long failCount = stats != null && stats.get("failCount") != null ? ((Number) stats.get("failCount")).longValue() : 0;
+
+        // 总记录数(含无隔日数据的,用于分页)
         int total = stockPoolMapper.countPoolHistory(startDate, endDate, poolType);
 
         // 计算总页数
@@ -57,6 +62,8 @@ public class StockHistoryServiceImpl implements StockHistoryService {
         Map<String, Object> result = new HashMap<>();
         result.put("list", list);
         result.put("total", total);
+        result.put("successCount", successCount);
+        result.put("failCount", failCount);
         result.put("pageNum", pageNum);
         result.put("pageSize", pageSize);
         result.put("pages", pages);
@@ -67,47 +74,23 @@ public class StockHistoryServiceImpl implements StockHistoryService {
     
     @Override
     public Map<String, Object> queryHistoryStats(LocalDate startDate, LocalDate endDate, Integer poolType) {
-        // 查询所有数据(不分页)
-        List<StockHistoryVO> allList = stockPoolMapper.selectPoolHistory(
-            startDate, endDate, poolType, 0, Integer.MAX_VALUE
-        );
-
-        // 计算每条记录的成功/失败状态并统计
-        int successCount = 0;
-        int failCount = 0;
-        java.math.BigDecimal totalTrend = java.math.BigDecimal.ZERO;
-        int trendCount = 0;
+        Map<String, Object> stats = stockPoolMapper.selectPoolHistoryStats(startDate, endDate, poolType);
 
-        for (StockHistoryVO vo : allList) {
-            if (vo.getNextDayHighTrend() != null) {
-                // 累加涨幅用于计算平均值
-                totalTrend = totalTrend.add(vo.getNextDayHighTrend());
-                trendCount++;
+        long totalCount = stats != null && stats.get("totalCount") != null ? ((Number) stats.get("totalCount")).longValue() : 0;
+        long successCount = stats != null && stats.get("successCount") != null ? ((Number) stats.get("successCount")).longValue() : 0;
+        long failCount = stats != null && stats.get("failCount") != null ? ((Number) stats.get("failCount")).longValue() : 0;
 
-                if (vo.getNextDayHighTrend().compareTo(new java.math.BigDecimal("2")) >= 0) {
-                    successCount++;
-                } else if (vo.getNextDayHighTrend().compareTo(new java.math.BigDecimal("-3")) <= 0) {
-                    failCount++;
-                }
-            }
-        }
+        String successRate = totalCount > 0 ? String.format("%.1f%%", (successCount * 100.0 / totalCount)) : "0%";
 
-        int total = allList.size();
-        String successRate = total > 0 ? String.format("%.1f%%", (successCount * 100.0 / total)) : "0%";
-
-        // 计算平均收益率
-        String avgTrend = "0%";
-        if (trendCount > 0) {
-            java.math.BigDecimal avg = totalTrend.divide(
-                new java.math.BigDecimal(trendCount),
-                2,
-                java.math.RoundingMode.HALF_UP
-            );
+        String avgTrend = "+0%";
+        if (stats != null && stats.get("avgTrend") != null) {
+            java.math.BigDecimal avg = new java.math.BigDecimal(stats.get("avgTrend").toString())
+                .setScale(2, java.math.RoundingMode.HALF_UP);
             avgTrend = String.format("%+.2f%%", avg);
         }
 
         Map<String, Object> result = new HashMap<>();
-        result.put("totalCount", total);
+        result.put("totalCount", totalCount);
         result.put("successCount", successCount);
         result.put("failCount", failCount);
         result.put("successRate", successRate);