第三章 数据获取与清洗:用akshare搭建你的可转债数据库
做量化交易,数据就是你的弹药库。弹药不行,再好的策略也白搭。
我个人习惯每天开盘前先跑一遍数据脚本,把全市场的可转债数据拉下来。今天我就带你走一遍这个流程——从akshare获取数据,到清洗、标准化,最后构建出一个可以直接用于策略分析的DataFrame。
3.1 为什么选akshare?
市面上能拿可转债数据的库不少,但akshare是我用得最顺手的。原因有三:
- 免费且开源——不用花钱买数据接口,对个人量化玩家非常友好
- 数据源稳定——底层抓取的是东方财富、新浪财经等主流平台的数据
- 接口统一——股票、基金、可转债都用同一套调用方式,省心
pip install akshare --upgrade,否则某些接口可能会因为网站改版而失效。
3.2 获取全市场可转债列表
先上代码。这是我最常用的数据获取脚本:
import akshare as ak
import pandas as pd
import datetime
# 获取全市场可转债实时数据
def get_all_convertible_bonds():
"""
获取全市场可转债行情数据
返回:DataFrame,包含代码、名称、价格、溢价率等核心字段
"""
try:
df = ak.bond_convert_jsl()
print(f"数据获取成功,共 {len(df)} 只可转债")
return df
except Exception as e:
print(f"数据获取失败:{e}")
return None
# 执行获取
raw_data = get_all_convertible_bonds()
这里用的是 bond_convert_jsl() 接口,它返回的是集思录风格的数据表。为什么选这个?因为集思录的数据字段最全——价格、溢价率、到期收益率、转股价值、剩余规模……基本上你策略需要的都有了。
bond_convert_jsl 报错,可以试试 ak.bond_convert_jsl() 或者去akshare官方文档查最新接口名。
3.3 数据清洗——把脏数据变成干净数据
拿到原始数据后,千万别直接拿去跑策略。我踩过这个坑——有一次没做清洗,结果策略里混进了一只已经退市的可转债,回测曲线直接崩了。
数据清洗我一般做这几步:
- 删除无效行——比如那些已经退市、或者数据为空的记录
- 处理缺失值——有些字段可能为空,需要填充或删除
- 数据类型转换——把字符串转成数值,把百分比转成小数
- 过滤异常值——比如价格低于50元或者高于500元的,基本是数据错误
来看具体代码:
def clean_bond_data(df):
"""
清洗可转债数据
"""
# 1. 删除退市和无效数据
df = df[df['债券代码'].notna()]
df = df[df['债券代码'].str.len() == 6] # 可转债代码都是6位
# 2. 处理缺失值
df = df.dropna(subset=['现价', '溢价率'])
# 3. 数据类型转换
# 现价转浮点数
df['现价'] = pd.to_numeric(df['现价'], errors='coerce')
# 溢价率转浮点数(原始数据可能是"12.34%"这种格式)
df['溢价率'] = df['溢价率'].str.replace('%', '').astype(float) / 100
# 4. 过滤异常值
df = df[(df['现价'] > 50) & (df['现价'] < 500)]
df = df[df['溢价率'] > -0.5] # 溢价率不会低于-50%
return df
# 执行清洗
clean_data = clean_bond_data(raw_data)
print(f"清洗后剩余 {len(clean_data)} 只可转债")
嗯,这里要注意一点:errors='coerce' 这个参数很关键。它会把无法转换的值变成NaN,而不是直接报错中断程序。我在生产环境里吃过亏——某天数据源突然改了格式,整个脚本直接崩溃,从那以后我就养成了加这个参数的习惯。
3.4 数据标准化——让数据口径统一
不同数据源、不同接口返回的数据,字段名和单位可能都不一样。标准化就是把这些数据统一成你策略能直接用的格式。
我一般做以下标准化:
- 字段重命名——把中文名改成英文名,方便后续代码调用
- 单位统一——比如规模统一用"亿元",价格统一用"元"
- 计算衍生字段——比如双低值 = 价格 + 溢价率×100
def standardize_bond_data(df):
"""
标准化可转债数据
"""
# 字段重命名
column_mapping = {
'债券代码': 'bond_code',
'债券简称': 'bond_name',
'现价': 'price',
'溢价率': 'premium_ratio',
'到期收益率': 'ytm',
'剩余规模': 'remain_size',
'转股价值': 'convert_value',
'正股代码': 'stock_code',
'正股名称': 'stock_name'
}
df = df.rename(columns=column_mapping)
# 计算衍生字段
df['double_low'] = df['price'] + df['premium_ratio'] * 100
# 排序
df = df.sort_values('double_low')
return df
# 执行标准化
final_data = standardize_bond_data(clean_data)
双低值这个字段,说白了就是衡量可转债"便宜程度"的一个指标。价格低、溢价率低,双低值就低,说明这只债性价比高。我自己的轮动策略就是基于双低值来排序的。
3.5 构建基础数据DataFrame
最后一步,把清洗和标准化后的数据整理成你策略可以直接用的DataFrame。我习惯保留这些核心字段:
| 字段名 | 含义 | 数据类型 | 示例 |
|---|---|---|---|
| bond_code | 债券代码 | str | 123456 |
| bond_name | 债券简称 | str | XX转债 |
| price | 当前价格(元) | float | 118.50 |
| premium_ratio | 溢价率 | float | 0.1234 |
| ytm | 到期收益率 | float | 0.025 |
| remain_size | 剩余规模(亿元) | float | 3.5 |
| convert_value | 转股价值 | float | 105.20 |
| double_low | 双低值 | float | 130.84 |
| stock_code | 正股代码 | str | 600000 |
| stock_name | 正股名称 | str | XX股份 |
有了这个DataFrame,你就可以直接用它来做策略回测、排序选债、甚至实盘监控了。
3.6 本章知识体系
下面这张图概括了本章的核心流程:
这张图把整个流程串起来了。你每天跑一遍这个脚本,就能拿到一份干净、标准化的全市场可转债数据。有了这个基础,后面的策略分析和实盘调仓才能站得住脚。
数据获取与清洗这一步,说白了就是磨刀。刀磨好了,砍柴才快。下一章我们会基于这份干净数据,开始构建真正的轮动策略。