第四章:金融数据可视化——让数字开口说话

做量化交易这些年,我越来越觉得:数据可视化不是锦上添花,而是基本功。你想想看,面对几万行价格数据,光看数字能看出趋势吗?能发现异常吗?很难。但一张K线图,一眼就能告诉你市场在发生什么。

这一章,我们就来搞定金融数据可视化。从最基础的Matplotlib绘图,到专业的K线图、移动平均线叠加,再到多子图布局和交互式图表。嗯,内容不少,但都很实用。

本章核心知识点

  • Matplotlib基础绘图:折线图、柱状图、散点图
  • K线图绘制:从零手写K线图
  • 移动平均线叠加:技术指标可视化
  • 多子图布局:一图胜千言
  • 交互式图表:让图表动起来
金融数据可视化 Matplotlib基础绘图 K线图绘制 移动平均线叠加 多子图布局 交互式图表 折线图 柱状图 散点图 蜡烛图 交互缩放

4.1 Matplotlib基础绘图——先跑起来再说

Matplotlib是Python可视化的老大哥。虽然现在有seaborn、plotly这些新秀,但Matplotlib依然是金融绘图的基石。我个人习惯先用Matplotlib快速出图,再考虑要不要美化。

先看一个最简单的折线图:

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

# 生成模拟数据
dates = pd.date_range('2024-01-01', periods=100, freq='D')
prices = 100 + np.cumsum(np.random.randn(100) * 0.5)

# 基础折线图
plt.figure(figsize=(12, 6))
plt.plot(dates, prices, color='#2196F3', linewidth=1.5)
plt.title('股票价格走势', fontsize=14)
plt.xlabel('日期')
plt.ylabel('价格')
plt.grid(True, alpha=0.3)
plt.show()

💡 我的小习惯:设置figsize=(12, 6)是金融图的标准尺寸。太小的图看不清细节,太大的图又占地方。另外,网格线透明度设成0.3,既能看到参考线,又不喧宾夺主。

柱状图在金融里也很常用,比如展示每日收益率:

# 计算日收益率
returns = prices.pct_change() * 100

# 柱状图
plt.figure(figsize=(12, 6))
colors = ['#4CAF50' if r >= 0 else '#F44336' for r in returns]
plt.bar(dates, returns, color=colors, width=0.8)
plt.title('日收益率分布', fontsize=14)
plt.xlabel('日期')
plt.ylabel('收益率(%)')
plt.axhline(y=0, color='black', linewidth=0.8)
plt.show()

这里用红绿区分涨跌,是金融图的标准配色。涨用绿色,跌用红色——嗯,这是中国市场的习惯。美股那边正好相反,红色涨绿色跌,刚入行时我经常搞混。

4.2 K线图绘制——金融人的"母语"

K线图,说白了就是价格的四维信息:开盘价、收盘价、最高价、最低价。一根K线告诉你一天(或一个周期)的博弈结果。

Matplotlib没有内置的K线图函数,但我们可以用matplotlib.patches.Rectangleplt.plot自己画。不过,更省事的方式是用mplfinance库:

import mplfinance as mpf

# 准备数据:需要包含Open, High, Low, Close四列
data = pd.DataFrame({
    'Open': [100, 102, 101, 103, 105],
    'High': [105, 104, 103, 107, 108],
    'Low':  [98,  100, 99,  102, 104],
    'Close':[102, 101, 103, 106, 107]
}, index=pd.date_range('2024-01-01', periods=5, freq='D'))

# 绘制K线图
mpf.plot(data, type='candle', style='charles',
         title='K线图示例', ylabel='价格',
         volume=False, figsize=(10, 6))

⚠️ 避坑指南:我曾经在项目中直接用plt.plot画K线,结果画出来的图又丑又慢。后来改用mplfinance,一行代码搞定。但要注意,数据索引必须是DatetimeIndex,否则会报错。

如果你不想装额外库,也可以手写K线图。核心逻辑是:阳线(收盘>开盘)用空心矩形,阴线(收盘<开盘)用实心矩形,上下影线用竖线表示。

4.3 移动平均线叠加——让趋势更清晰

K线图本身信息量很大,但加上移动平均线(MA)后,趋势就一目了然了。我个人习惯叠加三条均线:MA5(短期)、MA20(中期)、MA60(长期)。

