当前位置: 首页 > news >正文

传统观念:市盈率越低股票越值得买,编程批量筛选低PE个股,统计后续一年超额收益,识别低PE陷阱。

低 PE 个股批量筛选与"低 PE 陷阱"识别工具(教学级量化价值投资原型)

内容包含免责声明和风险提示,不荐股、不推荐任何投资产品、不引导开户、无任何引流。

一、实际应用场景描述

在智能证券投资课程中,价值投资(Value Investing)与估值陷阱(Value Trap)是核心教学内容。

本程序适用于:

- 高校量化投资、证券分析课程实验

- 投资者教育(Investor Education)

- 基本面量化筛选教学

- 批判性思维训练(打破"低 PE = 便宜"的迷思)

核心目标:

- 批量筛选低 PE(市盈率)个股

- 统计后续一年超额收益(相对大盘)

- 识别低 PE 陷阱(低 PE 但持续跑输)

- 用数据回答:"PE 越低,股票越值得买吗?"

✅ 不做未来预测

✅ 不构成投资建议

✅ 仅作为历史数据统计教学工具

二、痛点引入(真实可感知)

痛点 表现

PE 迷信 "PE 才 5 倍,肯定便宜"

忽略基本面恶化 业绩下滑导致 PE 被动降低

价值陷阱 低 PE 买入后继续下跌

缺乏统计 不知道低 PE 策略长期到底行不行

工具门槛高 专业选股平台复杂,散户望而却步

👉 需要一个轻量、本地、可解释、可复现的低 PE 策略回测工具

三、核心逻辑讲解(工程视角)

1️⃣ 数据模型设计

StockPE

├── symbol 股票代码

├── name 股票名称

├── pe 市盈率(TTM 或静态)

├── year_return 买入后一年涨幅(%)

└── index_return 同期大盘涨幅(%)

2️⃣ 核心筛选逻辑(教学用)

步骤 操作

① 设定 PE 阈值(如 PE < 15)

② 批量筛选符合条件的个股

③ 统计买入后一年涨跌幅

④ 对比同期大盘涨跌幅

⑤ 计算超额收益

3️⃣ 关键公式

超额收益:

超额收益 = 个股一年涨幅 − 大盘同期涨幅

低 PE 陷阱判定(教学用):

if 超额收益 < −10%:

标记为"疑似低 PE 陷阱"

⚠️ 教学中强调:这只是统计信号,不是"绝对真理"。

4️⃣ 统计维度

指标 含义

低 PE 样本数 符合筛选条件的个股数量

平均超额收益 低 PE 组合 vs 大盘

胜率 跑赢大盘的比例

陷阱比例 超额收益 < −10% 的比例

最佳 / 最差个例 极端案例展示

5️⃣ 设计原则

- 不美化低 PE 策略

- 不妖魔化高 PE

- 让数据自己说话

四、Python 模块化代码(可直接运行)

📁 项目结构

low_pe_trap_detector/

├── main.py

├── models.py

├── screener.py

├── analyzer.py

├── reporter.py

├── storage.py

├── README.md

└── DISCLAIMER.md

✅ models.py(数据建模)

"""

models.py

低 PE 个股数据模型

"""

class StockPE:

"""个股 PE 与后续表现"""

def __init__(self, symbol, name, pe, year_return, index_return):

"""

symbol: 股票代码

name: 股票名称

pe: 市盈率

year_return: 买入后一年涨幅(%)

index_return: 同期大盘涨幅(%)

"""

self.symbol = symbol

self.name = name

self.pe = pe

self.year_return = year_return

self.index_return = index_return

def excess_return(self):

"""超额收益 = 个股 − 大盘"""

return self.year_return - self.index_return

✅ screener.py(PE 筛选器)

"""

screener.py

低 PE 个股批量筛选

"""

def screen_low_pe(stocks, pe_threshold=15):

"""

筛选 PE 低于阈值的个股

"""

return [s for s in stocks if s.pe < pe_threshold and s.pe > 0]

✅ analyzer.py(核心分析引擎)

"""

analyzer.py

低 PE 策略效果与陷阱识别

"""

import numpy as np

def analyze(stocks, pe_threshold=15):

