第三章:事件序列可视化——用Matplotlib绘制事件序列图与K线图叠加事件标记
可视化这件事,在量化交易里有多重要?
我个人的体会是:你跑完一百个回测,看了一千个数字,都不如一张图来得直观。尤其是事件序列模式识别,你光看时间戳和价格变动,脑子很容易宕机。但把事件标在K线图上,一眼就能看出规律——嗯,这里出信号了,那里是假突破。
这一章,我们就来搞定两件事:
- 第一,画出事件序列图,看看事件在时间轴上的分布
- 第二,把事件标记叠加到K线图上,让模式和价格走势对应起来
说白了,就是让数据「开口说话」。
3.1 事件序列图:先看看事件长什么样
事件序列图,本质上就是一个时间轴上的散点图或柱状图。每个点代表一个事件发生的时间点,纵轴可以是事件类型、事件强度,或者干脆就是0/1标记。
我刚开始做事件驱动策略时,第一件事就是把所有事件按时间画出来。为什么?因为你会发现很多「看起来很美」的策略,事件分布其实稀稀拉拉,根本撑不起交易频率。
核心思路:
- 横轴:时间(datetime)
- 纵轴:事件类型(用不同颜色或y轴位置区分)
- 标记:每个事件用一个点或竖线表示
来看一个简单的例子。假设我们有一组事件数据:
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
# 模拟事件数据
np.random.seed(42)
dates = pd.date_range('2024-01-01', periods=100, freq='D')
events = pd.DataFrame({
'date': dates,
'event_type': np.random.choice(['买入信号', '卖出信号', '新闻冲击', '异常波动'], size=100),
'strength': np.random.rand(100) * 10
})
# 绘制事件序列图
fig, ax = plt.subplots(figsize=(12, 5))
# 用不同颜色区分事件类型
colors = {'买入信号': 'green', '卖出信号': 'red', '新闻冲击': 'orange', '异常波动': 'purple'}
for etype, group in events.groupby('event_type'):
ax.scatter(group['date'], [etype]*len(group),
color=colors[etype], label=etype, s=group['strength']*20, alpha=0.6)
ax.set_xlabel('时间')
ax.set_ylabel('事件类型')
ax.set_title('事件序列分布图')
ax.legend()
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()
这段代码里,我用散点图把事件按类型分布在纵轴上。点的大小代表事件强度——你想想看,如果某个时间段突然出现一堆大圆点,那肯定是有情况。
我的小技巧: 事件序列图最好配合「事件密度图」一起看。用直方图统计每天/每小时的事件数量,能快速发现事件聚集的时段。我曾经在分析某只股票的新闻事件时,发现大部分事件都集中在开盘后半小时内——后来才知道,那是机构集中发布公告的时间窗口。
3.2 K线图叠加事件标记:这才是实战利器
事件序列图只能看事件本身,但做交易的人更关心的是:事件发生时,价格在干什么?
所以,把事件标记直接画在K线图上,就成了最直观的分析方式。你一眼就能看到:
- 这个买入信号出现时,K线是什么形态?
- 那个新闻冲击之后,价格是涨了还是跌了?
- 异常波动事件是不是总出现在大阴线之后?
嗯,这才是模式识别的起点。
3.3 用mplfinance画带事件的K线图
Python里画K线图,我个人最推荐 mplfinance 这个库。它封装得很好,而且支持自定义标记叠加。
先安装:
pip install mplfinance
然后看代码:
import mplfinance as mpf
import pandas as pd
import numpy as np
# 模拟K线数据
np.random.seed(42)
dates = pd.date_range('2024-01-01', periods=200, freq='D')
price = 100 + np.cumsum(np.random.randn(200) * 0.5)
df = pd.DataFrame({
'Open': price + np.random.randn(200) * 0.2,
'High': price + np.abs(np.random.randn(200)) * 0.5,
'Low': price - np.abs(np.random.randn(200)) * 0.5,
'Close': price + np.random.randn(200) * 0.3,
'Volume': np.random.randint(1000, 10000, 200)
}, index=dates)
# 模拟事件标记
event_dates = dates[np.random.choice(range(200), size=15, replace=False)]
event_types = np.random.choice(['买入', '卖出', '新闻'], size=15)
# 准备标记数据
markers = []
for d, t in zip(event_dates, event_types):
if t == '买入':
markers.append(mpf.make_addplot(df.loc[d:d], type='scatter',
markersize=100, marker='^', color='green'))
elif t == '卖出':
markers.append(mpf.make_addplot(df.loc[d:d], type='scatter',
markersize=100, marker='v', color='red'))
else:
markers.append(mpf.make_addplot(df.loc[d:d], type='scatter',
markersize=80, marker='o', color='orange'))
# 绘制K线图叠加事件
mpf.plot(df, type='candle', volume=True,
addplot=markers,
title='K线图叠加事件标记',
style='charles',
figsize=(14, 8))
关键点说明:
make_addplot用来创建叠加图层,可以指定散点、线条、柱状图等- 用不同形状和颜色区分事件类型:绿色三角(买入)、红色倒三角(卖出)、橙色圆点(新闻)
markersize控制标记大小,可以根据事件强度动态调整
为什么我用三角和倒三角?因为买入信号向上,卖出信号向下,视觉上非常直觉。你想想看,如果都用圆点,那还得看颜色才能区分,多费劲。
避坑指南: 我曾经在叠加事件标记时,直接把所有事件都画上去,结果K线图密密麻麻全是点,根本看不清价格走势。后来我学乖了——只标记「高置信度」的事件,或者只显示最近N个事件。记住:可视化是为了看清模式,不是为了展示所有数据。
3.4 进阶:事件时间轴与K线图的联动
有时候,光在K线上标点还不够。比如你想看事件发生前后N根K线的价格行为——这就是事件驱动分析的核心。
我常用的做法是:
- 在K线图下方画一个事件时间轴子图
- 用竖线或色带标记事件发生的区间
- 在事件前后用不同背景色高亮
来看一个实现:
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(14, 8),
gridspec_kw={'height_ratios': [3, 1]})
# 上子图:K线图
mpf.plot(df, type='candle', ax=ax1, volume=False,
style='charles', show_nontrading=False)
# 下子图:事件时间轴
for d, t in zip(event_dates, event_types):
color = 'green' if t == '买入' else 'red' if t == '卖出' else 'orange'
ax2.axvline(x=d, color=color, linestyle='--', alpha=0.7, linewidth=1)
ax2.text(d, 0.5, t, rotation=90, fontsize=8, color=color)
ax2.set_ylim(0, 1)
ax2.set_yticks([])
ax2.set_xlabel('时间')
ax2.set_title('事件时间轴')
plt.tight_layout()
plt.show()
这样上下对照着看,效果非常好。上面是价格走势,下面是事件分布,一眼就能看出事件和价格之间的因果关系。
3.5 本章知识体系
下面这张图,是我自己总结的事件序列可视化核心逻辑,你可以把它当作一个检查清单:
3.6 一些实战经验
最后,分享几个我在项目中踩过的坑和总结的经验:
- 事件过滤很重要:别把所有事件都画上去。我一般会设置一个「置信度阈值」,只标记置信度高于0.7的事件。否则图上一团乱麻,什么都看不出来。
- 颜色要克制:最多用4-5种颜色,再多就分不清了。红绿蓝橙黄,基本够用。
- 交互式探索更高效:静态图只能看个大概。我建议用
plotly或bokeh做交互式图表,鼠标悬停能看到事件详情。这个我们后面章节会专门讲。 - 注意时间对齐:事件时间戳和K线时间戳必须精确对齐。我曾经因为时区问题,事件标记全部偏移了一天,查了半天才发现。
一个小技巧: 如果你的事件很多,可以试试「事件热力图」——把事件密度用颜色映射到K线图上,颜色越深代表事件越密集。这样既能保留K线信息,又能看到事件聚集区域。
好了,这一章的内容就到这里。可视化这件事,说白了就是「把数据变成故事」。你画得越清楚,模式就越容易浮现出来。下一章我们会进入更核心的部分——如何用机器学习自动识别这些事件模式。
公众号:蓝海数据掘金营,微信deep3321