股票数据可视化是金融数据分析领域的基础技能,也是量化投资的重要工具。这个Python项目通过爬取公开股票数据,使用Matplotlib、Seaborn等可视化库,实现从基础K线图到复杂技术指标的多维度展示。不同于简单的图表绘制,我们更关注如何通过可视化发现数据背后的市场规律。
我在实际量化工作中发现,90%的决策失误源于对原始数据的误读。一个优秀的可视化系统应该能同时满足三种需求:帮助新手快速理解市场趋势、辅助交易员发现微观波动规律、为量化策略提供数据验证支持。这正是本项目的核心价值所在。
采用AKShare作为主要数据源(安装:pip install akshare),这是目前最稳定的免费金融数据接口之一。相比其他方案,它有三大优势:
python复制import akshare as ak
# 获取贵州茅台日线数据
df = ak.stock_zh_a_daily(symbol="sh600519", adjust="hfq")
注意:国内股票代码需加市场前缀(sh/sz),美股使用代码全称如AAPL
| 工具 | 适用场景 | 性能表现 | 学习曲线 |
|---|---|---|---|
| Matplotlib | 基础图表、高度定制 | 优 | 陡峭 |
| Seaborn | 统计图表、快速成型 | 良 | 平缓 |
| Plotly | 交互式图表 | 中 | 中等 |
| Pyecharts | 中国式图表 | 中 | 中等 |
本项目采用混合方案:Matplotlib绘制核心K线+技术指标,Seaborn处理相关性矩阵等统计图表。
使用mpl_finance库(现迁移到mplfinance)的candlestick_ochl方法:
python复制import mplfinance as mpf
# 必须包含Open,Close,High,Low列且为float类型
df['date'] = pd.to_datetime(df['date'])
df.set_index('date', inplace=True)
mpf.plot(df, type='candle',
style='charles',
volume=True,
title='贵州茅台K线图',
ylabel='价格(元)')
关键参数说明:
style: 内置12种配色方案,'charles'最接近专业软件风格mav=(5,10,20): 添加移动平均线volume: 底部显示成交量柱状图通过annotate方法标记支撑位/压力位:
python复制ax = plt.gca()
ax.annotate('突破压力位',
xy=('2023-07-15', 1800),
xytext=(0, 20),
textcoords='offset points',
arrowprops=dict(arrowstyle='->'))
python复制def calculate_macd(df, fast=12, slow=26, signal=9):
df['EMA12'] = df['close'].ewm(span=fast).mean()
df['EMA26'] = df['close'].ewm(span=slow).mean()
df['DIF'] = df['EMA12'] - df['EMA26']
df['DEA'] = df['DIF'].ewm(span=signal).mean()
df['MACD'] = (df['DIF'] - df['DEA']) * 2
return df
plt.figure(figsize=(10,4))
plt.bar(df.index, df['MACD'],
color=np.where(df['MACD']>0, 'r','g'))
plt.plot(df['DIF'], label='DIF')
plt.plot(df['DEA'], label='DEA')
python复制df['MA20'] = df['close'].rolling(20).mean()
df['upper'] = df['MA20'] + 2*df['close'].rolling(20).std()
df['lower'] = df['MA20'] - 2*df['close'].rolling(20).std()
plt.fill_between(df.index, df['upper'], df['lower'], alpha=0.2)
plt.plot(df[['close','MA20']])
python复制import seaborn as sns
# 计算行业资金流
industry_flow = df.groupby('industry')['net_amount'].sum()
sns.heatmap(industry_flow.unstack(),
cmap='RdYlGn',
center=0,
annot=True,
fmt=".1f")
使用Plotly+Dash构建:
python复制import dash
from dash import dcc, html
app = dash.Dash()
app.layout = html.Div([
dcc.Dropdown(id='stock-selector',
options=[{'label':s, 'value':s}
for s in stock_list]),
dcc.Graph(id='kline-chart')
])
@app.callback(
Output('kline-chart','figure'),
[Input('stock-selector','value')]
)
def update_chart(selected):
df = get_data(selected)
fig = px.line(df, x='date', y='close')
return fig
python复制from functools import lru_cache
@lru_cache(maxsize=32)
def get_stock_data(code):
return ak.stock_zh_a_daily(symbol=code)
对于超过1000个数据点的情况:
python复制plt.plot(df['close'], '-',
linewidth=0.5,
alpha=0.7,
antialiased=True)
python复制# 前向填充+线性插值
df.fillna(method='ffill', inplace=True)
df.interpolate(method='linear', inplace=True)
python复制plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
python复制plt.ylim(df['low'].min()*0.95, df['high'].max()*1.05)
我在实际使用中发现,将可视化结果与交易日志结合分析效果最佳。建议建立这样的工作流: