Skip to content

Latest commit

 

History

History
544 lines (388 loc) · 18.9 KB

File metadata and controls

544 lines (388 loc) · 18.9 KB
CBLens

CBLens 使用文档

安装 · 数据源 · GUI · CLI · Python API · 排障


本文面向第一次运行和日常维护 CBLens 的使用者。更底层的数据字段说明见 data/README.md,维护约定见 AGENTS.md

目录


1. 安装

基础环境

git clone https://github.com/Grefer/CBLens.git
cd CBLens

python -m venv .venv
source .venv/bin/activate        # Windows: .venv\Scripts\activate
python -m pip install -U pip
pip install -e ".[dev]"

依赖清单

依赖 用途 备注
Python 3.10+ 运行环境 使用 X | None 等 3.10 类型语法
numpy, scipy PDE 定价数值计算
customtkinter, matplotlib GUI 界面
pillow 图像处理
akshare 免费动态行情源
WindPy 全字段条款同步 + 实时行情 ⚠️ 需从 Wind 终端安装,不能通过 pip

WindPy 安装

WindPy 不通过 pip 发布。如需使用:

  1. 打开 Wind 金融终端
  2. 进入 插件管理 → Python 接口
  3. 选择当前虚拟环境的 Python 路径进行安装
  4. 验证:python -c "from WindPy import w; print(w)"

Tip

不连接 Wind 也能正常使用!离线 PDE 模型、已有 data/cb_data.json、akshare 动态行情都不依赖 Wind。

桌面 APP

正式 Release 会附带可直接运行的桌面包:

  • macOS: CBLens-macOS.zip,解压后双击 CBLens.app
  • Windows: CBLens-Windows.zip,解压后双击 CBLens.exe

桌面包暂未使用 Apple Developer ID 或 Windows Authenticode 证书签名,首次运行需要手动放行:

  • macOS:Gatekeeper 可能提示"无法验证开发者"或"已损坏,无法打开"。在终端执行 xattr -dr com.apple.quarantine /path/to/CBLens.app 去掉隔离属性,或在 Finder 中右键 CBLens.app → 打开,再在弹窗中点"打开"。
  • Windows:SmartScreen 会显示"Windows 已保护你的电脑"。点击"更多信息" → "仍要运行"。

如希望避免上述提示,可参考下方步骤在本机自行编译。

源码构建桌面包:

python -m pip install -e ".[desktop]"
python scripts/build_desktop.py

构建产物位于 dist/。打包后的 APP 会把运行态数据写入用户目录,而不是写入应用安装目录:

  • macOS: ~/Library/Application Support/CBLens/data
  • Windows: %APPDATA%\CBLens\data
  • 可用 CBLENS_DATA_DIR 环境变量覆盖数据目录

若打包后怀疑内置数据或数据源依赖没有被带上,可在终端运行:

dist/CBLens/CBLens --diagnose
# 或 macOS .app 形态:
dist/CBLens.app/Contents/MacOS/CBLens --diagnose

诊断输出会列出 APP 内置种子数据、用户数据目录中的 cb_data.json 债券数量,以及 WindPy / akshare / certifi / requests 是否能被定位;WindPy 会实际 import 一次但不会启动连接。 GitHub Actions 自动构建环境不带 WindPy;在装有 Wind API 的本机打包时,APP 会像 DeltaLab 一样优先使用包内 WindPy。若发布包未内置 WindPy,运行时会自动探测本机 Wind 终端;非默认位置可把 CBLENS_WINDPY_PATH 指向 WindPy.py 或其所在目录。

发布桌面包时,Windows 与 macOS 分开处理,避免 CI 中无 WindPy 的 macOS 包覆盖本机 WindPy 版:

  • Windows: 触发 GitHub Actions 的 build-desktop.yml,它只会覆盖 Release 里的 CBLens-Windows.zip
  • macOS: 在装有 Wind API 的本机运行 python scripts/release_macos_desktop.py --tag v1.0.0,脚本会先诊断 WindPy 与缓存数据,再覆盖上传 CBLens-macOS.zip

2. 数据源分工

CBLens 把 静态条款动态行情 分开处理:

数据类型 默认来源 落盘位置 说明
转债条款、转股价、票息、评级、余额 Wind data/cb_data.json 半静态信息,建议定期同步
公告事件 cninfo data/cb_events.json 默认不需要 Wind
停牌、强赎、摘牌、ST、成交额 Wind data/cb_data.json 每日增量刷新
正股/转债行情、历史波动率、股息率、利率 Wind / akshare / CSV 不固定落盘 按行情源选择实时获取
关注池 本地维护 data/watchlist.json GUI 批量页管理,运行态文件默认不提交

Important

