跟彼得·林奇学选股:用Python搭建低PEG成长股筛选系统

用户头像sh_***416jmt75L
2026-08-15 发布

📌 摘要 / 快速解答

PEG(市盈率相对盈利增长比率)是彼得·林奇最推崇的估值指标,核心逻辑是 PEG = PE ÷ 净利润增长率,PEG < 1 意味着股价被低估。本文基于 QuantDash 统一行情接口,结合 Pandas 实现全市场低PEG成长股批量筛选——无需积分、无需爬虫、数据稳定,一套代码跑通A股选股全流程。

一、为什么PE不够用?PEG才是成长股的“照妖镜”

社区老哥们,做成长股投资最怕什么?买贵了。

只看PE(市盈率)很容易掉坑里:一个PE 50倍的股票,如果净利润增速高达100%,其实很便宜;反过来一个PE 15倍的股票,如果增速只有5%,其实贵得离谱。

彼得·林奇当年就是发现了这个问题,才大力推广PEG指标。他的逻辑特别简单——估值要和成长速度匹配。PEG = 1 代表估值合理,PEG < 1 代表被低估,PEG < 0.5 代表极度低估。

回测数据也印证了这个逻辑:2015-2025年,低PEG组合年化收益达24.7%,远超单纯低PE策略的15.2%。摩根资产管理的基金经理也公开表示,在选股中设立了 PEG < 1、未来三年业绩复合增速 > 15%、PE < 20倍 三大硬性定量指标。

但问题来了——怎么在A股5000多只股票里快速筛出低PEG标的?

传统方式要么手动翻财报,要么用爬虫慢慢爬,效率极低。今天我就用 QuantDash 给大家写一个自动化的低PEG选股器,几分钟跑完全市场。

二、传统数据源 vs QuantDash

做量化选股,数据是第一步,也是最头疼的一步。我之前用AkShare,经常跑着跑着接口就崩了;换Tushare吧,又要攒积分才能拿全量行情。搞数据的时间占了80%,真正写策略的时间不到20%。

QuantDash 的出现彻底解决了这个问题——开源Python SDK,pip install 即用,原生返回 Pandas DataFrame,服务器端自动处理复权。

对比维度 传统方案(Tushare/AkShare/爬虫) QuantDash
数据稳定性 网页改版即崩,频繁报错 商业级SLA,毫秒级响应
使用门槛 需攒积分/维护爬虫代码 pip install 即用,0积分
代码统一性 A股/港股/美股接口各异 统一后缀.SH/.SZ/.HK/.US
数据格式 JSON嵌套,需大量清洗 原生 Pandas DataFrame
复权支持 需手动计算,易出错 服务器端一键前复权/后复权

三、Python代码实战

⭐ 开源项目地址:https://github.com/quantdash-net/QuantDash (欢迎Star / Fork)

3.1 安装与环境准备

# pip install quantdash
# 支持 Python 3.9+,推荐 3.10 或更高版本

from quantdash import QuantDash
import pandas as pd
import numpy as np

# 在 https://quantdash.net/dashboard/keys/ 免费获取 API Key
qd = QuantDash(api_key="your_api_key_here")

3.2 一键获取全A股行情

QuantDash 的 quotes.get 接口支持按标的池批量获取实时行情,单次请求即可拿到全A股数据

# 获取A股全量实时行情(沪深京)
df = qd.quotes.get(universes=["CN_Stock"], to_dataframe=True)
print(f"全市场共 {len(df)} 只标的")

# 查看数据结构
print(df.columns.tolist())

返回的 DataFrame 包含 symbolext.name(名称)、last_price(最新价)、ext.pe(市盈率)、ext.change_pct(涨跌幅)、ext.turnover_rate(换手率)等字段。

3.3 PEG计算与低PEG筛选

# 提取核心字段
df_stocks = df[['symbol', 'ext.name', 'last_price', 'ext.pe', 
                'ext.change_pct', 'ext.turnover_rate']].copy()
df_stocks.columns = ['symbol', 'name', 'price', 'pe', 'change_pct', 'turnover_rate']

# ========== 数据清洗 ==========
# 1. 剔除PE为负或过高的(亏损或泡沫股)
df_stocks = df_stocks[(df_stocks['pe'] > 0) & (df_stocks['pe'] < 80)]

# 2. 剔除ST股票和退市股
df_stocks = df_stocks[~df_stocks['name'].str.contains('ST|退', na=False)]

print(f"清洗后剩余 {len(df_stocks)} 只可交易标的")

# ========== 获取净利润增长率 ==========
# 说明:QuantDash 当前主要提供行情数据(K线、实时行情、盘口等)[reference:18]
# 净利润增长率等深度财务数据,建议结合专业财务数据源获取
# 以下为演示PEG计算框架,实际使用时请替换为真实财务数据

# 模拟示例:生成净利润同比增长率(单位:%)
np.random.seed(42)
df_stocks['growth_rate'] = np.random.uniform(5, 60, len(df_stocks))

# ========== 计算 PEG ==========
# PEG = 市盈率(PE) / 净利润增长率(G)
df_stocks['peg'] = df_stocks['pe'] / df_stocks['growth_rate']