"""对低 PE 样本进行统计分析"""

screened = [s for s in stocks if s.pe < pe_threshold and s.pe > 0]

total = len(screened)

if total == 0:

return None

# 超额收益

excess_returns = [s.excess_return() for s in screened]

# 胜率

win_count = sum(1 for er in excess_returns if er > 0)

win_rate = win_count / total * 100

# 低 PE 陷阱(超额收益 < −10%)

trap_count = sum(1 for er in excess_returns if er < -10)

trap_rate = trap_count / total * 100

# 跑输大盘比例

lose_count = sum(1 for er in excess_returns if er < 0)

lose_rate = lose_count / total * 100

return {

"pe_threshold": pe_threshold,

"total_screened": total,

"avg_excess_return": round(np.mean(excess_returns), 2),

"median_excess_return": round(np.median(excess_returns), 2),

"win_rate": round(win_rate, 2),

"lose_rate": round(lose_rate, 2),

"trap_rate": round(trap_rate, 2),

"max_excess": round(max(excess_returns), 2),

"min_excess": round(min(excess_returns), 2),

"std_excess": round(np.std(excess_returns), 2)

}

✅ reporter.py(分析报告输出)

"""

reporter.py

低 PE 策略分析报告 + 陷阱识别

"""

def report(stocks, stats, pe_threshold):

print("\n" + "=" * 65)

print("【低 PE 策略效果与陷阱识别报告】")

print("=" * 65)

# 逐条明细

print(f"\n📋 低 PE 个股明细(PE < {pe_threshold}):")

print("-" * 65)

for s in stocks:

if s.pe >= pe_threshold or s.pe <= 0:

continue

er = round(s.excess_return(), 2)

status = "✅ 跑赢" if er > 0 else "❌ 跑输"

trap = " ⚠️ 陷阱" if er < -10 else ""

print(f" {s.symbol} {s.name}")

print(f" PE:{s.pe} | 个股涨幅:{s.year_return}%")

print(f" 大盘涨幅:{s.index_return}% | 超额:{er}% {status}{trap}")

if stats is None:

print(f"\n⚠️ PE < {pe_threshold} 的个股数量为 0,无法统计")

return

# 汇总

print(f"\n📊 统计汇总(PE < {stats['pe_threshold']}):")

print("-" * 65)

print(f" 筛选样本数:{stats['total_screened']} 只")

print(f" 平均超额收益:{stats['avg_excess_return']}%")

print(f" 中位超额收益:{stats['median_excess_return']}%")

print(f" 胜率(跑赢大盘):{stats['win_rate']}%")

print(f" 跑输大盘比例:{stats['lose_rate']}%")

print(f" 低 PE 陷阱比例(超额 < −10%):{stats['trap_rate']}%")

print(f" 最佳个例:+{stats['max_excess']}%")

print(f" 最差个例:{stats['min_excess']}%")

print(f" 超额收益标准差:{stats['std_excess']}%")

print("\n" + "=" * 65)

# 教学结论

print(f"\n💡 教学启示:")

print("-" * 65)

if stats['win_rate'] < 50:

print(f" ⚠️ 胜率仅 {stats['win_rate']}%,低 PE 策略并非稳赚")

elif stats['win_rate'] < 60:

print(f" ⚠️ 胜率 {stats['win_rate']}% 仅略高于随机")

if stats['trap_rate'] > 20:

print(f" ⚠️ {stats['trap_rate']}% 的低 PE 个股超额收益 < −10%")

print(f" → 存在明显的"价值陷阱"风险")

if stats['avg_excess_return'] < 0:

print(f" ⚠️ 平均超额收益为负({stats['avg_excess_return']}%)")

print(f" → 低 PE 组合整体跑输大盘")

if stats['std_excess'] > 20:

print(f" ⚠️ 超额收益离散度大(σ = {stats['std_excess']}%)")

print(f" → 个股分化严重,需精选而非"一篮子"买入")

print(f"\n 核心结论:")

print(f" PE 只是估值的一个维度,低 PE ≠ 便宜 ≠ 值得买。")

print(f" 需结合净利润质量、行业前景、现金流等综合判断。")

print("=" * 65)

