市赚率(PR)股票筛选器
> 基于 ericwarn丁宁(雪球2024十大影响力用户,近10年年化20%)公众号/雪球十年投资体系的市赚率估值方法。AI agent 读取本文档后即可独立完成估值计算,无需依赖外部脚本。
核心能力
当用户提出市赚率估值需求时,AI agent 应直接使用本文档中的公式执行计算并输出结果。如果有外部脚本可用(scripts/pr_calculator.py),优先使用脚本以保证计算精度;如果脚本不可用,直接按本文公式计算。
一、计算引擎(可直接执行)
1.1 输入参数提取
从用户输入中提取以下参数。如果任何必填参数缺失或无效,必须明确告知用户缺少什么、示例格式是什么,绝不允许静默失败。
| 参数 | 是否必填 | 格式要求 | 无效示例 | 正确示例 |
|---|---|---|---|---|
| PE | 价值股/银行股必填 | 正数,如 15.0 | 负数、0、"未知" | --pe 15.0 |
| PB | 周期股必填 | 正数,如 2.3 | 负数、0 | --pb 2.3 |
| ROE | 价值股/银行股必填 | 正数(百分号前数字),如 20 | ≤0、>100 需确认 | --roe 20(表示 20%) |
| ROA | 衍生公式必填 | 正数,如 12 | ≤0 | --roa 12 |
| payout | 银行股强烈建议 | 0~1 之间,如 0.5 | >1、负数 | --payout 0.5(表示 50%) |
| roe_list | 周期股建议 | 逗号分隔数字,如 "15,18,20" | 单个值、非数字 | --roe-list "15,18,20,22,16" |
| growth | 可选 | 正数 | 负数 | --growth 15 |
输入验证规则(强制执行):
1. PE/PB/ROE/ROA 不能为 0 或负数 → 报错:"XX 参数必须大于 0,请提供有效的财务数据"
2. payout 如果提供,必须在 0~1 之间 → 报错:"股利支付率应在 0~1 之间(如 0.5 表示 50%),当前值: {value}"
3. roe_list 至少需要 3 个值 → 提示:"周期股需要至少 3 年的 ROE 数据,当前仅提供 {n} 个"
4. ROE > 100 → 警告:"ROE={value}% 异常偏高,请确认数据正确性,建议使用衍生公式"
5. ROE < 0 → 报错:"ROE 不能为负数,亏损企业无法用市赚率估值"
6. 如果 type=bank 但未提供 payout → 提示:"银行股建议提供 --payout(股利支付率)以获得修正市赚率,否则仅显示基础 PR"
1.2 核心计算公式
公式一:价值股 / 银行股 / 保险股
base_pr = PE / ROE (ROE 取百分号前数字,如 20 表示 20%)
股利支付率修正(仅当提供了 payout 参数时):
if payout >= 0.50:
N = 1.0
elif payout <= 0.25:
N = 2.0
else:
N = 0.50 / payout (线性插值,上限 2.0)
adjusted_pr = N * base_pr
final_pr = adjusted_pr (有修正时使用修正值)
示例计算(格力电器):
- PE=8.5, ROE=22.8, payout=0.65
- base_pr = 8.5 / 22.8 = 0.3728
- N = 1.0(payout ≥ 50%)
- adjusted_pr = 1.0 × 0.3728 = 0.3728
- final_pr = 0.3728
公式二:周期股
single_pr = PB / (ROE²) * 100 (ROE 取百分号前数字)
如果提供了 roe_list(多年 ROE 列表),计算三种方法:
avg_roe = sum(roe_list) / len(roe_list)
avg_pr = PB / (avg_roe²) * 100
median_roe = 排序后的中位数
median_pr = PB / (median_roe²) * 100
trimmed_roe = 去掉最高最低后的平均值(需 ≥3 个数据)
trimmed_pr = PB / (trimmed_roe²) * 100
# 综合判断
if 三种方法都 ≤ 0.6: consensus = "低估"
elif 三种方法都 ≥ 1.0: consensus = "高估"
else: consensus = "分歧"
final_pr = avg_pr(默认使用平均值法)
示例计算(中国石油 H 股——验证丁宁案例):
- PB=0.96, ROE=15.88
- single_pr = 0.96 / (15.88²) * 100 = 0.96 / 252.17 * 100 = 0.3807
- final_pr ≈ 0.38 ✓(与丁宁原文一致)
公式三:衍生市赚率(高杠杆 / ROE 异常)
derivative_pr = PE / (1.5 * ROA)
final_pr = derivative_pr
公式四:PEG(成长股 / 科技股)
peg = PE / growth_rate
# PEG ≤ 0.6: 低估 | 0.6~0.8: 偏低 | 0.8~1.0: 合理 | >1.0: 高估
1.3 卖出阈值计算
if is_hk:
if hk_tax <= 0.20:
sell_threshold = 0.80
else:
sell_threshold = 0.72
else:
sell_threshold = 1.0
if is_low_rate:
sell_threshold = min(sell_threshold * 1.3, 1.4)
1.4 估值状态判定
if final_pr <= 0.4: → "黄金击球区 ⭐⭐⭐ (PR≤0.4,4折重仓买入)"
elif final_pr <= 0.5: → "深度低估 ⭐⭐ (0.4<PR≤0.5,5折重点买入)"
elif final_pr <= 0.6: → "低估区间 ⭐ (0.5<PR≤0.6,可分批布局)"
elif final_pr <= 0.8: → "偏低区间 (0.6<PR≤0.8,观察等待,不追高)"
elif final_pr <= sell_threshold: → f"合理偏高 (PR≤{sell_threshold},接近合理估值)"
else: → f"高估区间 ⚠️ (PR>{sell_threshold},考虑分批卖出)"
1.5 边界条件检查
warnings = []
if ROE < 10: → "⚠️ ROE={ROE}% < 10%,市赚率可能失真失效(银行股尤甚)"
if ROE > 40: → "⚠️ ROE={ROE}% > 40%,可能因高杠杆虚高,建议改用衍生公式 PE/(1.5×ROA)"
if ROE > 100: → "⚠️ ROE={ROE}% 极高,强烈建议改用衍生公式并人工复核"
if PE <= 0: → "❌ PE 无效(亏损企业无法用市赚率估值)"
1.6 增长率分析
ideal_growth = ROE / 2
min_growth = ROE / 3
if growth >= ideal_growth: → "✅ 增长率优秀({growth}% ≥ 理想 {ideal_growth}%)"
elif growth >= min_growth: → "✅ 增长率达标({growth}% ≥ 最低 {min_growth}%)"
else: → "⚠️ 增长率不达标({growth}% < 最低 {min_growth}%),投资复利与 ROE 脱钩,建议改用股息率估值法"
1.7 银行拨备覆盖率检查
if coverage >= 300: → "✅ 安全边际充足(≥300%)"
elif coverage >= 200: → "⚠️ 安全边际一般(200%~300%)"
elif coverage >= 150: → "⚠️ 安全边际偏低(150%~200%)"
else: → "❌ 安全边际不足(<150%),丁宁建议不买入"
1.8 行业标杆映射
标杆映射表:
白酒→贵州茅台 | 保险→中国平安 | 煤炭→中国神华H
石油→中国海油H | 券商→中国银河H | 银行→招商银行H | 家电→美的集团
卖出规则:行业标杆 PR 突破阈值后,一并卖出同行业所有股票
阈值:A股标杆 1.0PR,H股标杆 0.8PR
不可被消灭的必需行业(丁宁逆向投资原则):
✅ 白酒 ✅ 家电 ✅ 石油 ✅ 煤炭 ✅ 银行 ✅ 保险
二、输出格式模板
计算完成后,按以下模板输出结果:
============================================================
📊 市赚率(PR)估值结果 — {股票名称}({股票代码})
============================================================
【输入数据】
市盈率(PE): {pe}
ROE: {roe}%
股利支付率: {payout}%(如有)
市场: {A股/H股}(如H股则标注税率和卖出阈值)
【边界检查】
{warnings 逐条显示,无则显示"✅ 数据正常"}
【计算过程】
公式: {formula}
基础市赚率: {base_pr} = {pe} / {roe}
{如有股利修正} 修正系数 N: {N} = 50% / {payout}
{如有股利修正} 修正市赚率: {adjusted_pr} = {N} × {base_pr}
{周期股} 平均值法 PR={avg_pr} | 中位数法 PR={median_pr} | 去极值法 PR={trimmed_pr}
{周期股} 三法综合判断: {consensus}
【增长率分析】(如有 growth 参数)
要求: ≥ {ideal_growth}%(理想)/ ≥ {min_growth}%(最低)
实际: {growth}% → {评价}
【银行拨备】(如有 provision_coverage 参数)
拨备覆盖率: {coverage}% → {评价}
【行业标杆】(如提供了 industry 参数)
标杆: {标杆股票} | 卖出规则: {规则}
────────────────────────────────────────
🏁 最终市赚率: {final_pr}
📈 估值状态: {status}
【操作建议】
{根据 PR 区间给出具体建议}
============================================================
三、场景处理流程
场景 A:用户提供完整数据
直接执行第一章的计算引擎,输出第二章的格式模板。
场景 B:用户只提股票名称,未提供数据
- 使用 WebSearch 搜索 "{股票名称} PE TTM ROE 股利支付率 2026"
- 从搜索结果中提取 PE(TTM)、ROE、股利支付率
- 如果搜索不到,明确告知用户:"未搜索到 {股票名称} 的最新财务数据,请手动提供 PE 和 ROE"
- 判断股票类型(根据行业自动选择公式)
- 执行计算并输出
场景 C:用户要求批量筛选
- 如果用户提供 JSON 文件路径,使用
scripts/pr_screener.py - 如果没有文件,先通过 WebSearch 收集目标行业股票数据
- 构造临时 JSON 文件,调用筛选脚本
- 输出排序后的筛选结果
场景 D:用户输入数据异常
- 先执行输入验证规则(1.1 节)
- 对每个异常参数给出具体错误信息和正确示例
- 如果可以部分计算(如缺少 payout 但 PE/ROE 完整),给出基础 PR 并标注"缺少 XX 参数,结果仅供参考"
- 绝不允许静默失败或输出空结果
四、外部脚本(可选加速)
当需要批量处理或高精度计算时,可调用外部脚本。脚本位于 skill 目录下的 scripts/ 中。
pr_calculator.py — 单股计算
python3 {skill_dir}/scripts/pr_calculator.py \
--type value \ # value/cyclical/bank/derivative/peg
--pe 15.0 \ # 市盈率
--roe 20.0 \ # ROE 百分号前数字
--payout 0.5 \ # 股利支付率(可选)
--is-hk \ # H股标记(可选)
--industry 白酒 # 行业(可选)
pr_screener.py — 批量筛选
python3 {skill_dir}/scripts/pr_screener.py \
-i stocks.json \ # 输入 JSON 文件
--type all \ # value/cyclical/bank/all
--max-pr 0.6 \ # 最高市赚率
--benchmark # 显示行业标杆
> 注意:{skill_dir} 需替换为 skill 实际安装路径。如果脚本不可用,直接使用本文第一章的内嵌计算引擎。
五、示例数据(用于测试)
文件 assets/sample_stocks.json 包含 20 只 A/H 股样本数据,可用于测试批量筛选功能。
快速测试命令:
python3 {skill_dir}/scripts/pr_calculator.py --type value --pe 16.7 --roe 30.7 --payout 0.8
# 预期输出: 苏泊尔 PR=0.544,低估区间 ⭐
python3 {skill_dir}/scripts/pr_calculator.py --type cyclical --pb 0.96 --roe 15.88
# 预期输出: 中国石油 PR=0.381,黄金击球区 ⭐⭐⭐(与丁宁原文一致)
六、常见错误排查
| 错误现象 | 原因 | 解决方案 |
|---|---|---|
| "ROE必须大于0" | 输入了负数或0 | 确认 ROE 应为正数(百分号前数字) |
| 计算结果与预期不符 | ROE 格式错误 | ROE 应取百分号前数字,如 20% 取 20,而非 0.20 |
| 周期股 PR 数值异常大 | 公式用错 | 周期股用 PB/ROE²×100,不用 PE/ROE |
| 银行股基础 PR 很低但修正后很高 | 股利支付率低 | 修正系数 N>1 会拉高 PR,这是正常的 |
| H股和A股相同PE/ROE但卖出建议不同 | 税率修正 | H股有20%~28%股息税,卖出阈值更低 |
| ROE<10% 时计算结果 | 市赚率失真 | 显示警告,建议改用其他估值方法 |
七、重要注意事项
- 先定性后定量:先判断企业商业模式、行业地位和 ROE 稳定性,再用 PR 找好价格
- 不适用场景:亏损股(PE无效)、净现金过多公司、ROE<10%银行股、ROE靠高杠杆堆出的公司
- 增长率补充:理想增长率≥ROE/2,最低≥ROE/3;不达标则投资复利与ROE脱钩
- 周期股三法:平均值、中位数、去极值三种方法都低估才是真低估
- 分红修正适用范围:仅限ROE稳定的价值股,不适用于周期股、科技股、成长股
- H股阈值不同:A股1.0高估 vs H股0.8(20%税)/ 0.72(28%税)
- 交易纪律:PR跌到0.4~0.6才建仓,到1.0分批卖出;基本面破坏无条件止损
- 行业标杆法:龙头高估后一并卖出同行业所有股票
- 模糊正确:市赚率追求模糊正确而非精确错误,是定量初筛工具而非终极决策依据
八、巴菲特案例验证
| 年份 | 标的 | ROE | 买入PE | PR | 策略 |
|---|---|---|---|---|---|
| 1988 | 可口可乐 | 31% | 14.7 | 0.474 | 内忧外患中建仓 |
| 1989 | 可口可乐 | 46% | 15 | 0.326 | 两年平均 0.4PR |
| 1990 | 富国银行 | 23.3% | 4.32 | 0.19 | 地产危机,次年业绩崩盘 |
| 2003 | 中国石油 | 15.9% | 0.96PB | 0.38 | 周期股公式计算 |
| 2016 | 苹果 | 36.9% | 13.19 | 0.36 | 业绩短暂下滑时买入 |
> 丁宁统计:巴菲特 90% 的投资案例符合市赚率低估买入标准。
九、资源文件
scripts/(可选辅助工具)
pr_calculator.py— 市赚率单股计算器,5种估值模式 + 完整异常处理pr_screener.py— 市赚率批量筛选器,行业自动分类 + 标杆标注
references/
pr_method.md— 市赚率估值体系完整参考
assets/
sample_stocks.json— 20只多行业 A/H 股样本数据