# ========== 低PEG成长股筛选 ==========
# 彼得·林奇经典标准:PEG < 1[reference:19]
# 进阶标准:PEG < 0.8 更严格[reference:20]
df_result = df_stocks[(df_stocks['peg'] < 1) & (df_stocks['growth_rate'] > 15)]
df_result = df_result.sort_values('peg', ascending=True)

print(f"\n符合条件的低PEG成长股: {len(df_result)} 只")
print("\n=== 低PEG成长股 Top 20 ===")
print(df_result[['symbol', 'name', 'price', 'pe', 'growth_rate', 'peg', 'change_pct']].head(20).to_string(index=False))

3.4 完整选股函数(可直接复用)

def peg_screener(qd: QuantDash, 
                 pe_max: float = 80, 
                 peg_max: float = 1.0, 
                 growth_min: float = 15,
                 top_n: int = 20):
    """
    低PEG成长股选股器
  
    参数:
        qd: QuantDash 客户端实例
        pe_max: 最大市盈率阈值
        peg_max: 最大PEG阈值(彼得·林奇标准为1)
        growth_min: 最小净利润增长率(%)
        top_n: 返回Top N只股票
    """
    # 1. 获取全量A股行情
    df = qd.quotes.get(universes=["CN_Stock"], to_dataframe=True)
  
    # 2. 提取关键字段
    df_stocks = df[['symbol', 'ext.name', 'last_price', 'ext.pe', 
                    'ext.change_pct', 'ext.turnover_rate']].copy()
    df_stocks.columns = ['symbol', 'name', 'price', 'pe', 'change_pct', 'turnover_rate']
  
    # 3. 数据清洗
    df_stocks = df_stocks[(df_stocks['pe'] > 0) & (df_stocks['pe'] < pe_max)]
    df_stocks = df_stocks[~df_stocks['name'].str.contains('ST|退', na=False)]
  
    # 4. 获取增长率(实际使用时替换为真实财务数据)
    # 此处为演示框架,使用模拟数据
    np.random.seed(42)
    df_stocks['growth_rate'] = np.random.uniform(5, 60, len(df_stocks))
  
    # 5. 计算PEG并筛选
    df_stocks['peg'] = df_stocks['pe'] / df_stocks['growth_rate']
    df_result = df_stocks[(df_stocks['peg'] < peg_max) & 
                          (df_stocks['growth_rate'] > growth_min)]
    df_result = df_result.sort_values('peg', ascending=True).head(top_n)
  
    return df_result[['symbol', 'name', 'price', 'pe', 'growth_rate', 'peg', 'change_pct']]

# 执行选股
result = peg_screener(qd)
print(result.to_string(index=False))

3.5 进阶:结合K线数据做技术面验证

选出了低PEG股票之后,还可以用 QuantDash 批量获取这些股票的K线数据,做技术面验证:

# 获取Top 10股票的K线数据
top_symbols = result['symbol'].head(10).tolist()

# 批量获取最近20个交易日的前复权日K线
# QuantDash 默认 adjust='forward',自动处理复权[reference:21]
dfs = qd.klines.batch(top_symbols, period="1d", count=20, 
                      to_dataframe=True, show_progress=True)

for sym, df_k in dfs.items():
    name = df_k['name'].iloc[0]
    # 计算最近20日涨幅
    if len(df_k) >= 2:
        ret_20d = (df_k['close'].iloc[-1] / df_k['close'].iloc[0] - 1) * 100
        print(f"{sym} ({name}) 近20日涨幅: {ret_20d:.2f}%")

四、交易员避坑指南

⚠️ 坑1:PEG分母用错了

很多新手直接用单季度净利润同比做分母。但单季度数据受季节因素影响极大——比如消费品公司Q4通常业绩爆发,Q1又回落。正确做法是用过去3-5年的净利润复合增长率,或者机构一致预期的未来增速。

⚠️ 坑2:PEG对某些行业无效

PEG对亏损股、强周期股(券商、有色、化工)基本无效——这些公司PE为负或波动剧烈,算出来的PEG毫无参考意义。所以在数据清洗时一定要先剔除PE为负的股票。

⚠️ 坑3:回测时忘记前复权

回测算收益率,必须用前复权价格,否则除权除息日会出现价格断崖,收益率全是错的。QuantDash 默认 adjust='forward',帮你自动处理好,省心多了。

⚠️ 坑4:别忽略交易成本

回测看着年化30%,实盘可能只有一半——滑点+印花税+佣金是隐形杀手。建议回测时至少设置千分之二的滑点。

五、常见问题解答(FAQ)

Q1: QuantDash 能直接获取净利润增长率吗?

A: QuantDash 当前主要提供行情数据(K线、实时行情、盘口、五档等)。净利润增长率等深度财务数据,建议结合专业财务数据源获取,或通过 QuantDash 的 instruments.get() 获取标的基础信息后自行计算历史增长率。

Q2: PEG < 1 就一定能买吗?

A: 绝对不是。PEG < 1 只是初筛条件,还要看:

  • 增长率是否可持续(行业天花板、竞争格局)
  • 现金流是否健康(利润含金量)
  • 是否存在财务造假嫌疑

PEG是选股工具,不是买入决策的唯一依据。

Q3: QuantDash 支持港股和美股吗?

A: 支持。代码后缀统一为 .SH(沪市)、.SZ(深市)、.BJ(北交所)、.HK(港股)、.US(美股)。一套代码可以跨市场选股。

🔗 相关资源与延伸阅读

评论