feat: 增加简单回测
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
package com.lanyuanxiaoyao.leopard.strategy;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.lanyuanxiaoyao.leopard.core.entity.Daily;
|
||||
import com.lanyuanxiaoyao.leopard.core.entity.QStock;
|
||||
import com.lanyuanxiaoyao.leopard.core.repository.DailyRepository;
|
||||
import com.lanyuanxiaoyao.leopard.core.repository.StockRepository;
|
||||
@@ -9,10 +11,14 @@ import com.lanyuanxiaoyao.leopard.core.service.AssessmentService;
|
||||
import com.lanyuanxiaoyao.leopard.core.service.StockService;
|
||||
import com.lanyuanxiaoyao.leopard.core.service.TuShareService;
|
||||
import com.lanyuanxiaoyao.leopard.core.service.selector.PyramidStockSelector;
|
||||
import com.lanyuanxiaoyao.leopard.core.strategy.TradeEngine;
|
||||
import jakarta.annotation.Resource;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
@@ -39,6 +45,8 @@ public class StrategyApplication {
|
||||
private StockRepository stockRepository;
|
||||
@Resource
|
||||
private StockService stockService;
|
||||
@Resource
|
||||
private TradeEngine tradeEngine;
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(StrategyApplication.class, args);
|
||||
@@ -279,9 +287,41 @@ public class StrategyApplication {
|
||||
@EventListener(ApplicationReadyEvent.class)
|
||||
public void test() {
|
||||
var stock = stockRepository.findOne(QStock.stock.code.eq("000001.SZ")).orElseThrow();
|
||||
var weeklies = stockService.findWeeklyRecent(stock.getId(), 2);
|
||||
for (var weekly : weeklies) {
|
||||
log.info("{}", weekly);
|
||||
var asset = tradeEngine.backtest(
|
||||
List.of(stock.getId()),
|
||||
(now, currentAsset, dailies) -> {
|
||||
return dailies.entrySet()
|
||||
.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)
|
||||
.toList();
|
||||
},
|
||||
LocalDate.of(2024, 12, 1),
|
||||
LocalDate.of(2024, 12, 31)
|
||||
);
|
||||
log.info("Final Cash: {}", asset.getCash());
|
||||
for (var history : asset.getHistories()) {
|
||||
log.info("Date: {} Cash: {} Trade: {}", history.date(), history.cash(), history.trades().values());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user