feat: 简化交易计算
This commit is contained in:
@@ -33,6 +33,12 @@
|
||||
<artifactId>hutool-http</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.icepear.echarts</groupId>
|
||||
<artifactId>echarts-java</artifactId>
|
||||
<version>1.1.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.github.ralfkonrad.quantlib_for_maven</groupId>
|
||||
<artifactId>quantlib</artifactId>
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.lanyuanxiaoyao.leopard.core.repository.DailyRepository;
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -50,9 +51,6 @@ public class TradeEngine {
|
||||
.filter(daily -> daily.getTradeDate().isBefore(currentDate))
|
||||
.toList()
|
||||
);
|
||||
if (trade == 0) {
|
||||
continue;
|
||||
}
|
||||
var daily = dailies.stream()
|
||||
.filter(d -> ObjectUtil.equals(d.getTradeDate(), currentDate))
|
||||
.findFirst()
|
||||
@@ -75,20 +73,46 @@ public class TradeEngine {
|
||||
}
|
||||
|
||||
public int getVolume() {
|
||||
return getVolume(trade -> true);
|
||||
}
|
||||
|
||||
public int getVolume(LocalDate date) {
|
||||
return getVolume(trade -> trade.date().isBefore(date) || trade.date().isEqual(date));
|
||||
}
|
||||
|
||||
private int getVolume(Predicate<Trade> predicate) {
|
||||
return trades.stream()
|
||||
.filter(predicate)
|
||||
.mapToInt(Trade::volume)
|
||||
.sum();
|
||||
}
|
||||
|
||||
public double getCash() {
|
||||
return getCash(trade -> true);
|
||||
}
|
||||
|
||||
public double getCash(LocalDate date) {
|
||||
return getCash(trade -> trade.date().isBefore(date) || trade.date().isEqual(date));
|
||||
}
|
||||
|
||||
private double getCash(Predicate<Trade> predicate) {
|
||||
return trades.stream()
|
||||
.filter(predicate)
|
||||
.mapToDouble(trade -> -1 * trade.volume() * trade.price())
|
||||
.sum();
|
||||
}
|
||||
|
||||
public double getPrice() {
|
||||
int volume = getVolume();
|
||||
return volume == 0 ? 0 : getCash() / volume;
|
||||
return getPrice(trade -> true);
|
||||
}
|
||||
|
||||
public double getPrice(LocalDate date) {
|
||||
return getPrice(trade -> trade.date().isBefore(date) || trade.date().isEqual(date));
|
||||
}
|
||||
|
||||
public double getPrice(Predicate<Trade> predicate) {
|
||||
int volume = getVolume(predicate);
|
||||
return volume == 0 ? 0 : getCash(predicate) / volume;
|
||||
}
|
||||
|
||||
public record Trade(
|
||||
|
||||
@@ -65,7 +65,7 @@ public class StrategyApplication {
|
||||
var startDate = LocalDate.of(2024, 12, 1);
|
||||
var endDate = LocalDate.of(2024, 12, 31);
|
||||
var charts = new ArrayList<Dict>();
|
||||
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"*/)
|
||||
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"*/)
|
||||
.parallelStream()
|
||||
.forEach(code -> {
|
||||
var stock = stockRepository.findOne(QStock.stock.code.eq(code)).orElseThrow();
|
||||
@@ -112,6 +112,7 @@ public class StrategyApplication {
|
||||
charts.add(
|
||||
Dict.create()
|
||||
.set("title", code)
|
||||
.set("type", "candle")
|
||||
.set(
|
||||
"data",
|
||||
Dict.create()
|
||||
@@ -125,6 +126,7 @@ public class StrategyApplication {
|
||||
"points",
|
||||
asset.getTrades()
|
||||
.stream()
|
||||
.filter(trade -> trade.volume() != 0)
|
||||
.map(trade -> Dict.create()
|
||||
.set("value", trade.volume())
|
||||
.set("itemStyle", Dict.create()
|
||||
|
||||
@@ -397,6 +397,11 @@
|
||||
type: 'tabs',
|
||||
tabsMode: 'vertical',
|
||||
tabs: data.map(item => {
|
||||
let body = {}
|
||||
if (item?.type === 'candle') {
|
||||
body = Object.keys(item?.data ?? {})
|
||||
.map(key => candleChart(key, item.data[key]))
|
||||
}
|
||||
return {
|
||||
title: item?.title,
|
||||
body: Object.keys(item?.data ?? {})
|
||||
|
||||
Reference in New Issue
Block a user