# 计算移动平均线
data['MA5'] = data['Close'].rolling(window=5).mean()
data['MA20'] = data['Close'].rolling(window=20).mean()
data['MA60'] = data['Close'].rolling(window=60).mean()

# 叠加到K线图上
mpf.plot(data, type='candle', style='charles',
         mav=(5, 20, 60),  # 直接传入均线周期
         title='K线图 + 移动平均线', ylabel='价格',
         volume=True, figsize=(12, 8))

你想想看,当MA5上穿MA20时,就是"金叉",是买入信号。反之,MA5下穿MA20是"死叉",是卖出信号。这些技术指标叠加在K线图上,交易决策就直观多了。

🔑 关键点:移动平均线的周期选择没有标准答案。短线交易者喜欢MA5、MA10,长线投资者用MA60、MA120。我建议你根据交易策略灵活调整,不要死板套用。

4.4 多子图布局——信息密度拉满

金融分析中,我们经常需要同时看价格、成交量、MACD、RSI等多个指标。多子图布局就是解决这个问题的。

# 创建多子图
fig, axes = plt.subplots(3, 1, figsize=(12, 10), sharex=True)

# 子图1:K线图
mpf.plot(data, type='candle', ax=axes[0], style='charles',
         title='价格走势', ylabel='价格')

# 子图2:成交量
axes[1].bar(data.index, data['Volume'], color='gray', alpha=0.6)
axes[1].set_title('成交量', fontsize=12)
axes[1].set_ylabel('成交量')

# 子图3:RSI指标
rsi = compute_rsi(data['Close'], 14)  # 假设有RSI计算函数
axes[2].plot(data.index, rsi, color='purple', linewidth=1.5)
axes[2].axhline(y=70, color='red', linestyle='--', alpha=0.5)
axes[2].axhline(y=30, color='green', linestyle='--', alpha=0.5)
axes[2].set_title('RSI指标', fontsize=12)
axes[2].set_ylabel('RSI')

plt.tight_layout()
plt.show()

这里有个小技巧:sharex=True让所有子图共享X轴,这样缩放或平移时,所有子图同步变化。我在做回测报告时经常用这个功能,效果非常好。

4.5 交互式图表——让数据"活"起来

静态图有个问题:你没法放大看细节,也没法悬停看具体数值。交互式图表解决了这个问题。我推荐用plotly库,它生成的HTML图表可以直接在浏览器里交互。

import plotly.graph_objects as go

# 创建交互式K线图
fig = go.Figure(data=[go.Candlestick(
    x=data.index,
    open=data['Open'],
    high=data['High'],
    low=data['Low'],
    close=data['Close'],
    name='K线'
)])

# 添加移动平均线
fig.add_trace(go.Scatter(
    x=data.index, y=data['MA5'],
    mode='lines', name='MA5',
    line=dict(color='blue', width=1)
))

fig.add_trace(go.Scatter(
    x=data.index, y=data['MA20'],
    mode='lines', name='MA20',
    line=dict(color='orange', width=1)
))

# 设置布局
fig.update_layout(
    title='交互式K线图',
    xaxis_title='日期',
    yaxis_title='价格',
    template='plotly_white',
    hovermode='x unified'
)

fig.show()

💡 实战经验:交互式图表在汇报演示时特别有用。你可以让客户自己缩放查看感兴趣的时间段,比静态图专业得多。但要注意,交互式图表文件较大,如果数据量超过10万条,建议先做降采样。

为什么会推荐plotly而不是bokeh或pyecharts?嗯,plotly的API设计更符合金融人的思维习惯,而且它和pandas的集成做得很好。我刚开始用bokeh,后来发现plotly更顺手,就彻底转过去了。

本章小结

这一章我们走完了金融数据可视化的完整路径:从Matplotlib基础绘图,到专业的K线图,再到移动平均线叠加、多子图布局,最后是交互式图表。每一步都是我在实际项目中反复用到的技能。

记住一句话:好的可视化不是花里胡哨,而是让数据自己说话。K线图上的每一根蜡烛、均线的每一次交叉,都在告诉你市场的语言。学会画图,你就学会了和市场对话。

下一章,我们会进入更核心的内容——特征工程。到时候见。


专注资料整理