feat: 尝试多图生成
This commit is contained in:
@@ -4,8 +4,11 @@ import cn.hutool.core.lang.Dict;
|
|||||||
import cn.hutool.extra.template.TemplateConfig;
|
import cn.hutool.extra.template.TemplateConfig;
|
||||||
import cn.hutool.extra.template.TemplateEngine;
|
import cn.hutool.extra.template.TemplateEngine;
|
||||||
import cn.hutool.extra.template.TemplateUtil;
|
import cn.hutool.extra.template.TemplateUtil;
|
||||||
|
import com.lanyuanxiaoyao.leopard.core.entity.Daily;
|
||||||
import com.lanyuanxiaoyao.leopard.core.entity.QDaily;
|
import com.lanyuanxiaoyao.leopard.core.entity.QDaily;
|
||||||
|
import com.lanyuanxiaoyao.leopard.core.helper.TaHelper;
|
||||||
import com.lanyuanxiaoyao.leopard.core.repository.DailyRepository;
|
import com.lanyuanxiaoyao.leopard.core.repository.DailyRepository;
|
||||||
|
import com.lanyuanxiaoyao.leopard.core.repository.StockCollectionRepository;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
@@ -13,7 +16,6 @@ import java.nio.file.Path;
|
|||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
@@ -30,6 +32,8 @@ public class StrategyApplication {
|
|||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private DailyRepository dailyRepository;
|
private DailyRepository dailyRepository;
|
||||||
|
@Resource
|
||||||
|
private StockCollectionRepository stockCollectionRepository;
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
SpringApplication.run(StrategyApplication.class, args);
|
SpringApplication.run(StrategyApplication.class, args);
|
||||||
@@ -38,26 +42,43 @@ public class StrategyApplication {
|
|||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
@EventListener(ApplicationReadyEvent.class)
|
@EventListener(ApplicationReadyEvent.class)
|
||||||
public void test() throws IOException {
|
public void test() throws IOException {
|
||||||
var dailies = dailyRepository.findAll(
|
var charts = Dict.create();
|
||||||
QDaily.daily.stock.code.eq("000001.SZ")
|
List.of("000048.SZ", "000333.SZ", "000568.SZ", "000596.SZ", "000651.SZ", "000848.SZ", "000858.SZ", "000933.SZ", "002027.SZ", "002032.SZ", "002142.SZ", "002192.SZ", "002415.SZ", "002432.SZ", "002475.SZ", "002517.SZ", "002555.SZ", "002648.SZ", "002756.SZ", "002847.SZ", "600036.SH", "600096.SH", "600132.SH", "600188.SH", "600309.SH", "600426.SH", "600436.SH", "600519.SH", "600546.SH", "600563.SH", "600702.SH", "600779.SH", "600803.SH", "600809.SH", "600961.SH", "601001.SH", "601100.SH", "601138.SH", "601225.SH", "601899.SH", "601919.SH", "603195.SH", "603198.SH", "603288.SH", "603369.SH", "603444.SH", "603565.SH", "603568.SH", "603605.SH", "603688.SH")
|
||||||
.and(QDaily.daily.tradeDate.after(LocalDate.of(2025, 1, 1))),
|
.parallelStream()
|
||||||
QDaily.daily.tradeDate.asc()
|
.forEach(code -> {
|
||||||
);
|
var dailies = dailyRepository.findAll(
|
||||||
|
QDaily.daily.stock.code.eq(code)
|
||||||
|
.and(QDaily.daily.tradeDate.after(LocalDate.of(2025, 1, 1))),
|
||||||
|
QDaily.daily.tradeDate.asc()
|
||||||
|
);
|
||||||
|
|
||||||
var xList = new ArrayList<String>();
|
var sma30 = TaHelper.sma(dailies, 30, Daily::getHfqClose);
|
||||||
var yList = new ArrayList<List<Double>>();
|
var slopes = new ArrayList<Double>();
|
||||||
for (var daily : dailies) {
|
slopes.add(0.0);
|
||||||
xList.add(daily.getTradeDate().toString());
|
for (int i = 1; i < sma30.size(); i++) {
|
||||||
yList.add(List.of(daily.getHfqOpen(), daily.getHfqClose(), daily.getHfqLow(), daily.getHfqHigh()));
|
slopes.add(((sma30.get(i) - sma30.get(i - 1)) * 1000.0) / sma30.get(i - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var xList = new ArrayList<String>();
|
||||||
|
var yList = new ArrayList<List<Double>>();
|
||||||
|
for (var daily : dailies) {
|
||||||
|
xList.add(daily.getTradeDate().toString());
|
||||||
|
yList.add(List.of(daily.getHfqOpen(), daily.getHfqClose(), daily.getHfqLow(), daily.getHfqHigh()));
|
||||||
|
}
|
||||||
|
|
||||||
|
charts.set(
|
||||||
|
code,
|
||||||
|
Dict.create()
|
||||||
|
.set("xList", xList)
|
||||||
|
.set("yList", yList)
|
||||||
|
.set("sma30", sma30)
|
||||||
|
.set("sma30Slopes", slopes)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
var template = engine.getTemplate("report.html");
|
var template = engine.getTemplate("report.html");
|
||||||
Files.writeString(Path.of("report.html"), template.render(
|
Files.writeString(Path.of("report.html"), template.render(
|
||||||
Dict.create().set(
|
Dict.create().set("charts", charts)
|
||||||
"charts",
|
|
||||||
Dict.create()
|
|
||||||
.set("日线数据", Map.of("xList", xList, "yList", yList))
|
|
||||||
)
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
body: {
|
body: {
|
||||||
className: 'mt-2',
|
className: 'mt-2',
|
||||||
type: 'chart',
|
type: 'chart',
|
||||||
height: 500,
|
height: 800,
|
||||||
config: {
|
config: {
|
||||||
title: {
|
title: {
|
||||||
text: title,
|
text: title,
|
||||||
@@ -103,6 +103,32 @@
|
|||||||
},
|
},
|
||||||
yAxis: [
|
yAxis: [
|
||||||
{
|
{
|
||||||
|
position: 'left',
|
||||||
|
scale: true,
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: '#e0e0e0',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
color: '#666',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
formatter: function (value) {
|
||||||
|
return value.toFixed(2)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
lineStyle: {
|
||||||
|
type: 'dashed',
|
||||||
|
color: '#f0f0f0',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
position: 'right',
|
||||||
scale: true,
|
scale: true,
|
||||||
axisLine: {
|
axisLine: {
|
||||||
lineStyle: {
|
lineStyle: {
|
||||||
@@ -169,6 +195,26 @@
|
|||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 0,
|
||||||
|
data: '${sma30 || []}',
|
||||||
|
smooth: true,
|
||||||
|
symbol: 'none',
|
||||||
|
lineStyle: {
|
||||||
|
color: 'rgba(0,111,255,0.5)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 1,
|
||||||
|
data: '${sma30Slopes || []}',
|
||||||
|
smooth: true,
|
||||||
|
symbol: 'none',
|
||||||
|
lineStyle: {
|
||||||
|
color: 'rgba(0,255,81,0.5)',
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user