字段缺失时,主池准入筛选遵循保守原则:只有明确命中风险条件才剔除,None 不会直接剔除。


3. 首次使用流程

路径 A:有 Wind 环境

建议先建立完整本地条款库,再进入 GUI:

cb-sync-tradable             # 同步全市场基础条款
cb-sync-admission-status     # 刷新准入状态
cb-sync-events --apply       # 同步公告事件
cb-screen-pool               # 查看主池报告
cb-gui                       # 启动 GUI

路径 B:无 Wind 环境

# 验证 PDE 引擎
python CB.py

# 手工输入条款做单只定价
cb-gui

# 若仓库已有 data/cb_data.json,用 akshare 行情
python CB.py 128009.SZ --source akshare

4. GUI 使用

启动方式

cb-gui
#
python -m convertible_bond.gui.app
#
python gui.py

顶部栏功能

元素 功能
深色/浅色模式 切换 Catppuccin Latte/Mocha 主题
Tab 切换 📦 批量 · 🎯 策略 · ⚡ 定价 · 📈 回测 · 🔥 敏感性
行情源 选择 Wind 或 akshare
🌐 同步池 全市场基础信息、准入状态、公告事件同步入口
代码输入 输入 128009.SZ 或六位代码,命中条款库时自动补全
📥 同步 读取本地条款库 + 拉取正股行情、历史波动率与股息率
🔄 刷新 强制用 Wind 刷新当前债条款(下修/评级变更后使用)
💾 / 📂 保存/加载参数预设 (Ctrl+S / Ctrl+O)

快捷键

快捷键 功能
Ctrl + Enter 运行定价
Ctrl + S 保存预设
Ctrl + O 加载预设
Ctrl + D 收敛诊断(开发者调试)

4.1 批量页

批量页是默认首页,适合从全市场池里找复核候选。

操作步骤

  1. 选择行情源
  2. 选择视图:综合机会 / 低估候选 / 转股折价 / 需复核
  3. 设置最低机会分
  4. 点击 刷新重算
  5. 主表查看理论价、市价、偏离、转股溢价、机会分、风险标签
  6. 选中标的 → 加入关注池
  7. 关注池重算 快速更新已关注标的
  8. 导出 CSV 留档

关键指标解读

字段 含义
deviation (市价 - 理论价) / 理论价,负值越大 → 模型认为越低估
undervaluation_rate -deviation,正值表示低估程度
opportunity_score 综合低估、转股折价、HV、余额、评级、久期的排序辅助字段
risk_tags ⚠️ 优先查看:高 HV、极小余额、临近强赎/摘牌、数据缺口
review_notes 模型或数据异常的复核建议

Warning

opportunity_score 不是交易信号。它仅辅助筛选值得人工复核的标的,不能替代投资判断。


4.2 策略页

回放"按规则选债 + 定期调仓"的历史表现, 并与等权基准对比。这是研究诊断工具, 不是收益承诺。

三步上手

  1. 「策略方案」选一个预设 (稳健打底 / 低估轮动 / 折价套利) —— 模板会一键设好 全部参数 (含选券权重、现金收益), 不残留上次手动值; 日期默认近一年;
  2. 点「预检」确认池子与耗时 → 点「运行策略」。历史口径用默认「标准」(分钟级);
  3. 只看三个数: 总收益 vs 等权基准 (净值图虚线, 跑赢没有)、最大回撤 (最深亏多少)、结论卡 (一句话定性)。

参数分层 (该动哪些?)

区域 参数 普通用户建议
基础 策略方案 / 日期 / 频率 用模板 + 默认即可
基础 选债规则 · Top N · 选券权重 模板已设好。两种选券权重均无稳健选股 alpha (见 README"模型边界"), 是研究配置不是推荐
基础 成本 (bps) · 现金收益 (%/年) 默认 20bps / 2.2% 即可。现金收益 = 闲置现金按年化计息 (留现金/缺成交价时生效); 设 0 复现旧口径
高级 回测范围 / 历史口径 / 选债条件区间 深入研究再动

历史口径怎么选

  • 标准: 本地条款 + 补丁 + 事件回放, 分钟级; 历史发生过下修的债可能有转股价跳点偏差。
  • Wind高保真: 逐债逐期从 Wind 拉历史条款, 最准但大池可能数小时; 等价 CLI (cb-strategy-backtest) 配 --cache-dir 后复跑可大幅提速。

结果怎么读 (四条铁律)

  1. 一切对照基准: 总览同时给「等权基准」(全可投池) 与「中证转债指数」两条线, 跑不赢 = 这套规则没有超额, 哪怕绝对收益为正;
  2. 先看「稳健性」卡: 块自助给 Sharpe 置信区间与跑赢基准概率 —— CI 含 0 = 差异 可能只是运气, 别把点估计 (如 Sharpe 0.6 vs 0.4) 当真; 期数越少 CI 越宽;
  3. 机会分是复核标记、不是收益预测; 单一市场周期的回测不构成策略承诺;
  4. 「数据」子页先看条款补丁覆盖率与缺价跳过数 —— 数据质量差时, 先补数据再下结论。

