之前分享了一篇PE、PB、PEG等核心指标的解释,以及概要的说了一下怎么用这些指标来判断是否值得投资。
下面是将这个思考过程转换成Python的形式,输入对应的数据指标,就会输出对应的结果。
如何获取这些指标,我也在后面罗列了~
但是光看数据是很难Cover所有的方面和风险,只能说做一个简陋的预测,还有很多的不可控因素以及未预料到的因素。
投资需谨慎,没有极高的确定性,空仓才是最大的智慧。
运行效果如下:
class ValuationAnalyzer:
def __init__(self, data):
self.data = data
self.results = {}
self._validate_data()
def _validate_data(self):
"""检查必要数据是否存在"""
required_fields = ['current_price', 'net_profit', 'shares', 'equity']
missing = [field for field in required_fields if field not in self.data]
if missing:
raise ValueError(f"缺少必要字段: {missing}")
def _print_header(self, title):
"""打印步骤标题"""
print(f"\n{'=' * 30}")
print(f"* 正在计算: {title}")
print(f"{'=' * 30}")
def calculate_pe(self):
"""计算市盈率及分析"""
self._print_header("市盈率(PE)")
eps = self.data['net_profit'] / self.data['shares']
print(
f" → 每股收益(EPS) = 净利润 {self.data['net_profit']}亿 / 股本 {self.data['shares']}亿 = {eps:.2f} 元/股")
pe = self.data['current_price'] / eps
print(f" → PE = 股价 {self.data['current_price']}元 / EPS {eps:.2f}元 = {pe:.2f} 倍")
# 行业对比逻辑示例
industry_pe = 15.0 # 假设行业平均PE为15
print(f"\n[分析建议]")
print(f" 当前PE为行业平均的 {pe / industry_pe * 100:.1f}%")
if pe < industry_pe:
print(" → 可能被低估(需结合增长性验证)")
else:
print(" → 可能被高估(检查是否有高增长支撑)")
self.results['PE'] = pe
def calculate_peg(self):
"""计算PEG比率"""
if 'growth_rate' not in self.data:
print("\n[警告] 缺少增长率数据,跳过PEG计算")
return
self._print_header("PEG比率")
pe = self.results.get('PE', None)
if not pe:
self.calculate_pe()
pe = self.results['PE']
growth = self.data['growth_rate'] / 100
peg = pe / (growth * 100) # 增长率转换为百分比
print(f" → PEG = PE {pe:.2f} / 增长率 {self.data['growth_rate']}% = {peg:.2f}")
print("\n[分析建议]")
if peg < 0.5:
print(" → 显著低估(需核实增长预测可靠性)")
elif 0.5 <= peg < 1:
print(" → 合理偏低(可能具备投资价值)")
elif 1 <= peg < 1.5:
print(" → 合理估值")
else:
print(" → 可能高估(增长无法支撑当前估值)")
self.results['PEG'] = peg
def calculate_pb(self):
"""计算市净率"""
self._print_header("市净率(PB)")
bvps = self.data['equity'] / self.data['shares']
print(
f" → 每股净资产(BVPS) = 股东权益 {self.data['equity']}亿 / 股本 {self.data['shares']}亿 = {bvps:.2f} 元/股")
pb = self.data['current_price'] / bvps
print(f" → PB = 股价 {self.data['current_price']}元 / BVPS {bvps:.2f}元 = {pb:.2f} 倍")
print("\n[分析建议]")
if pb < 1:
print(" → 破净股(需检查资产质量是否恶化)")
elif 1 <= pb < 2:
print(" → 合理区间(传统行业常见)")
else:
print(" → 高溢价(可能反映无形资产价值)")
self.results['PB'] = pb
def generate_report(self):
"""生成最终报告"""
print("\n\n" + "=" * 50)
print("估值分析最终报告".center(50))
print("=" * 50)
for metric, value in self.results.items():
print(f"- {metric}: {value:.2f}")
print("\n[重要提示]")
print("请结合以下因素综合判断:")
print("1. 行业特性(周期/成长)")
print("2. 财务报表质量(审计意见)")
print("3. 管理团队背景")
print("4. 宏观经济环境")
# 示例数据(可修改为最新数据)
company_data = {
'current_price': 25.00, # 当前股价(元)
'net_profit': 50.0, # 最近12个月净利润(亿元)
'shares': 20.0, # 总股本(亿股)
'equity': 600.0, # 净资产(亿元)
'growth_rate': 35.0, # 预期未来3年净利润增长率(%)
'revenue': 300.0, # 营业收入(亿元)
'total_debt': 200.0, # 总负债(亿元)
}
if __name__ == "__main__":
try:
analyzer = ValuationAnalyzer(company_data)
analyzer.calculate_pe()
analyzer.calculate_pb()
analyzer.calculate_peg()
analyzer.generate_report()
except Exception as e:
print(f"错误发生: {str(e)}")
怎么获取这些参数?
一、基础数据获取路径
1. 当前股价
- 手机端:
- 同花顺/东方财富APP → 搜索股票代码(如赛力斯:601127) → 实时行情页查看
- PC端:
- 新浪财经(finance.sina.com.cn)→ 输入代码查询
- 雪球(xueqiu.com)→ 个股页查看实时价格
2. 每股收益(EPS)
- 获取路径:
- 公司财报 → 利润表 → “归属于母公司股东的净利润” ÷ 总股本
- 直接查看:
- 同花顺F10 → 财务概况 → 主要指标 → “基本每股收益”
- 东方财富网 → 个股页 → 财务分析 → 每股指标
3. 每股净资产
- 计算公式:
每股净资产 = 归属于母公司股东权益合计 ÷ 总股本
- 快速获取:
- 雪球个股页 → 财务 → 资产负债表 → “股东权益合计”
- 理杏仁(lixinger.com)→ 搜索股票 → 财务指标 → 资产负债表
4. 净利润
- 官方来源:
- 上交所/深交所官网 → 公司公告 → 定期报告(年报/季报)
- 巨潮资讯网(cninfo.com.cn)→ 输入代码查财报
- 第三方平台:
- 同花顺F10 → 财务概况 → 利润表 → “净利润”
5. 营收增长率
- 计算方法:
近1年营收增长率 = (本期营业收入 - 上期营业收入) ÷ 上期营业收入 × 100%
- 数据获取:
- 公司财报 → 利润表 → 连续两期"营业收入"数据
- Choice数据终端 → 财务数据 → 成长能力指标
二、进阶数据获取技巧
1. 总市值计算
- 手动计算:
总市值 = 当前股价 × 总股本
- 直接获取:
- 同花顺个股页 → 盘口信息 → “总市值”
- 腾讯证券(stockhtm.finance.qq.com)→ 输入代码查看
2. 行业平均PE/PB
- 行业对比工具:
- 东方财富网 → 行业中心 → 选择"汽车制造"等 → 查看行业市盈率
- 理杏仁 → 行业分析 → 申万行业分类 → 下载行业PE/PB中位数
3. 预期增长率
- 专业平台:
- Wind金融终端 → 盈利预测 → 查看机构一致预期
- 慧博投研(hibor.com)→ 研报汇总 → 提取分析师预测均值
四、数据获取注意事项
- 时间一致性:
- 确保股价与财报数据时间匹配(如用Q3财报时,取季度末收盘价)
- 会计准则差异:
- 国际公司数据需用IFRS准则(如港股用港元计价)
- 数据验证:
- 交叉核对三大报表勾稽关系:
现金流量表净额 ≈ 净利润 + 非现金支出 - 营运资本变动
- 交叉核对三大报表勾稽关系:
- 特殊处理:
- 新股/ST股需注意财务数据异常(如借壳上市资产重组)
五、推荐数据工具清单
工具类型 | 推荐工具 | 特点 |
---|---|---|
免费终端 | 同花顺、东方财富、雪球 | 基础数据齐全,适合小白 |
付费终端 | Wind、Choice、Capital IQ | 含深度财务分析和行业对比 |
国际数据 | Yahoo Finance、Morningstar | 美股/港股数据 |
研报平台 | 慧博投研、迈博汇金 | 获取分析师预测数据 |
数据清洗 | 八爪鱼、Python爬虫 | 批量获取历史财务数据 |
六、常见问题解决方案
Q1:找不到"归属于母公司股东权益"怎么办?
- 解决方案:在资产负债表查找以下科目相加:
归属于母公司股东权益 = 股本 + 资本公积 + 盈余公积 + 未分配利润
Q2:如何处理非经常性损益?
- 调整方法:使用"扣非净利润"替代净利润计算PE
(数据来源:利润表 → “扣除非经常性损益后的净利润”)
Q3:总股本变动如何处理?
- 应对策略:使用最新股本数据(定期报告披露限售股解禁情况)