1
0

feat: 增加周线表

This commit is contained in:
2025-10-11 18:41:18 +08:00
parent b9a02194e2
commit e387fc839f
3 changed files with 98 additions and 30 deletions

View File

@@ -0,0 +1,60 @@
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 + "weekly")
public class Weekly extends SimpleEntity {
@Column(name = "`year`", nullable = false)
@Comment("年份")
private Integer year;
@Column(name = "`week`", nullable = false)
@Comment("周数")
private Integer week;
@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;
}

View File

@@ -34,11 +34,11 @@ public class TaskService extends SimpleServiceSupport<Task> {
@Getter
private final Set<TaskTemplate> templates = Stream.of(
new TaskTemplate("更新股票信息", "更新股票信息", UpdateStockTask.class),
new TaskTemplate("更新年线指标", "更新年线指标", UpdateYearlyTask.class),
new TaskTemplate("更新日线数据", "更新日线数据", UpdateDailyTask.class),
new TaskTemplate("更新财务指标", "更新财务指标", UpdateFinanceIndicatorTask.class),
new TaskTemplate("金字塔选股", "金字塔选股", PyramidSelect.class)
new TaskTemplate("b29f76a5-b07d-4182-85f8-2641c2a975c1", "更新股票信息", "更新股票信息", UpdateStockTask.class),
new TaskTemplate("e42dde60-5584-4c27-b3f7-72e4a4ff662d", "更新年线数据", "更新年线数据", UpdateYearlyTask.class),
new TaskTemplate("b9df25ce-aa55-4f73-8265-d8a724614177", "更新日线数据", "更新日线数据", UpdateDailyTask.class),
new TaskTemplate("8ab30478-c81f-4bbf-94dd-7e05fa537b50", "更新财务指标", "更新财务指标", UpdateFinanceIndicatorTask.class),
new TaskTemplate("a6a7b569-a171-481b-9184-716925571639", "金字塔选股", "金字塔选股", PyramidSelect.class)
).collect(Collectors.toSet());
private final Map<String, TaskTemplate> templateMap = templates.stream()
.collect(Collectors.toMap(TaskTemplate::id, template -> template));

View File

@@ -40,31 +40,39 @@ public class UpdateYearlyTask extends TaskRunner {
var endYear = dailyRepository.findMaxTradeDate().getYear();
var stocks = stockRepository.findAll();
for (int year = startYear, index = 0; year <= endYear; year++, index++) {
for (var stock : stocks) {
log.info("Processing {} {}", stock.getCode(), year);
if (stock.getListedDate().getYear() > year) {
continue;
}
var dailies = dailyRepository.findAll(
QDaily.daily.tradeDate.year().eq(year)
.and(QDaily.daily.stock.eq(stock))
);
var yearly = yearlyRepository.findOne(
QYearly.yearly.stock.eq(stock)
.and(QYearly.yearly.year.eq(year))
).orElseGet(Yearly::new);
yearly.setStock(stock);
yearly.setYear(year);
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);
}
int currentYear = year;
stocks.parallelStream()
.forEach(stock -> {
if (stock.getListedDate().getYear() > currentYear) {
return;
}
var yearlyOptional = yearlyRepository.findOne(
QYearly.yearly.stock.eq(stock)
.and(QYearly.yearly.year.eq(currentYear))
);
if (yearlyOptional.isPresent() && currentYear != endYear) {
return;
}
var dailies = dailyRepository.findAll(
QDaily.daily.tradeDate.year().eq(currentYear)
.and(QDaily.daily.stock.eq(stock))
);
if (dailies.isEmpty()) {
return;
}
var yearly = yearlyOptional.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);
});
updater.update((year - startYear) * 1.0 / (endYear - startYear + 1));
}
return null;