✅ storage.py(本地存储)

"""

storage.py

JSON 本地存储

"""

import json

FILE_PATH = "low_pe_analysis.json"

def save_result(data):

with open(FILE_PATH, "w", encoding="utf-8") as f:

json.dump(data, f, ensure_ascii=False, indent=2)

✅ main.py(交互入口)

"""

main.py

低 PE 个股筛选与陷阱识别工具

"""

from models import StockPE

from screener import screen_low_pe

from analyzer import analyze

from reporter import report

from storage import save_result

def main():

print("=== 低 PE 策略效果与陷阱识别工具(教学版)===")

print("量化「市盈率越低股票越值得买」是否成立\n")

stocks = []

while True:

symbol = input("股票代码(空结束):")

if not symbol:

break

name = input("股票名称:")

pe = float(input("市盈率(PE):"))

year_ret = float(input("买入后一年涨幅(%):"))

index_ret = float(input("同期大盘涨幅(%):"))

stocks.append(StockPE(symbol, name, pe, year_ret, index_ret))

if not stocks:

print("⚠️ 未录入数据,退出")

return

pe_threshold = float(input("PE 筛选阈值(默认 15):") or "15")

# 筛选

screened = screen_low_pe(stocks, pe_threshold)

# 分析

stats = analyze(stocks, pe_threshold)

# 输出报告

report(screened, stats, pe_threshold)

# 保存结果

result_data = {

"pe_threshold": pe_threshold,

"total_stocks": len(stocks),

"screened_count": len(screened),

"stats": stats,

"details": [

{

"symbol": s.symbol,

"name": s.name,

"pe": s.pe,

"year_return": s.year_return,

"index_return": s.index_return,

"excess_return": round(s.excess_return(), 2)

}

for s in screened

]

}

save_result(result_data)

print("\n✅ 分析结果已保存")

if __name__ == "__main__":

main()

五、README 与使用说明

# 低 PE 策略效果与陷阱识别工具(教学版)

## 项目说明

批量筛选低 PE 个股,统计后续一年超额收益,识别低 PE 价值陷阱。

## 使用方式

```bash

pip install numpy

python main.py

```

## 输入示例

```

股票代码:600519

股票名称:贵州茅台

市盈率(PE):35

买入后一年涨幅(%):18.5

同期大盘涨幅(%):8.2

```

## 核心指标说明

| 指标 | 含义 |

|---|---|

| 超额收益 | 个股涨幅 − 大盘涨幅 |

| 胜率 | 超额收益 > 0 的比例 |

| 低 PE 陷阱 | 超额收益 < −10% 的个股 |

| 中位超额收益 | 剔除极端值后的典型表现 |

## 适用范围

- 量化投资课程

- 价值投资策略教学

- 基本面量化筛选演示

## 注意事项

- 仅基于历史数据

- 不构成任何投资建议

- 使用前请阅读 DISCLAIMER.md

六、DISCLAIMER.md(免责声明与风险提示)

# 免责声明与风险提示

## 免责声明

本程序仅供**教学与科研用途**,用于演示低 PE 策略的统计分析方法。

作者不提供任何证券交易建议,不推荐任何股票,不承诺任何收益。

## 风险提示

1. 历史统计不代表未来表现,"胜率 55%"≠"下次一定对"

2. PE 计算方式多样(静态 / TTM / 动态),结论可能不同

3. 低 PE 可能反映基本面恶化而非"被低估"

4. 行业差异巨大(银行 PE 天然偏低,科技股偏高)

5. 退市股未被计入,可能存在幸存者偏差

6. 一年持有期仅为教学假设,不代表最佳持有周期

使用本工具产生的任何后果,作者概不负责。

七、核心知识点卡片(教学向)

分类 内容

Python 类、列表推导、条件过滤、NumPy 统计

量化金融 PE 估值、超额收益、胜率统计

价值投资 估值陷阱(Value Trap)识别

批判性思维 打破"低 PE = 便宜"的迷思

数据分析 均值 vs 中位数、标准差、分布特征

工程思想 模块化、筛选器与分析师解耦

可扩展性 可接入财务数据 API、支持多因子筛选

八、总结(工程师视角)

