4、数据获取与清洗:用akshare搞定可转债行情数据
做量化投资,有一句老话叫「垃圾进,垃圾出」。数据质量不行,再牛的策略也是白搭。这一章,我们就来聊聊怎么用 akshare 把可转债的行情数据拿到手,再把它收拾得干干净净。
我个人习惯把数据获取和清洗放在一起做。为什么?因为拿到的原始数据,十有八九是「脏」的。缺字段、格式不对、甚至还有乱码。你想想看,要是数据没洗干净,后面的轮动信号算出来能准吗?
4.1 用akshare获取可转债行情数据
akshare 这个库,说白了就是A股数据的「瑞士军刀」。它把各种公开数据源封装成了统一的接口,用起来非常方便。我最早接触它的时候,还担心数据源不稳定,后来发现它支持多个数据源切换,心里踏实多了。
获取可转债行情,核心就一个函数:ak.bond_zh_cov()。它会返回所有上市可转债的实时行情数据。
import akshare as ak
import pandas as pd
# 获取可转债实时行情
df_cov = ak.bond_zh_cov()
print(df_cov.head())
运行之后,你会得到一个DataFrame。里面包含的字段大概有这些:
| 字段名 | 含义 | 备注 |
|---|---|---|
| 代码 | 可转债代码 | 如 123456 |
| 名称 | 可转债名称 | 如 某某转债 |
| 现价 | 当前价格 | 单位:元 |
| 涨跌幅 | 当日涨跌幅 | 百分比 |
| 正股价 | 对应正股价格 | 单位:元 |
| 转股价 | 转股价格 | 单位:元 |
| 转股价值 | 转股后的价值 | 单位:元 |
| 溢价率 | 转股溢价率 | 百分比 |
| 剩余规模 | 剩余未转股规模 | 单位:亿元 |
| 到期时间 | 剩余到期年限 | 单位:年 |
pip install akshare --upgrade。我在项目中遇到过两次接口变更,升级后就好了。
4.2 数据清洗与预处理
拿到原始数据后,别急着用。先看看它长什么样。我一般会做这几步:
4.2.1 检查缺失值
原始数据里,有些字段可能是空的。比如刚上市的可转债,可能还没有成交数据。或者某些指标因为计算原因暂时缺失。
# 检查缺失值
print(df_cov.isnull().sum())
# 处理缺失值:直接删除缺失严重的行
df_cov = df_cov.dropna(subset=['现价', '转股价', '溢价率'])
嗯,这里要注意:不要一股脑把所有缺失行都删了。有些字段缺失是正常的,比如「到期时间」对于永续债来说就是空的。我建议只删除那些对策略计算关键字段缺失的行。
4.2.2 数据类型转换
原始数据里,价格、百分比这些字段,经常是字符串类型。比如「现价」可能是 '128.50' 这样的字符串。不转成浮点数,后面没法算。
# 将价格字段转为浮点数
df_cov['现价'] = pd.to_numeric(df_cov['现价'], errors='coerce')
df_cov['转股价'] = pd.to_numeric(df_cov['转股价'], errors='coerce')
df_cov['溢价率'] = pd.to_numeric(df_cov['溢价率'], errors='coerce')
'--' 这样的占位符。用 pd.to_numeric 加上 errors='coerce' 参数,会自动把这些非法值变成 NaN,然后再统一处理。
4.2.3 过滤无效数据
有些可转债已经退市了,或者处于停牌状态。这些数据如果不剔除,会干扰轮动信号的计算。
# 过滤:只保留价格大于0的可转债
df_cov = df_cov[df_cov['现价'] > 0]
# 过滤:只保留溢价率在合理范围内的(比如 -50% 到 100%)
df_cov = df_cov[(df_cov['溢价率'] > -50) & (df_cov['溢价率'] < 100)]
为什么溢价率要设上下限?你想想看,溢价率超过100%的可转债,基本就是深度价外,转股无望。这种债的股性很弱,不太适合做轮动。当然,如果你有特殊策略,可以自己调整阈值。
4.3 构建基础数据DataFrame
数据洗干净了,接下来就是构建我们自己的基础数据表。我习惯把常用的计算字段都提前算好,存到一个干净的DataFrame里。
# 构建基础数据DataFrame
df_base = pd.DataFrame()
df_base['代码'] = df_cov['代码']
df_base['名称'] = df_cov['名称']
df_base['现价'] = df_cov['现价']
df_base['转股价'] = df_cov['转股价']
df_base['正股价'] = df_cov['正股价']
df_base['溢价率'] = df_cov['溢价率']
df_base['剩余规模'] = df_cov['剩余规模']
df_base['到期时间'] = df_cov['到期时间']
# 计算转股价值
df_base['转股价值'] = df_base['正股价'] / df_base['转股价'] * 100
# 计算到期收益率(简化版)
df_base['到期收益率'] = (100 - df_base['现价']) / df_base['现价'] / df_base['到期时间'] * 100
# 排序:按溢价率升序排列
df_base = df_base.sort_values(by='溢价率', ascending=True)
print(df_base.head())
4.4 知识体系总览
这一章的内容,可以用下面这张图来概括。它展示了从数据获取到基础DataFrame构建的完整流程。
这张图把整个流程串起来了。从akshare获取原始数据,到清洗、预处理,最后构建出我们自己的基础DataFrame。每一步都有坑,但踩过之后,后面的路就好走了。
好了,数据已经准备好了。干净、完整、结构清晰。接下来,我们就可以用它来构建轮动策略了。
公众号:蓝海数据掘金营,微信deep3321