2. 数据获取:如何用Python获取实时股票和可转债行情数据?
做量化交易,第一步就是搞定数据。没有数据,再牛的策略也是纸上谈兵。
我个人习惯把数据获取比作「做饭前的买菜」。菜买不好,厨艺再高也白搭。今天咱们就聊聊,怎么用Python把这「菜」买得又快又新鲜。
2.1 数据源的选择:免费还是付费?
先说说数据源。市面上能拿行情数据的渠道不少,我列几个常用的:
| 数据源 | 类型 | 实时性 | 费用 | 我的评价 |
|---|---|---|---|---|
| akshare | 开源库 | 准实时(延迟1-3秒) | 免费 | 入门首选,够用 |
| tushare | 开源库 | 准实时 | 免费/付费 | 老牌,但积分限制多 |
| baostock | 开源库 | 日线为主 | 免费 | 历史数据不错,实时不行 |
| 券商API | 官方接口 | 实时 | 开户即可 | 最稳,但有门槛 |
| 聚宽/米筐 | 量化平台 | 实时 | 付费 | 专业级,适合机构 |
我个人最常用的是 akshare。为什么?因为它免费、接口统一、文档还算友好。我在项目中遇到过几次数据源突然挂掉的情况,akshare 的社区响应速度是最快的。
2.2 安装与基础配置
先装库。打开终端,一行命令搞定:
pip install akshare pandas
嗯,这里要注意。akshare 依赖的库比较多,如果遇到安装报错,多半是网络问题。我建议用国内镜像:
pip install akshare -i https://pypi.tuna.tsinghua.edu.cn/simple
装好之后,在Python里导入:
import akshare as ak
import pandas as pd
搞定。就这么简单。
2.3 获取实时股票行情
股票行情数据,akshare 提供了 stock_zh_a_spot_em 这个接口。名字有点长,但功能很直接——获取A股实时行情。
看代码:
# 获取全市场A股实时行情
df_stock = ak.stock_zh_a_spot_em()
print(df_stock.head())
跑一下,你会看到类似这样的输出:
代码 名称 最新价 涨跌幅 涨跌额 成交量 成交额
0 600000 浦发银行 7.12 0.42% 0.03 12.3万 8765万
1 600004 白云机场 12.35 -0.56% -0.07 8.7万 1.07亿
...
数据量很大,全市场5000多只股票。但我们做正股联动,通常只关注少数几只。怎么筛选?
比如我只想看「贵州茅台」和「宁德时代」:
# 筛选指定股票
target_stocks = ['600519', '300750']
df_filtered = df_stock[df_stock['代码'].isin(target_stocks)]
print(df_filtered[['代码', '名称', '最新价', '涨跌幅']])
2.4 获取实时可转债行情
可转债的接口类似,叫 bond_zh_cov_spot_em。名字里多了个 cov,代表可转债(Convertible Bond)。
# 获取全市场可转债实时行情
df_bond = ak.bond_zh_cov_spot_em()
print(df_bond.head())
输出长这样:
代码 转债名称 最新价 涨跌幅 正股代码 转股价值 溢价率
0 110044 大秦转债 112.50 0.18% 601006 108.20 3.97%
1 113050 南银转债 118.30 -0.22% 601009 120.15 -1.54%
...
注意看,这里直接包含了「正股代码」和「溢价率」字段。这对我们做正股联动分析来说,简直是天赐之物。
我曾经踩过一个坑:可转债的代码和股票代码格式不一样。股票是6位数字,可转债也是6位,但前两位是11、12、13开头。筛选的时候千万别搞混。
2.5 合并股票与可转债数据
做正股联动,核心就是把正股和转债的数据拼在一起。怎么拼?用「正股代码」作为桥梁。
看代码:
# 1. 获取股票数据
df_stock = ak.stock_zh_a_spot_em()
# 只保留需要的字段
df_stock = df_stock[['代码', '名称', '最新价', '涨跌幅']]
df_stock.columns = ['stock_code', 'stock_name', 'stock_price', 'stock_pct']
# 2. 获取转债数据
df_bond = ak.bond_zh_cov_spot_em()
# 只保留需要的字段
df_bond = df_bond[['代码', '转债名称', '最新价', '涨跌幅', '正股代码', '溢价率']]
df_bond.columns = ['bond_code', 'bond_name', 'bond_price', 'bond_pct', 'stock_code', 'premium']
# 3. 合并
df_merged = pd.merge(df_bond, df_stock, on='stock_code', how='left')
print(df_merged.head())
合并之后,每一行就是一只可转债,同时带着正股的最新行情。这样你就能一眼看出:正股涨了3%,转债才涨0.5%,溢价率是不是在扩大?
how='inner' 可以只保留两边都有的数据。我一般用 left,因为转债数据更全,正股偶尔会有停牌。
2.6 实时刷新与定时任务
行情是动态的。你不可能手动一遍遍跑代码。怎么办?加个定时器。
最简单的做法:
import time
def fetch_realtime_data():
"""获取实时数据并打印"""
df_stock = ak.stock_zh_a_spot_em()
df_bond = ak.bond_zh_cov_spot_em()
# ... 合并逻辑同上 ...
print(f"数据更新时间:{pd.Timestamp.now()}")
return df_merged
# 每30秒刷新一次
while True:
data = fetch_realtime_data()
# 这里可以加你的策略判断逻辑
time.sleep(30)
嗯,这里要注意。akshare 的免费接口有频率限制。我实测下来,每秒请求不要超过2次,否则会被封IP。30秒刷新一次,对套利策略来说完全够用。
你想想看,正股联动偏离度的变化,通常是以分钟为单位的。30秒刷新一次,已经比大多数散户反应快了。
2.7 本章知识体系
说了这么多,咱们用一张图把核心逻辑串起来:
这张图把整个流程分成了四层:数据源、获取、处理、输出。每一层都有对应的代码实现。你照着这个框架搭,基本不会出错。
2.8 写在最后
数据获取这块,说白了就是三板斧:选对源、调对接口、拼好数据。代码量不大,但细节不少。
我个人习惯把数据获取封装成一个类,每天开盘前自动跑一次,然后每30秒刷新。这样既保证了实时性,又不会把API搞崩。
好了,数据到手了。下一章咱们聊聊怎么用这些数据计算「正股联动偏离度」,以及怎么捕捉套利机会。