feat: 增加年线行情更新
This commit is contained in:
@@ -29,6 +29,7 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
||||
@Table(name = Constants.DATABASE_PREFIX + "daily")
|
||||
public class Daily extends SimpleEntity {
|
||||
@Column(nullable = false)
|
||||
@Comment("交易日")
|
||||
private LocalDate tradeDate;
|
||||
@Comment("开盘价")
|
||||
private Double open;
|
||||
|
||||
@@ -61,6 +61,10 @@ public class Stock extends SimpleEntity {
|
||||
@ToString.Exclude
|
||||
private Set<Daily> dailies;
|
||||
|
||||
@OneToMany(mappedBy = "stock", cascade = CascadeType.REMOVE)
|
||||
@ToString.Exclude
|
||||
private Set<Yearly> yearlies;
|
||||
|
||||
@OneToMany(mappedBy = "stock", cascade = CascadeType.REMOVE)
|
||||
@ToString.Exclude
|
||||
private Set<FinanceIndicator> indicators;
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.lanyuanxiaoyao.leopard.core.entity;
|
||||
|
||||
import com.lanyuanxiaoyao.leopard.core.Constants;
|
||||
import com.lanyuanxiaoyao.service.template.entity.SimpleEntity;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.EntityListeners;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
import lombok.experimental.FieldNameConstants;
|
||||
import org.hibernate.annotations.Comment;
|
||||
import org.hibernate.annotations.DynamicInsert;
|
||||
import org.hibernate.annotations.DynamicUpdate;
|
||||
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
||||
|
||||
/**
|
||||
* 年线行情,后复权
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
@ToString(callSuper = true)
|
||||
@FieldNameConstants
|
||||
@Entity
|
||||
@DynamicUpdate
|
||||
@DynamicInsert
|
||||
@EntityListeners(AuditingEntityListener.class)
|
||||
@Table(name = Constants.DATABASE_PREFIX + "yearly")
|
||||
public class Yearly extends SimpleEntity {
|
||||
@Column(nullable = false)
|
||||
@Comment("年份")
|
||||
private Integer year;
|
||||
@Comment("开盘价")
|
||||
private Double open;
|
||||
@Comment("最高价")
|
||||
private Double high;
|
||||
@Comment("最低价")
|
||||
private Double low;
|
||||
@Comment("收盘价")
|
||||
private Double close;
|
||||
@Comment("涨跌额")
|
||||
private Double priceChangeAmount;
|
||||
@Comment("涨跌幅")
|
||||
private Double priceFluctuationRange;
|
||||
@Comment("成交量")
|
||||
private Double volume;
|
||||
@Comment("成交额")
|
||||
private Double turnover;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(nullable = false)
|
||||
@ToString.Exclude
|
||||
private Stock stock;
|
||||
}
|
||||
@@ -19,6 +19,14 @@ public interface DailyRepository extends SimpleRepository<Daily> {
|
||||
@Query("select distinct daily.tradeDate from Daily daily where daily.stock.id = ?1")
|
||||
List<LocalDate> findDistinctTradeDateByStockId(Long stockId);
|
||||
|
||||
@Query("select max(daily.tradeDate) from Daily daily")
|
||||
LocalDate findMaxTradeDate();
|
||||
|
||||
@Query("select min(daily.tradeDate) from Daily daily")
|
||||
LocalDate findMinTradeDate();
|
||||
|
||||
List<Daily> findAllByTradeDate_YearAndStock_Code(int tradeDateYear, String stockCode);
|
||||
|
||||
@EntityGraph(attributePaths = {"stock"})
|
||||
@Override
|
||||
Optional<Daily> findOne(Predicate predicate);
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.lanyuanxiaoyao.leopard.core.repository;
|
||||
|
||||
import com.lanyuanxiaoyao.leopard.core.entity.Yearly;
|
||||
import com.lanyuanxiaoyao.service.template.repository.SimpleRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface YearlyRepository extends SimpleRepository<Yearly> {
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.lanyuanxiaoyao.leopard.core;
|
||||
|
||||
import com.lanyuanxiaoyao.service.template.util.DDLGenerator;
|
||||
import com.lanyuanxiaoyao.service.template.Helper;
|
||||
import org.hibernate.dialect.PostgreSQLDialect;
|
||||
import org.postgresql.Driver;
|
||||
|
||||
@@ -12,7 +12,7 @@ import org.postgresql.Driver;
|
||||
*/
|
||||
public class GenerateDDL {
|
||||
public static void main(String[] args) {
|
||||
DDLGenerator.generateDDL(
|
||||
Helper.generateDDL(
|
||||
"com.lanyuanxiaoyao.leopard.core.entity",
|
||||
"/Users/lanyuanxiaoyao/Project/IdeaProjects/leopard/leopard-core/target",
|
||||
PostgreSQLDialect.class,
|
||||
|
||||
@@ -17,13 +17,13 @@ import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@LiteflowComponent("check_daily")
|
||||
public class CheckDailyNode extends TaskNodeComponent {
|
||||
public class CheckDaily extends TaskNodeComponent {
|
||||
private final StockRepository stockRepository;
|
||||
private final DailyRepository dailyRepository;
|
||||
|
||||
private final TuShareService tuShareService;
|
||||
|
||||
public CheckDailyNode(TaskService taskService, StockRepository stockRepository, DailyRepository dailyRepository, TuShareService tuShareService) {
|
||||
public CheckDaily(TaskService taskService, StockRepository stockRepository, DailyRepository dailyRepository, TuShareService tuShareService) {
|
||||
super(taskService);
|
||||
this.stockRepository = stockRepository;
|
||||
this.dailyRepository = dailyRepository;
|
||||
@@ -21,7 +21,7 @@ import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
@Slf4j
|
||||
@LiteflowComponent("update_daily")
|
||||
public class UpdateDailyNode extends NodeComponent {
|
||||
public class UpdateDaily extends NodeComponent {
|
||||
private final StockRepository stockRepository;
|
||||
private final DailyRepository dailyRepository;
|
||||
|
||||
@@ -29,7 +29,7 @@ public class UpdateDailyNode extends NodeComponent {
|
||||
|
||||
private final TransactionTemplate transactionTemplate;
|
||||
|
||||
public UpdateDailyNode(StockRepository stockRepository, DailyRepository dailyRepository, TuShareService tuShareService, TransactionTemplate transactionTemplate) {
|
||||
public UpdateDaily(StockRepository stockRepository, DailyRepository dailyRepository, TuShareService tuShareService, TransactionTemplate transactionTemplate) {
|
||||
this.stockRepository = stockRepository;
|
||||
this.dailyRepository = dailyRepository;
|
||||
this.tuShareService = tuShareService;
|
||||
@@ -19,13 +19,13 @@ import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@LiteflowComponent("update_finance")
|
||||
public class UpdateFinanceIndicatorNode extends TaskNodeComponent {
|
||||
public class UpdateFinanceIndicator extends TaskNodeComponent {
|
||||
private final FinanceIndicatorRepository financeIndicatorRepository;
|
||||
private final StockRepository stockRepository;
|
||||
|
||||
private final TuShareService tuShareService;
|
||||
|
||||
protected UpdateFinanceIndicatorNode(TaskService taskService, FinanceIndicatorRepository financeIndicatorRepository, StockRepository stockRepository, TuShareService tuShareService) {
|
||||
protected UpdateFinanceIndicator(TaskService taskService, FinanceIndicatorRepository financeIndicatorRepository, StockRepository stockRepository, TuShareService tuShareService) {
|
||||
super(taskService);
|
||||
this.financeIndicatorRepository = financeIndicatorRepository;
|
||||
this.stockRepository = stockRepository;
|
||||
@@ -11,12 +11,12 @@ import java.time.LocalDate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@LiteflowComponent("update_stock")
|
||||
public class UpdateStockNode extends NodeComponent {
|
||||
public class UpdateStock extends NodeComponent {
|
||||
private final StockRepository stockRepository;
|
||||
|
||||
private final TuShareService tuShareService;
|
||||
|
||||
public UpdateStockNode(StockRepository stockRepository, TuShareService tuShareService) {
|
||||
public UpdateStock(StockRepository stockRepository, TuShareService tuShareService) {
|
||||
this.stockRepository = stockRepository;
|
||||
this.tuShareService = tuShareService;
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.lanyuanxiaoyao.leopard.server.service.task;
|
||||
|
||||
import com.lanyuanxiaoyao.leopard.core.entity.Daily;
|
||||
import com.lanyuanxiaoyao.leopard.core.entity.QYearly;
|
||||
import com.lanyuanxiaoyao.leopard.core.entity.Yearly;
|
||||
import com.lanyuanxiaoyao.leopard.core.repository.DailyRepository;
|
||||
import com.lanyuanxiaoyao.leopard.core.repository.StockRepository;
|
||||
import com.lanyuanxiaoyao.leopard.core.repository.YearlyRepository;
|
||||
import com.lanyuanxiaoyao.leopard.server.service.TaskService;
|
||||
import com.yomahub.liteflow.annotation.LiteflowComponent;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
@Slf4j
|
||||
@LiteflowComponent("update_yearly")
|
||||
public class UpdateYearly extends TaskNodeComponent {
|
||||
private final StockRepository stockRepository;
|
||||
private final DailyRepository dailyRepository;
|
||||
private final YearlyRepository yearlyRepository;
|
||||
|
||||
private final TransactionTemplate transactionTemplate;
|
||||
|
||||
protected UpdateYearly(TaskService taskService, StockRepository stockRepository, DailyRepository dailyRepository, YearlyRepository yearlyRepository, TransactionTemplate transactionTemplate) {
|
||||
super(taskService);
|
||||
this.stockRepository = stockRepository;
|
||||
this.dailyRepository = dailyRepository;
|
||||
this.yearlyRepository = yearlyRepository;
|
||||
this.transactionTemplate = transactionTemplate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process() {
|
||||
var startYear = dailyRepository.findMinTradeDate().getYear();
|
||||
var endYear = dailyRepository.findMaxTradeDate().getYear();
|
||||
var stocks = stockRepository.findAll();
|
||||
for (var year = startYear; year <= endYear; year++) {
|
||||
var currentYear = year;
|
||||
transactionTemplate.execute(status -> {
|
||||
try {
|
||||
for (var stock : stocks) {
|
||||
if (stock.getListedDate().getYear() > currentYear) {
|
||||
continue;
|
||||
}
|
||||
var dailies = dailyRepository.findAllByTradeDate_YearAndStock_Code(currentYear, stock.getCode());
|
||||
var yearly = yearlyRepository.findOne(
|
||||
QYearly.yearly.stock.code.eq(stock.getCode())
|
||||
.and(QYearly.yearly.year.eq(currentYear))
|
||||
).orElseGet(Yearly::new);
|
||||
yearly.setStock(stock);
|
||||
yearly.setYear(currentYear);
|
||||
yearly.setClose(dailies.getLast().getHfqClose());
|
||||
yearly.setOpen(dailies.getFirst().getHfqOpen());
|
||||
yearly.setHigh(dailies.stream().map(Daily::getHfqHigh).max(Double::compareTo).orElse(0.0));
|
||||
yearly.setLow(dailies.stream().map(Daily::getHfqLow).min(Double::compareTo).orElse(0.0));
|
||||
yearly.setVolume(dailies.stream().mapToDouble(Daily::getVolume).sum());
|
||||
yearly.setTurnover(dailies.stream().mapToDouble(Daily::getTurnover).sum());
|
||||
yearly.setPriceChangeAmount(yearly.getClose() - yearly.getOpen());
|
||||
yearly.setPriceFluctuationRange((yearly.getClose() - yearly.getOpen()) / yearly.getOpen());
|
||||
yearlyRepository.save(yearly);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception exception) {
|
||||
log.error("Error", exception);
|
||||
status.setRollbackOnly();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user