每当我给训练营的同学讲解股票数据可视化时,常会先问一个问题:“开盘头30分钟,你们是想知道日K 收在哪里,还是想看清价格每一分钟是怎么跳动的?” 答案几乎都是后者。然而当大家兴致勃勃开始动手时,第一个绊脚石就出现了:数据源能输出分钟级序列吗?拿到的推送是连续的还是断断续续的?这一课,我们就以真实开发者的视角,把从实时行情到分时图的整个流程拆解开。
研究痛点:为什么拿到当天分时线并不像想象中简单
很多新手以为行情接口都天生支持分钟线,其实多数公开接口的免费档位只给日线或有限的历史分钟线,而且延迟较大。这就导致本地画出的日内走势常常带着“天窗”:某一分钟没成交,下一分钟又突然跳价,曲线变得难以信任。我们真正需要的是一个能推实时 tick,且允许我们本地定制聚合逻辑的数据链路。
数据需求:三步定好分时数据的骨架
在写第一行代码前,我建议先明确要把什么字段存下来:
- 分钟刻度时间:以
HH:MM作为对齐基准。 - 该分钟收盘价:用最后一笔成交近似,可避免盘中尖刺影响。
- 分钟成交量:若 tick 级别带量,就累加;否则用快照成交量差值计算。
如果接口不提供量,至少也要保证前两项,这样分时走势的主体就立住了。
AllTick API 的支持:以稳定推送作为数据底座
我在示范项目里采用 AllTick 的实时行情接口作为数据源,是因为它的 WebSocket 推送结构清晰,配合简单的订阅动作就能拿到 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 海洋中提炼出每分钟一个价格点
单靠上面那串消息还不够画图,因为 tick 每秒可能来好几个,分钟之间也有可能出现空档。我习惯用 pandas 来收拾这些时间序列数据:
import pandas as pd
df['time'] = pd.to_datetime(df['time'])
df.set_index('time', inplace=True)
# 每分钟取最后一笔价格,没有成交的分钟自动向前填充
df_1min = df['price'].resample('1min').last().ffill()
这样处理后,序列就变成以 1 分钟为步长的整齐数组,再也不会出现因无成交而产生的断裂。
从分钟数组到交互图表:用 Plotly 让走势“活”起来
有了规整的 df_1min,我通常选择 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()
配合成交量柱状图,就能在一个画布里同时观察价格运动方向与资金参与力度。
学术价值与应用延伸
分时数据的标准程度,直接影响着后续所有计量分析的准确性。不少金融工程课程中的日内动量策略回测、价差套利模拟,都以连续分钟价格为基础。换句话说,今天你亲手搭出的这条分钟数据链,其实也是未来做严谨量化研究的起点。把“每一分钟”这个基本功夯实,后面无论是做预警、做复盘还是做因子挖掘,都会从容得多。

随时随地看视频