我们在做港股量化策略时,发现很多信号失效并不是因为因子不好,而是因为底层行情数据的时间边界没有处理好。尤其是使用港股 api 获取实时行情时,开市前、午间休市、收市后这些时间段的数据,如果没有严格区分,会直接影响策略的回测和实盘表现。
一、研究痛点:数据时间与交易时间的混淆
我们团队在给专业交易者和基金公司开发部门做港股量化模块时,最常遇到的问题就是:早上 9:05 的数据被当成连续交易数据处理,导致策略在竞价阶段就触发了信号。还有一次,服务器跑在 UTC 时区,直接拿 datetime.now() 和香港时间比较,结果下午的数据判断全部错位。
这些问题的根源在于:我们把“数据时间”和“交易时间”混在一起了。
二、数据需求:先定义清楚港股交易时段
港股不是全天连续交易。我们通常把一天拆成几个区间:
| 时段 | 香港时间 | 程序处理 |
|---|---|---|
| 开市前竞价 | 09:00–09:30 | 预开市数据 |
| 上午交易 | 09:30–12:00 | 正常交易 |
| 午间休市 | 12:00–13:00 | 非连续交易 |
| 下午交易 | 13:00–16:00 | 正常交易 |
| 收市后 | 16:00 之后 | 非正常交易 |
一个常见的错误写法是:
if current_time >= time(9, 30):
market_open = True
这个写法没有限定结束时间,所以下午 17:00 也会被判断成开市。我们后来改成区间判断:
def is_market_open(t):
morning = time(9, 30) <= t < time(12, 0)
afternoon = time(13, 0) <= t < time(16, 0)
return morning or afternoon
三、支持:API 时间戳统一转换
港股 api 返回的时间戳通常是 Unix timestamp:
{
"symbol": "00700.HK",
"price": 520.5,
"timestamp": 1788226200
}
这个时间戳本身没有时区概念。我们必须转成带时区的 datetime:
from datetime import datetime
from zoneinfo import ZoneInfo
timestamp = 1788226200
dt = datetime.fromtimestamp(
timestamp,
tz=ZoneInfo("Asia/Hong_Kong")
)
print(dt)
这样即使服务器部署在不同时区,策略端的时间判断也是一致的。我们在接入 AllTick 的港股数据时,也会先统一转换到 Asia/Hong_Kong,确保数据质量稳定。
四、开市前数据不能参与策略信号
9:00 到 9:30 虽然已有行情,但市场还在竞价阶段,不能作为连续交易信号。我们使用状态区分:
def get_market_status(t):
if time(9, 0) <= t < time(9, 30):
return "pre_open"
if time(9, 30) <= t < time(12, 0):
return "morning"
if time(12, 0) <= t < time(13, 0):
return "break"
if time(13, 0) <= t < time(16, 0):
return "afternoon"
return "closed"
策略端可以只接受 morning 和 afternoon 的数据,避免竞价阶段的异常波动干扰信号。
五、跨日期和交易日历
午夜判断也容易出错。比如:
if current_time > time(16, 0):
status = "closed"
凌晨 1 点确实会被判断成收市后,但如果还要判断“当前交易日”,就不能只看 time。我们的经验是:时间段用 datetime.time,交易日用 datetime.date,分开维护。
香港公众假期和台风休市要独立维护交易日历,不能只按周一到周五判断。
六、K 线聚合的时间边界
做 1 分钟 K 线时,时间边界更严格。09:29:59 和 09:30:00 只差一秒,但属于不同的 K 线周期。我们使用左闭右开区间:
09:30:00 <= tick_time < 09:31:00
这样每条 tick 只会进入一个周期,避免重复统计。
七、学术价值:可扩展的行情处理流程
我们现在的行情处理流程是:
API实时数据
↓
解析 timestamp
↓
转换为 Asia/Hong_Kong
↓
判断交易日期
↓
判断交易时段
↓
过滤/分类行情
↓
K线聚合或策略计算
把交易时段、时区、交易日历做成独立配置,策略代码里不再出现 09:30、16:00 这类魔法数字。这样无论是回测还是实盘,数据质量都能得到保证。时间边界处理是量化策略的基础功,值得我们花时间做好。

