
先把话挑明:K 线不是“画出来”的,而是“算出来”的。它是对一段时间内价格与成交的压缩表示:Open、High、Low、Close、Volume(常加 Turnover、交易笔数),按某种“窗口”聚合而成。听起来像个普通的聚合任务,但真要把它在交易系统里做稳、做快、做准,会踩很多坑。
解决思路:
java.time 下的 ZonedDateTime 并固定为交易所时区,禁止用系统默认时区。sessionId(如 20250809-Night)做键的一部分。解决思路:
symbol(甚至 symbol+venue)哈希,保证单分区内顺序;同一 symbol 聚合必须单线程。tradeId/matchNumber),每个活跃窗口挂一个 LRU Set 或 BloomFilter,窗口关了再销毁。解决思路:
BigDecimal 慢,double 有误差,long 容易溢出,turnover(成交额)乘合约乘数后尤甚。解决思路:
long 存(如价格按最小价位或 1e4 缩放),只在边界 I/O 处做格式化。BigDecimal,但复用对象与避免频繁创建),或分币种分桶存 long 后离线汇总。tickSize、priceScale、lot、multiplier、currency。解决思路:
max(high)、min(low)、开=首根 open、收=末根 close、量/额累加”的严格规则,避免误差。解决思路:
adjPrice = raw * factor(t) / factor(now)。解决思路:
BigDecimal 运算,批量落盘,内存对齐。解决思路:
数据模型(long 代表已整数化的价格与量):
CandleKey: symbol, interval, sessionId, windowStartCandleState: open, high, low, close, volume, turnover, tradeCount, version核心流程:
symbol 分区、单线程消费)非常小的一段 Java 伪代码(仅示意,真实实现要更多边界判断)
class Candle {
long open = Long.MIN\_VALUE;
long high = Long.MIN\_VALUE;
long low = Long.MAX\_VALUE;
long close = Long.MIN\_VALUE;
long volume;
long turnover;
int trades;
void applyTrade(long px, long qty) {
if (open == Long.MIN_VALUE) open = px;
if (px > high) high = px;
if (px < low) low = px;
close = px;
volume += qty;
turnover += px * qty; // 注意溢出与缩放
trades++;
}
boolean isEmpty() {
return open == Long.MIN_VALUE;
}
}
class Aggregator {
final Map map = new HashMap<>();
void onTrade(Trade t) {
CandleKey key = calendar.locateWindow(t.symbol, t.exchangeTime, t.session);
Candle c = map.computeIfAbsent(key, k -> new Candle());
if (t.isCancelOrCorrect()) {
// 查找原事件并回滚/重算(需要事件日志)
return;
}
c.applyTrade(t.price, t.qty);
}
void onTickBoundary(Instant now) {
// 找到到期的窗口,封口输出,落盘并清理
}
}symbol 分区,消费端单线程聚合。tradeId 集合;全局 Bloom 限制内存。symbol+date 分区;历史修正以 upsert。LongOpenHashSet 做去重;少用 BigDecimal,必要处汇总线程集中转换。K 线是“低级需求,高级实现”。从产品视角它只是几根柱子,从工程视角它是时间、数据质量、并发与业务规则的交叉地带。真正难的不是把 open/high/low/close 算出来,而是:
如果你正准备做这件事,先把时区、交易日历、事件顺序、去重与修正理顺,再谈性能优化;这样第二天早上看监控的时候,心里会更踏实。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。