进阶旋钮 (高级研究)

  • 仓位择时: 「估值缩放」按全市场中位偏差调总仓位 (贵→降仓), 是模型唯一跨牛熊· 跨频率稳健的优势 (风险预算工具, 非收益增强); 默认「恒定满仓」。
  • 现金收益: 留现金/缺价/降仓留出的现金按此年化计息 (默认 2.2%≈货基); 设 0 复现旧口径。 注意 Sharpe 课征无风险门槛, 现金 0 计息会系统性低估持现金策略。

CLI 等价命令: cb-strategy-backtest --start 2025-01-01 --end 2026-01-01 --freq M --holding-mode top_score --cash-yield 0.022 --cache-dir .cache/bt (全部参数见 --help)。

4.3 定价页

定价页适合单债深度分析

操作步骤

  1. 输入转债代码 → 点击 📥 同步
  2. 确认自动填充的条款参数(正股价、转股价、票息、到期日等)
  3. 调整模型参数:sigmarqbase_spreaddistress_kp_down
  4. 点击 开始计算(或 Ctrl + Enter
  5. 查看结果:
    • 理论价与市价偏离
    • 纯债价值 / 转股价值 / 期权溢价
    • 希腊值:Δ, Γ, ν, Θ
  6. 输入市价 → 点击 解 IV 反解隐含波动率
  7. 点击 现金流 查看付息和到期兑付计划

参数来源标签

每个输入字段旁标注数据来源(手工 / 条款库 / Wind / akshare / 模型 / 预设),方便追溯。

核心模型参数

参数 含义 单位与默认
sigma 正股年化历史波动率 百分数,默认按窗口历史价估算
r 无风险利率 百分数,可用 Shibor 参考
q 正股连续股息率 百分数,默认从数据源读取,缺失时为 0
base_spread 信用利差 百分数,可按评级填入
p_down 下修事件年化强度 百分数/年
distress_k 正股下跌时信用利差扩张参数 百分数

PDE 中股价风险中性漂移使用 r - q,折现仍使用 r + credit_spread(S)。因此提高 q 通常会压低转股权相关价值。


4.4 回测页

回测页用于复盘模型表现

操作步骤

  1. 在定价页先同步或手工确认当前条款
  2. 切到回测页
  3. 选择开始/结束日期和频率(日/周/月)
  4. 可选:开启 价值分解反解 IV
  5. 点击 运行回测
  6. 分析指标:
    • 理论价曲线 vs 市价曲线
    • IV / HV spread
    • 统计偏差指标

回测会沿用定价页中的 rq、信用利差、下修强度和强赎宽限天数。历史正股价与滚动 sigma 从数据源取数,q 当前作为固定输入参与整段回测。

Note

历史回测默认使用当前条款。发生过下修的债可能出现历史转股价跳点偏差。


4.5 敏感性页

敏感性页生成 σ–S 二维热力图

操作步骤

  1. 先在定价页准备好条款和基础参数
  2. 设置 S (%K)sigma (%) 的扫描范围
  3. 设置网格密度
  4. 点击 运行分析
  5. 查看热力图:颜色深浅对应理论价变化
  6. 点击 PNG 导出报告图

敏感性热力图只扫描 Ssigmarq、信用利差和下修参数保持定价页当前值不变。


5. CLI 命令

单只定价

python CB.py 128009.SZ                              # 自动选源
python CB.py 128009.SZ 2026-04-20 --source auto     # 指定估值日
python CB.py 128009.SZ --source akshare             # 指定 akshare
python CB.py                                        # 离线示例

--source 只选择动态行情源。静态条款优先读取 data/cb_data.json

同步全市场条款

cb-sync-tradable                                   # 全量同步
cb-sync-tradable --info                            # 仅查看状态
cb-sync-tradable --limit 50                        # 限量同步
cb-sync-tradable --codes 113050.SH 128009.SZ       # 指定代码

Tip

典型节奏:月初全量同步;新债上市、下修、评级变更、退市集中发生后补同步。

刷新准入状态

cb-sync-admission-status                           # 全量刷新
cb-sync-admission-status --limit 50                # 限量刷新
cb-sync-admission-status --codes 113050.SH         # 指定代码

刷新字段:停牌、强赎状态、最后交易日、摘牌日、正股 ST、转债成交额、评级、剩余余额等。

同步公告事件

cb-sync-events                                     # 扫描新事件
cb-sync-events --limit 50                          # 限量扫描
cb-sync-events --codes 118006.SH --apply           # 指定代码 + 应用
cb-sync-events --source cninfo --no-pdf            # 跳过 PDF 解析

--apply 会把事件表应用回 cb_data.json(例如强赎公告写入 call_status,不下修写入 down_reset_block_until)。

查看主池筛选

cb-screen-pool                                     # 默认参数
cb-screen-pool --min-rating AA- --min-balance 1    # 严格筛选
cb-screen-pool --min-turnover 10000000 --show-excluded 50

6. Python API

离线模型

from datetime import date
from convertible_bond.pricer import UniversalCBPricer

pricer = UniversalCBPricer(
    S0=55.0,
    K=52.77,
    current_date=date(2026, 4, 20),
    maturity_date=date(2026, 7, 30),
    issue_date=date(2020, 7, 30),
    conversion_start_date=date(2021, 2, 6),
    coupon_rates=(0.003, 0.004, 0.008, 0.015, 0.018, 0.02),
    redemption_price=107.0,
)

price = pricer.price(sigma=0.28, r=0.022, q=0.015, base_spread=0.03)

q 为连续股息率,小数形式。例如 0.015 表示 1.5%/年。

自动取数定价

from convertible_bond.pricing_api import price_from_auto

row = price_from_auto("128009.SZ", prefer="akshare")
print(row["theoretical_price"], row["market_price"], row["sigma"], row["q"])

自动取数定价会调用行情源的 get_stock_dividend_yield()。该接口返回百分数,例如 2.5 表示 2.5%/年;price_from_auto() 返回结果里的 q 已经转换为模型小数,例如 0.025。如果行情源没有返回有效股息率,q 会回退为 0.0

批量定价

from convertible_bond.batch_pricing import build_batch_provider, list_batch_codes_from_cache
from convertible_bond.cache import TermsBundle, project_bundle_path
from convertible_bond.pricing_api import batch_price_from_provider_threaded

bundle = TermsBundle(project_bundle_path())
codes = list_batch_codes_from_cache(bundle)[:50]
provider = build_batch_provider("akshare", terms_cache=bundle)

rows = batch_price_from_provider_threaded(provider, codes, max_workers=4)
rows = [row for row in rows if row.get("status") == "ok"]

7. 数据文件

文件 用途 手工编辑
data/cb_data.json 全市场条款与准入状态 ❌ 一般不要
data/cb_events.json 结构化公告事件 ❌ 由同步维护
data/down_reset_overrides.json 人工下修覆盖 ✅ 可以手工维护
data/watchlist.json 关注池 ✅ 可由 GUI 管理,默认忽略
data/batch_pricing_cache.json 批量定价缓存 ❌ 自动生成,默认忽略

Note

JSON 写入采用 .tmprename 的原子写模式,避免半截文件。


8. 常见问题

❓ WindPy import 失败

确认 Wind 终端已安装 Python 接口到当前 venv:

which python
python -c "from WindPy import w; print(w)"

如果路径不匹配,需要在 Wind 终端中重新选择正确的 Python 路径。

❓ akshare 能取行情但不能同步条款

这是预期行为。akshare 动态行情可用,但完整转债条款(强赎/回售触发比例、回售观察期、完整付息计划)仍以 Wind 写入的 cb_data.json 为准。

❓ GUI 输入代码后字段为空

先确认条款库里有这只债:

cb-sync-tradable --info
cb-sync-tradable --codes 128009.SZ

❓ 批量结果出现大量失败

先缩小范围定位问题:

cb-screen-pool --show-excluded 50
cb-sync-admission-status --limit 50
cb-sync-events --limit 50 --apply

如果是网络或数据源问题,换行情源或降低并发后再跑。

❓ 理论价和市价偏差很大

优先检查以下几项:

  • 转股价是否刚下修但本地条款未刷新
  • 是否已公告强赎、摘牌或停牌
  • 正股价、转债市价和估值日是否同日
  • HV 是否异常高,导致期权价值被放大
  • 股息率 q 是否缺失或口径异常,尤其是高股息正股
  • 余额、评级、转股溢价是否触发风险标签

❓ 股息率 q 为什么是 0

Wind 或 akshare 未返回有效股息率时,系统会保守回退到 0,避免数据缺口直接阻断定价。可以在定价页手工输入 q (%) 后重新计算;保存参数预设时,q 也会一并保存。


9. 测试

# 全量
pytest

# 快速失败
pytest -x -q

# 按模块
pytest tests/test_pricer.py -x -q
pytest tests/test_pricing_api.py -x -q
pytest tests/test_batch_pricing.py -x -q

📘 CBLens 使用文档 · 更多信息见 README