feat: add support for fetching recent trading day chart data and optimize caching for index retrieval

This commit is contained in:
2025-08-11 07:29:26 +08:00
parent f3dd600189
commit dd5eeede7d
3 changed files with 95 additions and 16 deletions

View File

@@ -1063,8 +1063,8 @@ public class StockService {
market.setRate(String.valueOf(stockIndex.getPercentChange()));
vo1.setIndexVo(market);
List<ChartCandle> kLines = HomeApiIndex.fetchChartData(stockIndex.getId(), 100);
// List kline = HomeApiIndex.convertToJsonList(kLines);
// 只获取最近交易日的K线数据智能跳过周末优化性能和网络传输
List<ChartCandle> kLines = HomeApiIndex.fetchTodayAndYesterdayChartData(stockIndex.getId());
vo1.setKLine(kLines);
indexVoList.add(vo1);
}

View File

@@ -9,12 +9,16 @@ import okhttp3.Response;
import org.json.JSONArray;
import org.json.JSONObject;
import java.time.DayOfWeek;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class HomeApiIndex {
private static final OkHttpClient client = new OkHttpClient();
@@ -80,7 +84,29 @@ public class HomeApiIndex {
return result;
}
/**
* 获取图表数据(原方法,保持向后兼容)
*/
public static List<ChartCandle> fetchChartData(String symbol, int amount) throws Exception {
return fetchChartDataWithDateFilter(symbol, amount, false);
}
/**
* 获取最近的交易日K线数据支持跨周末
* @param symbol 股票代码
* @return 最近交易日的K线数据
*/
public static List<ChartCandle> fetchTodayAndYesterdayChartData(String symbol) throws Exception {
return fetchChartDataWithDateFilter(symbol, 168, true); // 获取7天数据确保包含交易日
}
/**
* 获取图表数据,支持日期过滤
* @param symbol 股票代码
* @param amount 数据量
* @param filterRecentDays 是否只返回最近交易日的数据
*/
private static List<ChartCandle> fetchChartDataWithDateFilter(String symbol, int amount, boolean filterRecentDays) throws Exception {
List<ChartCandle> result = new ArrayList<>();
String url = BASE_URL + "?symbol=" + symbol + "&interval=H&amount=" + amount;
@@ -101,22 +127,72 @@ public class HomeApiIndex {
JSONObject json = new JSONObject(body);
JSONArray data = json.getJSONArray("data");
for (int i = 0; i < data.length(); i++) {
JSONObject obj = data.getJSONObject(i);
ChartCandle candle = new ChartCandle();
if (filterRecentDays) {
// 获取最近的交易日期
Set<LocalDate> recentTradingDays = getRecentTradingDays();
long ts = obj.optLong("time");
String formattedTime = convertToGermanTime(ts);
for (int i = 0; i < data.length(); i++) {
JSONObject obj = data.getJSONObject(i);
candle.setUpd_date(formattedTime);
candle.setPrice(getDoubleOrNull(obj, "close"));
long ts = obj.optLong("time");
ZonedDateTime zonedDateTime = Instant.ofEpochSecond(ts).atZone(ZoneId.of("Europe/Berlin"));
LocalDate dataDate = zonedDateTime.toLocalDate();
result.add(candle);
// 只保留最近交易日的数据
if (recentTradingDays.contains(dataDate)) {
ChartCandle candle = new ChartCandle();
String formattedTime = convertToGermanTime(ts);
candle.setUpd_date(formattedTime);
candle.setPrice(getDoubleOrNull(obj, "close"));
result.add(candle);
}
}
} else {
// 不过滤,返回所有数据
for (int i = 0; i < data.length(); i++) {
JSONObject obj = data.getJSONObject(i);
long ts = obj.optLong("time");
String formattedTime = convertToGermanTime(ts);
ChartCandle candle = new ChartCandle();
candle.setUpd_date(formattedTime);
candle.setPrice(getDoubleOrNull(obj, "close"));
result.add(candle);
}
}
return result;
}
/**
* 获取最近的交易日期(排除周末)
* @return 最近两个交易日的日期集合
*/
public static Set<LocalDate> getRecentTradingDays() {
Set<LocalDate> tradingDays = new HashSet<>();
ZoneId germanyZone = ZoneId.of("Europe/Berlin");
LocalDate current = LocalDate.now(germanyZone);
int foundDays = 0;
int daysBack = 0;
// 向前查找最近的两个交易日
while (foundDays < 2 && daysBack < 10) { // 最多向前查找10天
LocalDate checkDate = current.minusDays(daysBack);
// 排除周末(周六=6, 周日=7
if (checkDate.getDayOfWeek() != DayOfWeek.SATURDAY &&
checkDate.getDayOfWeek() != DayOfWeek.SUNDAY) {
tradingDays.add(checkDate);
foundDays++;
}
daysBack++;
}
return tradingDays;
}
// public static List<JSONObject> convertToJsonList(List<ChartCandle> candles) {
// List<JSONObject> result = new ArrayList<>();
//

View File

@@ -244,15 +244,18 @@ public class StockApiController {
}
@RequestMapping({"getIndiaIndexByToday.do"})
@ApiOperation(value = "印度--获取指定指数信息", httpMethod = "GET")
@ApiOperation(value = "德国--获取指定指数信息最近交易日K线", httpMethod = "GET")
@ResponseBody
public ServerResponse getIndiaIndexByToday() {
String INDEX_CODE = "TODAY_INDEX";
return RequestCacheUtils.cache("getIndiaIndexByToday.do", INDEX_CODE,6000, (string) -> {
// 优化缓存时间为15秒平衡数据实时性和系统性能
// 由于只返回最近交易日数据,可以适当延长缓存时间
return RequestCacheUtils.cache("getIndiaIndexByToday.do", INDEX_CODE, 15000, (string) -> {
try {
return this.stockService.getIndexByBtoday();
} catch (Exception e) {
throw new RuntimeException(e);
log.error("获取德国指数数据失败: {}", e.getMessage(), e);
throw new RuntimeException("获取指数数据失败: " + e.getMessage(), e);
}
});
}