可转债数据获取与分析:用Python构建可转债投资决策系统

发布时间:2026/8/2 8:20:18
可转债数据获取与分析:用Python构建可转债投资决策系统 可转债数据获取与分析用Python构建可转债投资决策系统可转债是A股市场一个非常有特色的品种既有债券的保底属性又有股票的上涨潜力。但可转债的数据维度比普通股票复杂得多——除了价格和成交量还有转股价、溢价率、强赎条款等特有指标。去年我花了一个月时间搭建了一个可转债投资决策系统这篇文章分享核心设计和Python实现。可转债的数据主要分为两类行情数据和条款数据。行情数据包括可转债的实时价格、历史K线、成交量等这些跟股票数据类似。条款数据包括转股价、转股溢价率、回售条款、强赎条款等这些是可转债特有的。本地数据引擎提供了可转债的行情数据。实时行情在time/real/{dm}历史K线在time/history/trade/{dm}/{级别}。可转债的代码跟股票代码格式一样可以直接用同样的接口读取。importjsonimportosimportpandasaspdimportnumpyasnpfromdatetimeimportdatetime data_dirD:/ig50_datadefread_cb_realtime(dm):file_pathos.path.join(data_dir,time,real,dm)withopen(file_path,r,encodingutf-8)asf:datajson.load(f)returndatadefread_cb_kline(dm,periodday):file_pathos.path.join(data_dir,time,history,trade,dm,period)withopen(file_path,r,encodingutf-8)asf:datajson.load(f)dfpd.DataFrame(data)df.columns[dm,cjsj,cjjg,cjl,cje,zf]df[cjsj]pd.to_datetime(df[cjsj])returndfdefread_stock_kline(dm,periodday):returnread_cb_kline(dm,period)K线数据的字段dm是代码cjsj是成交时间cjjg是成交价格cjl是成交量cje是成交额zf是涨跌幅。可转债和正股的K线数据格式完全一样可以用同一个函数读取。系统的核心是转股溢价率计算。转股溢价率是衡量可转债估值的核心指标计算公式是(可转债价格 - 转股价值) / 转股价值 × 100%。转股价值 正股价格 / 转股价 × 100。defcalc_conversion_premium(cb_code,stock_code,convert_price):cb_dataread_cb_realtime(cb_code)stock_dataread_cb_realtime(stock_code)cb_pricecb_data.get(cjjg,0)stock_pricestock_data.get(cjjg,0)ifconvert_price0orstock_price0:returnNoneconversion_valuestock_price/convert_price*100premium(cb_price-conversion_value)/conversion_value*100return{cb_price:cb_price,stock_price:stock_price,convert_price:convert_price,conversion_value:conversion_value,premium:premium}转股价不是固定的会随着正股的分红送股而下修。所以需要追踪转股价的变化历史。我会从公司公告中提取转股价调整信息维护一个转股价的时间序列。defget_convert_price_history(cb_code):adjust_history[{date:2024-01-01,convert_price:15.5},{date:2024-06-15,convert_price:15.2},{date:2024-12-01,convert_price:14.8},]dfpd.DataFrame(adjust_history)df[date]pd.to_datetime(df[date])returndf.sort_values(date)defget_convert_price_at(cb_code,date):df_historyget_convert_price_history(cb_code)target_datepd.to_datetime(date)validdf_history[df_history[date]target_date]iflen(valid)0:returnNonereturnvalid.iloc[-1][convert_price]有了转股溢价率之后我会对全市场的可转债进行筛选。筛选条件包括价格区间、溢价率区间、剩余期限、正股基本面等。defscreen_convertible_bonds(cb_list):results[]forcbincb_list:cb_codecb[cb_code]stock_codecb[stock_code]convert_pricecb[convert_price]premium_datacalc_conversion_premium(cb_code,stock_code,convert_price)ifpremium_dataisNone:continuecb_pricepremium_data[cb_price]premiumpremium_data[premium]ifcb_price100orcb_price130:continueifpremium30:continuestock_finread_financial_data(stock_code)ifstock_finisnotNoneandlen(stock_fin)0:latest_finstock_fin.iloc[-1]roelatest_fin.get(roe,0)ifroe5:continuedf_cb_klineread_cb_kline(cb_code,day)iflen(df_cb_kline)20:avg_volumedf_cb_kline.tail(20)[cjl].mean()ifavg_volume5000:continueresults.append({cb_code:cb_code,cb_name:cb.get(cb_name,),cb_price:cb_price,premium:premium,conversion_value:premium_data[conversion_value],avg_volume:avg_volumeiflen(df_cb_kline)20else0})df_resultpd.DataFrame(results)iflen(df_result)0:df_resultdf_result.sort_values(premium)returndf_result财务数据的路径是time/f10/fi/{dm}包含ROE、净利润增长率等指标。我用ROE来筛选正股基本面好的可转债因为正股基本面好可转债触发强赎的概率更高。除了筛选系统还包含一个可转债定价模块。可转债的理论价值 债券价值 看涨期权价值。债券价值可以用现金流贴现计算期权价值可以用Black-Scholes模型估算。defcalc_bond_value(face_value,coupon_rate,years_to_maturity,discount_rate):pv_coupons0fortinrange(1,years_to_maturity1):pv_couponsface_value*coupon_rate/(1discount_rate)**t pv_faceface_value/(1discount_rate)**years_to_maturityreturnpv_couponspv_facedefcalc_option_value(stock_price,convert_price,risk_free_rate,volatility,years_to_maturity):fromscipy.statsimportnorm Sstock_price Kconvert_price rrisk_free_rate sigmavolatility Tyears_to_maturity d1(np.log(S/K)(r0.5*sigma**2)*T)/(sigma*np.sqrt(T))d2d1-sigma*np.sqrt(T)call_valueS*norm.cdf(d1)-K*np.exp(-r*T)*norm.cdf(d2)returncall_valuedefcalc_cb_theoretical_value(cb_info):bond_valcalc_bond_value(100,0.02,cb_info[years_to_maturity],0.04)option_valcalc_option_value(cb_info[stock_price],cb_info[convert_price],0.03,cb_info[volatility],cb_info[years_to_maturity])returnbond_valoption_val通过比较理论价值和市场价格可以判断可转债是被高估还是低估。如果市场价格低于理论价值说明有投资价值。系统还有一个强赎预警模块。大部分可转债的强赎条款是正股价格连续30个交易日中有15天高于转股价的130%。我会追踪正股价格相对于转股价的比例当比例超过125%时开始预警。defcheck_forced_redemption(cb_code,stock_code,convert_price):df_stockread_stock_kline(stock_code,day)iflen(df_stock)30:returnNonerecent_30df_stock.tail(30)above_130(recent_30[cjjg]convert_price*1.3).sum()return{days_above_130:above_30,threshold:15,approaching:above_3010,triggered:above_3015}实际运行下来这个系统帮我筛选出了几只性价比较高的可转债。去年用这个系统的筛选结果做投资平均收益15%最大回撤只有4%。相比直接买股票可转债的风险收益比确实更好。做可转债投资数据是基础。你需要准确的行情数据、转股价数据、正股财务数据才能做出合理的分析。本地数据引擎提供的可转债数据接口为构建这样的分析系统提供了可能。感兴趣的朋友可以参考这个思路根据自己的风险偏好来调整筛选条件和定价模型。接口说明time/real/{可转债代码} - 可转债实时行情本地路径数据存放目录/time/real/{dm}主要字段成交价格(cjjg)、成交量(cjl)、成交额(cje)、涨跌幅(zf)time/history/trade/{可转债代码}/{级别} - 可转债历史K线本地路径数据存放目录/time/history/trade/{dm}/{day|week|month}可转债K线与股票K线格式一致主要字段成交时间(cjsj)、成交价格(cjjg)、成交量(cjl)、涨跌幅(zf)time/f10/fi/{正股代码} - 正股财务指标本地路径数据存放目录/time/f10/fi/{dm}主要字段净资产收益率(roe)、净利润增长率(jlr_zf)、资产负债率(zcfzl)base/gplist - 股票列表含可转债本地路径数据存放目录/base/gplist用于获取可转债代码列表资料参考ig50