1
0

feat: 简化交易计算

This commit is contained in:
2025-11-07 23:08:56 +08:00
parent db8a094c8f
commit 7703f88d7f
2 changed files with 83 additions and 104 deletions

View File

@@ -1,7 +1,6 @@
package com.lanyuanxiaoyao.leopard.strategy;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.template.TemplateConfig;
import cn.hutool.extra.template.TemplateEngine;
@@ -71,33 +70,26 @@ public class StrategyApplication {
.forEach(code -> {
var stock = stockRepository.findOne(QStock.stock.code.eq(code)).orElseThrow();
var asset = tradeEngine.backtest(
List.of(stock.getId()),
stockRepository.findById(stock.getId()).orElseThrow(),
(now, currentAsset, dailies) -> {
return dailies.entrySet()
var stockDailies = dailies
.stream()
.map(entry -> {
var stockId = entry.getKey();
var stockDailies = entry.getValue()
.stream()
.sorted(Comparator.comparing(Daily::getTradeDate))
.toList();
var yesterday = stockDailies.getLast();
if (yesterday.getHfqClose() > yesterday.getHfqOpen()) {
log.info("{} Buy for price {} {}", now, yesterday.getHfqOpen(), yesterday.getHfqClose());
return new TradeEngine.Trade(now, stockId, 100);
} else if (yesterday.getHfqClose() < yesterday.getHfqOpen()) {
var hold = currentAsset.getStocks().getOrDefault(stockId, 0);
if (hold > 0) {
log.info("{} Sell for price {} {}", now, yesterday.getHfqOpen(), yesterday.getHfqClose());
return new TradeEngine.Trade(now, stockId, -1 * hold);
}
} else {
log.info("{} Hold for price {} {}", now, yesterday.getHfqOpen(), yesterday.getHfqClose());
}
return null;
})
.filter(ObjectUtil::isNotNull)
.sorted(Comparator.comparing(Daily::getTradeDate))
.toList();
var yesterday = stockDailies.getLast();
if (yesterday.getHfqClose() > yesterday.getHfqOpen()) {
log.info("{} Buy for price {} {}", now, yesterday.getHfqOpen(), yesterday.getHfqClose());
return 100;
} else if (yesterday.getHfqClose() < yesterday.getHfqOpen()) {
var hold = currentAsset.getVolume();
if (hold > 0) {
log.info("{} Sell for price {} {}", now, yesterday.getHfqOpen(), yesterday.getHfqClose());
return -1 * hold;
}
} else {
log.info("{} Hold for price {} {}", now, yesterday.getHfqOpen(), yesterday.getHfqClose());
}
return 0;
},
startDate,
endDate
@@ -121,37 +113,34 @@ public class StrategyApplication {
dailyYList.add(List.of(daily.getHfqOpen(), daily.getHfqClose(), daily.getHfqLow(), daily.getHfqHigh()));
dailyCloseMapping.put(daily.getTradeDate().toString(), daily.getHfqClose());
}
charts.add(Dict.create()
.set("title", code)
.set(
"data",
Dict.create()
.set(
"日线",
Dict.create()
.set("xList", dailyXList)
.set("yList", dailyYList)
.set(
"points",
asset.getHistories()
.stream()
.filter(history -> ObjectUtil.isNotEmpty(history.trades()))
.filter(history -> history.trades().containsKey(stock.getId()))
.filter(history -> ObjectUtil.isNotEmpty(history.trades().get(stock.getId())))
.map(history -> {
var trade = history.trades().get(stock.getId()).getFirst();
return Dict.create()
.set("value", trade.volume())
.set("itemStyle", Dict.create()
.set("color", trade.volume() > 0 ? "#e5b8b5" : "#b5e2e5")
)
.set("coord", List.of(history.date().toString(), dailyCloseMapping.getOrDefault(history.date().toString(), 0.0)));
}
)
.toList()
)
)
)
charts.add(
Dict.create()
.set("title", code)
.set(
"data",
Dict.create()
.set(
"日线",
Dict.create()
.set("xList", dailyXList)
.set("yList", dailyYList)
.set(
"points",
asset.getTrades()
.stream()
.map(trade -> {
return Dict.create()
.set("value", trade.volume())
.set("itemStyle", Dict.create()
.set("color", trade.volume() > 0 ? "#e5b8b5" : "#b5e2e5")
)
.set("coord", List.of(trade.date().toString(), dailyCloseMapping.getOrDefault(trade.date().toString(), 0.0)));
}
)
.toList()
)
)
)
);
/*log.info("Final Cash: {}", asset.getCash());
for (var history : asset.getHistories()) {