量化策略中不可忽视的分时数据:从实时采集到分钟线合成的全链路

用户头像sh_****559rtx
2026-06-09 发布

我做日内策略回测时,吃过最大的亏不是因子失效,而是实盘与回测之间那一点点数据精度的差异。很多策略在 1 分钟频率上信号非常依赖开盘后价格的变化节奏,一旦分时线出现空缺或填充错误,整个入场逻辑就会偏移。因此,对于量化爱好者而言,自建一套可控的分钟级数据采集与聚合流程,是让策略从拟合走向稳健的必修课。

研究痛点:回测分钟线与实盘分时图的两张皮

在多数量化平台上,分钟线数据是经过服务端预先切片然后吐出来的,表面上看省事,实际上暗藏两个陷阱:一是切片时区与本地不一致,可能出现分钟边界错位;二是某些低活跃度时段服务端直接忽略,造成分钟序列缺失,而我们做因子计算时又极度依赖序列的连续性。结果就是回测很美,实盘信号却频频错乱。

数据需求:量化策略对分钟切片的结构要求

做日内因子,我要求每一条分钟切片必须包含:

  • 分钟时间标记:务必为本地交易时间,且严格对齐。
  • 成交价格:用该分钟最后一笔成交价作为“分钟收盘价”。
  • 成交量:若数据源提供累加 tick,可以算出分钟内的攻击量;若提供快照量,则做差值。

有了这个结构,再加上价格,就可以构建最简单的量价因子,如分钟涨速、量比等。

AllTick API 的支持:将控制权收回本地

为了避免被服务端切片“二次加工”干扰,我直接接入 AllTick 的实时 tick 推送,在本地完成所有聚合逻辑。这样无论是夏令时切换还是分钟边界的定义,都由我的策略代码完全掌握。

import websocket
import json

def on_message(ws, message):
    data = json.loads(message)
    # 接收实时 tick 数据,准备本地聚合
    print(f"时间: {data['time']}, 价格: {data['price']}, 成交量: {data['volume']}")

def on_open(ws):
    subscribe_data = {
        "action": "subscribe",
        "symbol": "AAPL"
    }
    ws.send(json.dumps(subscribe_data))

ws = websocket.WebSocketApp(
    "wss://api.alltick.co/stock",
    on_message=on_message,
    on_open=on_open
)

ws.run_forever()

分钟聚合:从 tick 海洋中提炼标准分钟线

数据到手后,我用 pandasresample 进行 1 分钟重采样,并对无成交时段做前向填充,保证序列不中断:

import pandas as pd

df['time'] = pd.to_datetime(df['time'])
df.set_index('time', inplace=True)

# 按1分钟窗口聚合,取价格最后值,成交量可另行累加
df_1min = df['price'].resample('1min').last().ffill()

可视化与策略信号叠加

分钟序列标准化之后,我通常会用 plotly 绘制分时走势,同时将策略的开平仓信号标记在图上,便于复盘:

import plotly.graph_objects as go

fig = go.Figure()
fig.add_trace(
    go.Scatter(
        x=df_1min.index,
        y=df_1min.values,
        mode='lines',
        name='价格'
    )
)
fig.show()

学术价值:高频分钟数据是量化研究的基石

在量化金融学术领域,分钟级价格序列常被用来测试 日内动量效应、流动性成本以及市场反应速度 等假说。一个未被污染的连续分钟数据集,能显著提升统计检验的效力。对于社区里希望深入研究的同仁来说,先把这条从实时数据到标准分钟线的管道建好,后续的因子挖掘与模型训练才会站在坚实的地基上。

ad29521c3a38f1851283e90754732438.jpg

评论