From 3991effa881647113c354ca4de9962f875141036 Mon Sep 17 00:00:00 2001 From: lanyuanxiaoyao Date: Thu, 25 Sep 2025 17:46:52 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E9=87=91=E5=AD=97?= =?UTF-8?q?=E5=A1=94=E9=80=89=E8=82=A1=E4=BB=BB=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../selector/PyramidStockSelector.java | 2 + .../leopard/server/service/StockService.java | 2 - .../leopard/server/service/TaskService.java | 4 +- .../server/service/task/PyramidSelect.java | 45 +++++++++++++++++++ 4 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 leopard-server/src/main/java/com/lanyuanxiaoyao/leopard/server/service/task/PyramidSelect.java diff --git a/leopard-core/src/main/java/com/lanyuanxiaoyao/leopard/core/service/selector/PyramidStockSelector.java b/leopard-core/src/main/java/com/lanyuanxiaoyao/leopard/core/service/selector/PyramidStockSelector.java index bc02734..a9b2aa5 100644 --- a/leopard-core/src/main/java/com/lanyuanxiaoyao/leopard/core/service/selector/PyramidStockSelector.java +++ b/leopard-core/src/main/java/com/lanyuanxiaoyao/leopard/core/service/selector/PyramidStockSelector.java @@ -12,6 +12,7 @@ import java.util.stream.Collectors; import lombok.extern.slf4j.Slf4j; import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; /** * 金字塔选股 @@ -28,6 +29,7 @@ public class PyramidStockSelector implements StockSelector select(Request request) { // 选择至少有最近5年财报的股票 diff --git a/leopard-server/src/main/java/com/lanyuanxiaoyao/leopard/server/service/StockService.java b/leopard-server/src/main/java/com/lanyuanxiaoyao/leopard/server/service/StockService.java index 67fd889..899d4a7 100644 --- a/leopard-server/src/main/java/com/lanyuanxiaoyao/leopard/server/service/StockService.java +++ b/leopard-server/src/main/java/com/lanyuanxiaoyao/leopard/server/service/StockService.java @@ -25,13 +25,11 @@ import org.springframework.stereotype.Service; @Slf4j @Service public class StockService extends SimpleServiceSupport { - private final StockRepository stockRepository; private final FinanceIndicatorRepository financeIndicatorRepository; private final DailyRepository dailyRepository; public StockService(StockRepository repository, FinanceIndicatorRepository financeIndicatorRepository, DailyRepository dailyRepository) { super(repository); - this.stockRepository = repository; this.financeIndicatorRepository = financeIndicatorRepository; this.dailyRepository = dailyRepository; } diff --git a/leopard-server/src/main/java/com/lanyuanxiaoyao/leopard/server/service/TaskService.java b/leopard-server/src/main/java/com/lanyuanxiaoyao/leopard/server/service/TaskService.java index dfbe638..f641387 100644 --- a/leopard-server/src/main/java/com/lanyuanxiaoyao/leopard/server/service/TaskService.java +++ b/leopard-server/src/main/java/com/lanyuanxiaoyao/leopard/server/service/TaskService.java @@ -4,6 +4,7 @@ import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.ObjectUtil; import com.lanyuanxiaoyao.leopard.core.entity.Task; import com.lanyuanxiaoyao.leopard.core.repository.TaskRepository; +import com.lanyuanxiaoyao.leopard.server.service.task.PyramidSelect; import com.lanyuanxiaoyao.leopard.server.service.task.TaskRunner; import com.lanyuanxiaoyao.leopard.server.service.task.UpdateDailyTask; import com.lanyuanxiaoyao.leopard.server.service.task.UpdateFinanceIndicatorTask; @@ -40,7 +41,8 @@ public class TaskService extends SimpleServiceSupport { new TaskTemplate("更新股票信息", "更新股票信息", UpdateStockTask.class), new TaskTemplate("更新年线指标", "更新年线指标", UpdateYearlyTask.class), new TaskTemplate("更新日线数据", "更新日线数据", UpdateDailyTask.class), - new TaskTemplate("更新财务指标", "更新财务指标", UpdateFinanceIndicatorTask.class) + new TaskTemplate("更新财务指标", "更新财务指标", UpdateFinanceIndicatorTask.class), + new TaskTemplate("金字塔选股", "金字塔选股", PyramidSelect.class) ).collect(Collectors.toSet()); private final Map templateMap = templates.stream() .collect(Collectors.toMap(TaskTemplate::id, template -> template)); diff --git a/leopard-server/src/main/java/com/lanyuanxiaoyao/leopard/server/service/task/PyramidSelect.java b/leopard-server/src/main/java/com/lanyuanxiaoyao/leopard/server/service/task/PyramidSelect.java new file mode 100644 index 0000000..f5627f6 --- /dev/null +++ b/leopard-server/src/main/java/com/lanyuanxiaoyao/leopard/server/service/task/PyramidSelect.java @@ -0,0 +1,45 @@ +package com.lanyuanxiaoyao.leopard.server.service.task; + +import com.lanyuanxiaoyao.leopard.core.entity.StockCollection; +import com.lanyuanxiaoyao.leopard.core.repository.StockCollectionRepository; +import com.lanyuanxiaoyao.leopard.core.service.selector.PyramidStockSelector; +import com.lanyuanxiaoyao.leopard.core.service.selector.StockSelector; +import java.time.LocalDate; +import java.util.Map; +import java.util.stream.Collectors; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.ApplicationContext; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +/** + * 金字塔选股 + * + * @author lanyuanxiaoyao + * @version 20250925 + */ +@Slf4j +@Component +public class PyramidSelect extends TaskRunner { + private final StockCollectionRepository stockCollectionRepository; + + private final PyramidStockSelector pyramidStockSelector; + + protected PyramidSelect(ApplicationContext context, StockCollectionRepository stockCollectionRepository, PyramidStockSelector pyramidStockSelector) { + super(context); + this.stockCollectionRepository = stockCollectionRepository; + this.pyramidStockSelector = pyramidStockSelector; + } + + @Transactional(rollbackFor = Throwable.class) + @Override + public String process(Map params, StepUpdater updater) throws Exception { + var candidates = pyramidStockSelector.select(new PyramidStockSelector.Request(LocalDate.now().getYear(), 50)); + var collection = new StockCollection(); + collection.setName("金字塔选股"); + collection.setDescription("金字塔选股"); + collection.setStocks(candidates.stream().map(StockSelector.Candidate::stock).collect(Collectors.toSet())); + stockCollectionRepository.save(collection); + return null; + } +}