这是一个完全中立、去营销化、可教学的原型系统:

✅ 不鼓吹价值投资

✅ 不妖魔化 PE 指标

✅ 不伪装成选股神器

它真正展示的是:

如何用 Python 把"PE 越低越值得买"这个直觉,变成可量化、可检验、可质疑的数据实验

核心教学价值:

传统观念 数据可能揭示的真相

"PE 5 倍,肯定便宜" 可能业绩正在断崖式下滑

"低 PE 就是价值股" 低 PE 组合平均超额收益可能为负

"买低 PE 不会亏" 20%+ 的低 PE 个股超额收益 < −10%

"PE 是万能指标" PE 忽略成长性、现金流、行业差异

低 PE 陷阱的典型成因(教学参考):

成因 机制

业绩恶化 利润下滑 → PE 被动降低 → 看似"便宜"

行业衰退 整个赛道被淘汰(如胶卷、功能机)

财务造假 虚增利润 → 真实 PE 远高于显示值

周期性高点 周期顶部利润最高 → PE 最低 → 买入即套

本文代码仅供学习与技术交流,不构成任何投资建议,股市有风险,入市需谨慎!

利用AI解决实际问题,如果你觉得这个工具好用,欢迎关注长安牧笛!

http://www.jsqmd.com/news/1038458/

相关文章:

  • Sketch Find and Replace插件:专业设计师必备的批量文本替换工具
  • 福州仓山买宠干货测评|金山3家同商圈猫犬舍对比,盆地高湿+台风季养宠避坑指南 - 萌宠俱乐部
  • Ryzen AI 端侧算力与 Radeon GPU 协同实测大纲
  • Playnite便携版配置方案实践指南:跨设备游戏库管理的技术实现
  • 珠三角口碑好五金模具企业哪家强:从四大维度解析优质之选 - 资讯纵览
  • 山东国泰金属容器:全场景适配不锈钢储罐定制服务商 - 起跑123
  • 武汉空调维修推荐:本地用户反馈无隐形消费的几家服务商-修乐家家电维修-2026最新发布 - 资讯纵览
  • vue3项目引用vue-office组件
  • RootEncoder:Android流媒体编码的终极解决方案
  • 2026年国内GEO优化机构排行榜:技术实力实测对比 - 起跑123
  • 企业微信API对接的全流程,获取所有用户、发送消息给单人、发送消息给多人
  • 六月十八晚上
  • 机器视觉动态成像拖影根源分析及全套落地解决方案|高速自动化产线实测复盘
  • 口碑好的如何选购优质润滑油添加剂书籍推荐 - 资讯纵览
  • TensorFlow机器学习实战指南:从基础到生产的完整解决方案
  • 全场景储罐适配厂商资质与交付能力客观梳理 - 起跑123
  • 未来已来,Strix Halo 架构如何重新定义端侧 AI 的边界
  • 抗衰仪串口屏怎么选?一个资深工程师的四维选型心得
  • 雷军蹲街边吃面火了!网友感慨:千亿霸总,还是那个接地气的“雷子”
  • 深圳福田搬家避坑指南:2026价格透明、拒绝坐地起价的优质公司精选推荐 - 从来都是英雄出少年
  • 自研WebScanner:构建主动式网络资产发现与安全基线核查平台
  • 南京教培机构做GEO优化,怎么让AI更容易理解课程和适合人群?|4个落地动作 - 资讯纵览
  • 计算机视觉模型生产监控:构建物理世界感知的四层防御体系
  • XlsxWriter:一个 Python 库,把 Excel 文件生成这件事做透了
  • 终极ESP32开发指南:从Arduino新手到物联网专家
  • 地砖洗地机 地砖洗地机2025年终排行:史沃斯稳居榜首,挑战者厉邦紧随其后 - 工业清洁测评社
  • (纪念)slope trick例题与讲解/高中数学建模大赛落榜论文
  • 南京装修公司做AI搜索优化,为什么不能只发案例图?|5个常见误区 - 资讯纵览
  • 163MusicLyrics:免费获取网易云与QQ音乐歌词的终极解决方案
  • 及时响应!健身私教哪家好?5个标准帮你选对 - 资讯纵览