如何用Xbbg或blpapi Python获取纽交所全部可交易债券?
用Python获取纽交所可交易债券数据(xbbg/blpapi实现)
一、使用xbbg实现(推荐,封装更简洁)
xbbg是blpapi的轻量封装,无需直接处理底层请求,步骤分为获取纽交所债券列表和批量提取目标字段两步。
1. 安装与初始化
先确保安装xbbg,且彭博终端已登录:
pip install xbbg
from xbbg import blp # 验证连接是否正常 blp.bdp('IBM US Equity', 'NAME')
2. 获取纽交所可交易债券列表
通过instrument_list函数筛选纽交所(NYSE)的活跃债券,可指定资产类型(如需所有债券可省略market_sector参数):
# 获取纽交所活跃公司债列表 bond_list = blp.instrument_list( exchange='NYSE', market_sector='CORPORATE', trading_status='ACTIVE', max_results=1000 # 可根据需求调整数量,彭博有返回上限 )
也可通过彭博筛选器实现更精确的筛选:
bond_list = blp.bds( 'BBG000000000', 'SCREEN_RESULTS', screen_params={ 'Exchange': 'NYSE', 'Asset Class': 'Bonds', 'Trading Status': 'Active' } )
3. 批量提取目标字段
拿到债券代码列表后,用blp函数批量获取所需字段(以下是对应彭博字段代码):
# 定义需要提取的字段 fields = [ 'OAS_SPREAD', # Option Adjusted Spread 'SP_RATING', # S&P Rating 'YLD_YTM_MID', # Yield to Maturity(中间价) 'GICS_SECTOR_NAME' # Sector(公司债用GICS行业更准确) ] # 批量获取数据 bond_data = blp.blp( tickers=bond_list['ticker'].tolist(), flds=fields, ovrds=[('CURRENCY', 'USD')] # 可选:指定计价货币 )
返回的bond_data是DataFrame格式,可直接保存为CSV或做进一步分析。
二、使用blpapi直接实现(底层控制)
你之前的代码返回空结果,核心问题是未指定交易所、筛选条件模糊,以下是修正后的实现:
1. 初始化会话与服务
import blpapi # 初始化会话 session_options = blpapi.SessionOptions() session_options.setServerHost('localhost') session_options.setServerPort(8194) session = blpapi.Session(session_options) if not session.start(): print("无法连接彭博终端") exit() # 打开instruments服务 if not session.openService("//blp/instruments"): print("无法打开instruments服务") session.stop() exit() service = session.getService("//blp/instruments")
2. 构造正确的instrumentListRequest
需指定交易所、资产类型、交易状态等精确筛选条件,避免模糊的query参数:
request = service.createRequest("instrumentListRequest") # 核心筛选条件 request.set("assetType", "BOND") request.set("exchange", "NYSE") request.set("tradingStatus", "ACTIVE") request.set("marketSector", "CORPORATE") # 如需所有债券类型,可注释此行 request.set("maxResults", 10) # 先小数量测试 # 指定返回字段 request.append("returnFields", "TICKER") request.append("returnFields", "SECURITY_NAME")
3. 发送请求并解析债券列表
print("发送请求...") session.sendRequest(request) bond_tickers = [] while True: event = session.nextEvent() for msg in event: if msg.hasElement("instrumentList"): instr_list = msg.getElement("instrumentList") for instr in instr_list.values(): ticker = instr.getElementAsString("ticker") name = instr.getElementAsString("securityName") bond_tickers.append(ticker) print(f"找到债券: {ticker} - {name}") if event.eventType() == blpapi.Event.RESPONSE: break session.stop()
4. 批量提取目标字段
拿到ticker列表后,用ReferenceDataRequest获取字段:
# 打开refdata服务 session.openService("//blp/refdata") ref_service = session.getService("//blp/refdata") # 构造请求 ref_request = ref_service.createRequest("ReferenceDataRequest") for ticker in bond_tickers: ref_request.append("securities", ticker) # 添加目标字段 ref_request.append("fields", "OAS_SPREAD") ref_request.append("fields", "SP_RATING") ref_request.append("fields", "YLD_YTM_MID") ref_request.append("fields", "GICS_SECTOR_NAME") # 发送请求并解析结果 session.sendRequest(ref_request) while True: event = session.nextEvent() for msg in event: if msg.hasElement("securityData"): sec_data = msg.getElement("securityData") for sec in sec_data.values(): ticker = sec.getElementAsString("security") print(f"\n债券: {ticker}") field_data = sec.getElement("fieldData") # 逐个提取字段并处理可能的缺失 if field_data.hasElement("OAS_SPREAD"): print(f"Option Adjusted Spread: {field_data.getElementAsFloat('OAS_SPREAD')} bps") if field_data.hasElement("SP_RATING"): print(f"S&P Rating: {field_data.getElementAsString('SP_RATING')}") if field_data.hasElement("YLD_YTM_MID"): print(f"Yield to Maturity: {field_data.getElementAsFloat('YLD_YTM_MID')}%") if field_data.hasElement("GICS_SECTOR_NAME"): print(f"Sector: {field_data.getElementAsString('GICS_SECTOR_NAME')}") if event.eventType() == blpapi.Event.RESPONSE: break session.stop()
关键注意事项
- 必须保持彭博终端登录状态,且API默认端口(8194)未被防火墙拦截。
- 部分字段可能因债券类型缺失(如国债无S&P评级),需用
hasElement判断避免报错。 instrumentListRequest有返回数量限制,如需全量数据,需通过startIndex参数分页请求。- 字段代码需准确,可在彭博终端用
FLDS命令查询对应字段的官方代码。
内容的提问来源于stack exchange,提问作者Lost Algorithm
相关产品推荐
相关产品推荐

