港股拟延长交易:TradingView做跨市场行情App,K线为何差一天
TickDB Research ·
用 TradingView 开源的 Lightweight Charts 画腾讯10月14日的日K,图上显示的是10月13日。图表库没错,数据也没错,错在喂数据的那一步。我用真实行情把同一组数据喂了两遍,挑出跨市场K线最容易画错的10个地方,文末附一段能直接复制的喂数代码。
10月9日,香港证监会透露,香港正在研究延长证券交易时段,港交所第四季度会就现货市场延时发讨论文件。再过两周多,11月1日,美股换冬令时,北京时间开盘从21:30推迟到22:30。
交易时间要变了。做行情App的人该先问自己一句:K线的时间轴是写死的还是算出来的?
我先拿腾讯试了一下。用 TradingView 开源的 Lightweight Charts 画日K,接口返回的数据原样喂进去:

10月14日的K线,图上写着13日,整条时间轴都早了一天。
做单一市场,这类错一两处;做A股、港股、美股一起的跨市场App,它们会一起冒出来。
图表库只负责画,画得对不对取决于你怎么喂数据。
读完你能带走:10个最常见的画错点和修法,一段约50行的喂数代码,一张上线前体检表。
一、图表库只管画,不懂行情
Lightweight Charts 免费、轻量,几十行代码就能画出专业样式的K线,很多行情App和交易工具都在用。
但它不知道你的时间戳属于哪个市场,不知道国内习惯红涨绿跌,不知道这只股票上个月除过权,也不知道A股成交量的“1”是一手。这些都得在数据进图表之前处理好,我把这一步叫“喂数层”。
下面每一条都是同一组真实数据喂两遍的对比:一遍原样喂,一遍先过喂数层。
二、首页对比图
① 腾讯10月14日的K线,标成了13日
行情接口的日K时间戳,通常标在交易所当地零点。腾讯10月14日这根是北京时间14日0点,换成 UTC 是13日16点。图表库只按 UTC 显示时间,所以标成13日。用户电脑设成北京时间也没用。
用户截图发群里一句“你们日期都错了”,比什么 bug 报告都伤口碑。
修法:日K别喂时间戳,换成当地日期字符串 '2026-10-14' 再喂。
② 三个市场放进一张图,同一天对不上
腾讯标在北京零点,苹果标在纽约零点,比特币标在 UTC 零点。放在同一条时间轴上,“10月14日”变成了三个点,腾讯那根还掉进了13日。

分钟K也一样。我取的15分钟K里,寒武纪第一根标09:45,腾讯第一根标09:30:A股标的是结束时刻,港股标的是开始时刻。两边各有一根“09:45”,管的是相邻的两段。
做联动分析、相关性、配对交易,最怕的就是这种错位。
修法:每个市场先换成各自的当地交易日,再对齐。另外得有人拍板:美股10月14日那一场在北京是14日晚上到15日凌晨,你的首页算它哪一天?
三、个股K线
③ 涨是绿的,跌是红的
图表库默认绿涨红跌,这是欧美习惯。国内用户第一眼就会看反。
修法:按用户地区设涨跌色,K线和成交量柱一起改。
④ 寒武纪除权那天,像是暴跌了36.7%
5月8日是寒武纪除权日。前一天收盘1,868元,当天收盘1,182.53元,不复权的图上断开一个大缺口。

前复权后,前一天收盘折算成1,252.68元,当天其实只跌了5.6%。不复权的话,均线、指标在这里都会失真,按涨跌幅设的提醒也会误报。
修法:看图用前复权。做回测记下复权方式,因为每次新的除权都会让前复权的历史价格整体变一次。
⑤ 汇率6.69916,图上只剩6.70
图表库默认保留2位小数,股票够用,汇率不够。汇率一天的波动常在千分位,两位小数什么都看不出来。
修法:按品种设小数位,外汇5位,股票2位,低价港股3位。
四、盘中分时
⑥ A股分时图从凌晨01:45开始
还是 UTC 显示的问题,到了分时图上更扎眼:09:45显示成01:45,15:00显示成07:00。

