2. 数据获取:如何用Python获取实时股票和可转债行情数据?

做量化交易,第一步就是搞定数据。没有数据,再牛的策略也是纸上谈兵。

我个人习惯把数据获取比作「做饭前的买菜」。菜买不好,厨艺再高也白搭。今天咱们就聊聊,怎么用Python把这「菜」买得又快又新鲜。

2.1 数据源的选择:免费还是付费?

先说说数据源。市面上能拿行情数据的渠道不少,我列几个常用的:

数据源 类型 实时性 费用 我的评价
akshare 开源库 准实时(延迟1-3秒) 免费 入门首选,够用
tushare 开源库 准实时 免费/付费 老牌,但积分限制多
baostock 开源库 日线为主 免费 历史数据不错,实时不行
券商API 官方接口 实时 开户即可 最稳,但有门槛
聚宽/米筐 量化平台 实时 付费 专业级,适合机构

我个人最常用的是 akshare。为什么?因为它免费、接口统一、文档还算友好。我在项目中遇到过几次数据源突然挂掉的情况,akshare 的社区响应速度是最快的。

我的建议:刚开始做策略回测,用免费数据完全够。等实盘跑起来了,再考虑上券商API或付费数据源。

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[['代码', '名称', '最新价', '涨跌幅']])
关键点:akshare 返回的字段名是中文,这在后续处理时要注意。我习惯在获取后统一重命名成英文,方便写策略。

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开头。筛选的时候千万别搞混。

避坑指南:可转债的「最新价」单位是「元/张」,不是「元/手」。1手=10张,计算市值时记得乘以10。

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 本章知识体系

说了这么多,咱们用一张图把核心逻辑串起来:

数据获取核心流程 数据源层 akshare | tushare | 券商API | 聚宽/米筐 数据获取层 股票行情: stock_zh_a_spot_em 转债行情: bond_zh_cov_spot_em 数据处理层 字段筛选 → 重命名 → 按正股代码合并 → 计算偏离度 输出:实时联动数据表 → 策略判断

这张图把整个流程分成了四层:数据源、获取、处理、输出。每一层都有对应的代码实现。你照着这个框架搭,基本不会出错。

2.8 写在最后

数据获取这块,说白了就是三板斧:选对源、调对接口、拼好数据。代码量不大,但细节不少。

我个人习惯把数据获取封装成一个类,每天开盘前自动跑一次,然后每30秒刷新。这样既保证了实时性,又不会把API搞崩。

好了,数据到手了。下一章咱们聊聊怎么用这些数据计算「正股联动偏离度」,以及怎么捕捉套利机会。


专注资料整理