你的第一个量化分析项目:用Python解析茅台股价数据
第一次接触量化分析时,我盯着屏幕上闪烁的股票行情图发呆。那些红绿交错的K线背后藏着怎样的规律?作为一个既不懂金融又刚学Python的菜鸟,直到用代码抓取到第一组茅台股价数据时,才真正感受到用技术解码金融的魔力。本文将带你用不到50行代码,完成从数据获取到可视化的完整分析闭环。
1. 环境配置与工具选型
工欲善其事,必先利其器。量化分析不需要昂贵的Bloomberg终端,只需准备:
- Python 3.8+:建议使用Anaconda发行版
- 关键库:
pip install efinance pandas matplotlib - 开发环境:VS Code或Jupyter Notebook
为什么选择efinance?这个轻量级库完美适配国内A股市场:
| 特性 | efinance | 其他替代方案 |
|---|---|---|
| 数据源 | 国内交易所 | 雅虎财经(不稳定) |
| 安装复杂度 | 一键安装 | 需要API密钥 |
| 更新频率 | 实时 | 延迟15分钟 |
提示:遇到安装报错时,可尝试添加
--user参数或使用清华镜像源
2. 数据获取实战
让我们从茅台股票(代码600519)开始。新建maotai_analysis.py文件:
import efinance as ef import pandas as pd def fetch_stock_data(code, start='2023-01-01', end='2023-12-31'): """ 获取股票历史行情 :param code: 股票代码(如'600519') :param start: 开始日期(YYYY-MM-DD) :param end: 结束日期 :return: 包含OHLCV数据的DataFrame """ df = ef.stock.get_quote_history(code, beg=start, end=end) # 数据清洗 df = df[['日期','开盘','收盘','最高','最低','成交量','成交额']] df.columns = ['date','open','close','high','low','volume','turnover'] df.set_index(pd.to_datetime(df['date']), inplace=True) return df.drop('date', axis=1) if __name__ == '__main__': mt_data = fetch_stock_data('600519') print(mt_data.tail())运行后会看到类似这样的输出:
open close high low volume turnover date 2023-12-25 1688.0 1690.01 1699.00 1685.00 33842612 5.731549e+09 2023-12-26 1685.0 1680.12 1689.88 1676.00 31985705 5.381430e+09 2023-12-27 1680.0 1685.35 1688.00 1675.00 28713213 4.828038e+09 2023-12-28 1688.0 1688.01 1696.00 1682.00 31932412 5.398040e+09 2023-12-29 1685.0 1685.58 1692.00 1680.00 29183276 4.923754e+093. 数据清洗技巧
原始数据需要加工才能用于分析。常见问题及解决方案:
缺失值处理:
# 前向填充 df.fillna(method='ffill', inplace=True) # 或删除缺失行 df.dropna(inplace=True)异常值检测:
# 找出涨跌幅超过10%的异常交易日 df['pct_change'] = df['close'].pct_change() * 100 anomalies = df[abs(df['pct_change']) > 10]数据标准化(当比较不同价格股票时):
df['normalized'] = df['close'] / df['close'].iloc[0]
4. 基础分析可视化
Matplotlib绘制专业级K线图:
import matplotlib.pyplot as plt from mplfinance.original_flavor import candlestick_ohlc import matplotlib.dates as mdates # 准备数据 plot_data = mt_data.copy() plot_data['date_num'] = mdates.date2num(plot_data.index.to_pydatetime()) # 创建画布 fig, ax = plt.subplots(figsize=(12, 6)) candlestick_ohlc(ax, plot_data[['date_num','open','high','low','close']].values, width=0.6, colorup='r', colordown='g') # 美化图表 ax.xaxis_date() ax.grid(True) plt.title('贵州茅台(600519) 2023年K线图') plt.xlabel('日期') plt.ylabel('价格(元)') plt.xticks(rotation=45) plt.tight_layout() plt.show()进阶分析可以添加:
- 移动平均线(MA5、MA20)
- 成交量柱状图
- MACD/KDJ等技术指标
5. 扩展应用场景
掌握基础技能后,可以尝试:
多股对比分析
codes = ['600519', '000858', '600809'] # 茅台、五粮液、山西汾酒 combined = pd.concat([fetch_stock_data(code)['close'] for code in codes], axis=1) combined.columns = codes构建简易策略回测
# 金叉策略示例 df['MA5'] = df['close'].rolling(5).mean() df['MA20'] = df['close'].rolling(20).mean() df['signal'] = np.where(df['MA5'] > df['MA20'], 1, -1)对接交易API(需券商支持)
遇到数据接口不稳定时,可以考虑:
- 使用
try-except包装请求代码 - 添加随机延迟避免被封禁
- 本地存储历史数据备份
6. 常见问题排查
- 获取数据为空:检查股票代码是否带市场前缀(如SH600519)
- 日期格式错误:确保传入
YYYY-MM-DD格式 - 内存不足:分批获取数据,特别是处理分钟级数据时
- 图表显示异常:检查数据中是否存在NaN值
第一次成功获取到茅台数据时,我盯着那些数字看了很久——原来千元股价的波动就藏在这简单的DataFrame里。量化分析最迷人的地方在于,无论你是用价值百万的量化系统,还是像我们这样用十几行Python代码,面对的都是同样真实的市场脉搏。