修法:用图表库的时间格式化选项,按交易所时区名显示:A股 Asia/Shanghai,美股 America/New_York。别写“加8小时”。
⑦ 11月以后,美股时间错一小时
很多代码里写死了“美东加12小时就是北京时间”。夏令时是对的,11月1日以后要加13小时。

写死的话,开盘、收盘、“交易中”的判断全部早一小时。港股如果真延长交易时段,所有写死“16:00收盘”的地方也得改。
修法:时区换算用时区名,夏令时交给系统处理。交易时段从接口读,别写死在代码里,交易所改时间你也不用发版。
⑧ 最后一根K线,看着像缩量六成
北京时间23:33打开苹果日K,最新一根成交量1,482万股,前一天3,898万股。其实是这根还没收盘,当天才交易了两个小时。

“放量缩量”、均线信号、价格提醒,都会被这根半成品带偏。拿它算策略信号,回测里看不出问题,实盘才出事。
修法:最后一根单独标“未完成”,颜色画浅一点;更新它用 series.update();指标和提醒只用已收盘的K线。
五、成交量和上线当天
⑨ 寒武纪的量柱,只有腾讯的1/270
10月14日,寒武纪成交量73,781,单位是手;腾讯19,933,548,单位是股。直接画在一起,寒武纪的柱子几乎看不见。乘100换成股,是738万股,约为腾讯的37%。
修法:A股成交量乘100换成股。跨市场比活跃度,用成交额更稳。
⑩ 日期跑到58709年,或者整张图白屏
这是上线当天最常见的两种“图没了”:
- 毫秒没转秒:接口时间戳一般是毫秒,图表库要秒。毫秒直接喂进去不报错,横轴写着“58709年”,所有K线挤在一角。
- 没按时间排序:图表库要求数据严格升序、不能重复。顺序一乱,整张图白屏,生产环境只报一句
Value is null,很难查。
顺带一个合规提醒:图表左下角那个小 logo 是开源许可要求的署名。嫌碍眼关掉的话,记得在页面别处补上 TradingView 的署名和链接。
修法:毫秒转秒、升序排序、去掉重复时间,三件事都放进喂数层。
六、上线前体检表
| # | 用户看到的 | 修法 |
|---|---|---|
| ① | 日K日期早一天 | 日K换成当地日期字符串 |
| ② | 三个市场同一天对不上 | 先换成各自交易日再对齐 |
| ③ | 涨跌颜色反了 | 按用户地区设颜色 |
| ④ | 除权日像暴跌 | 看图用前复权 |
| ⑤ | 汇率只剩两位小数 | 按品种设小数位 |
| ⑥ | 分时从01:45开始 | 按交易所时区名显示 |
| ⑦ | 冬令时后错一小时 | 时区名换算,时段从接口读 |
| ⑧ | 最后一根像缩量 | 标记未完成,不进指标 |
| ⑨ | A股量柱矮100倍 | 乘100换成股,或用成交额 |
| ⑩ | 58709年、白屏 | 毫秒转秒、升序去重、保留署名 |
七、怎么做:一个喂数层
10条修法都落在同一个地方:数据进图表之前。别在每个页面各修各的,写一个喂数层,所有K线都从这里过。
喂数层代码
这段代码用本文的真实数据在 Lightweight Charts 5.2.1 里跑通过:
// feed.js:K线数据进图表之前,统一过这一层
const TZ = { CN: 'Asia/Shanghai', HK: 'Asia/Hong_Kong', US: 'America/New_York', CRYPTO: 'UTC', FX: 'UTC' };
const LOT = { CN: 100, HK: 1, US: 1, CRYPTO: 1, FX: 1 }; // A股成交量按手,乘100换成股
const DIGI = { CN: 2, HK: 2, US: 2, CRYPTO: 2, FX: 5 }; // 价格小数位,低价港股、个别品种单独覆盖
const dayOf = (ms, tz) => // 交易所当地日期 'YYYY-MM-DD'
new Intl.DateTimeFormat('en-CA', { timeZone: tz, year: 'numeric', month: '2-digit', day: '2-digit' })
.format(new Date(ms));
function normalize(klines, { market, interval, lastIsForming = false }) {
const tz = TZ[market];
const daily = /^(1d|1w|1M)$/.test(interval);
const rows = klines
.map(k => ({ ms: Number(k.time), o: +k.open, h: +k.high, l: +k.low, c: +k.close,
v: +k.volume * LOT[market], amt: k.quote_volume == null ? null : +k.quote_volume }))
.filter(r => Number.isFinite(r.ms) && Number.isFinite(r.c))
.sort((a, b) => a.ms - b.ms); // 不假设接口返回顺序
const out = [];
for (const r of rows) {
const time = daily ? dayOf(r.ms, tz) : Math.floor(r.ms / 1000); // 日K用日期,分钟K用秒
const bar = { time, open: r.o, high: r.h, low: r.l, close: r.c, volume: r.v, amount: r.amt };
if (out.length && out[out.length - 1].time === time) out[out.length - 1] = bar; // 重复时间保留后到的
else out.push(bar);
}
if (lastIsForming && out.length) out[out.length - 1].forming = true; // 未收盘,指标和提醒不用它
return out;
}
function chartOptions(market) {
const tz = TZ[market];
const hm = new Intl.DateTimeFormat('zh-CN', { timeZone: tz, hour: '2-digit', minute: '2-digit', hourCycle: 'h23' });
const ymd = new Intl.DateTimeFormat('zh-CN', { timeZone: tz, year: 'numeric', month: '2-digit', day: '2-digit' });
const fmt = t => typeof t === 'number' ? `${ymd.format(new Date(t * 1000))} ${hm.format(new Date(t * 1000))}` : t;
return {
layout: { attributionLogo: true }, // 保留署名,或在页面别处放 NOTICE 和链接
localization: { timeFormatter: fmt },
timeScale: { timeVisible: true,
tickMarkFormatter: t => typeof t === 'number' ? hm.format(new Date(t * 1000)) : null },
};
}
function seriesStyle(market, region = 'CN') {
const [up, down] = region === 'CN' ? ['#e5484d', '#16a34a'] : ['#16a34a', '#e5484d'];
const d = DIGI[market];
return { upColor: up, downColor: down, wickUpColor: up, wickDownColor: down, borderVisible: false,
priceFormat: { type: 'price', precision: d, minMove: 10 ** -d } };
}
function safeUpdate(series, bar) { // 推送乱序时,旧K线不回写
const last = series.data().at(-1);
if (last && bar.time < last.time) return; // 日期字符串和秒数都能直接比大小
series.update(bar);
}
用法:
// resp:后端转发的K线接口返回,API Key 留在后端
const bars = normalize(resp.data.klines, { market: 'CN', interval: '1d', lastIsForming: true });
const chart = LightweightCharts.createChart(el, chartOptions('CN'));
const candles = chart.addSeries(LightweightCharts.CandlestickSeries, seriesStyle('CN'));
candles.setData(bars);
跨市场,最好只接一套接口
喂数层要按市场分支,这躲不掉,A股按手、港股按股是市场规则。但按数据源分支是可以躲掉的。如果A股、港股、美股、加密、外汇各接一家,每一家的时间戳格式、字段名、复权参数都要单独写一套转换,哪家一升级就可能出错。
TickDB 为开发者和 AI 应用提供统一的全球行情数据接口,让团队通过一套接入获取多市场实时与历史数据,更快构建行情、分析和监控产品。
本文的实验数据都来自 TickDB 的K线接口,和喂数层直接相关的有三点:
- A股、港股、美股、外汇、加密资产的K线是同一组字段,喂数层只需要按市场分支;
- 股票K线用
adjust一个参数切换不复权、前复权、后复权; - 交易时段有单独的接口,按市场返回当地时段,开收盘时间不用写死。
最后
打开你们的K线页面,把光标停在最新一根上,看看日期是不是今天;再找一只最近除过权的股票,看看除权那天。两分钟就能知道,第①④条你们中了没有。
港股延时还在讨论,美股冬令时还有两周多。交易时间会变,复权因子会变,这些变化都放在喂数层里处理,别散落在每一张图里。
参考资料
- 21世纪经济报道,[香港证监会:将就延长交易时段发讨论文件],2026-10-10
- 每日经济新闻,[港交所将就延长交易时段发表讨论文件],2026-10-12
- TradingHours.com,[Nasdaq Trading Hours]
- TradingView,[Lightweight Charts™ version 5]