Skip to content

按巴菲特六维打分法选股,半年后验真九只美股涨跌

作 者:老余捞鱼

原创不易,转载请标明出处及原作者。

文中示例仅用于技术讨论,不构成任何操作建议。
量化策略开发应以学习和技术交流为目的。
本号不荐股、不卖课、不承诺收益。
市场有风险,请合法合规投资。

本文约 2800 字 | 预计阅读 9分钟,后有代码,建议先收藏。

先看一组数字。

三月,我按巴菲特那一套,给 9 只美股大盘股打了分。每个指标过线 1 分,满分 6 分。半年过去,6 只涨了 10% 以上,3 只跌穿底。

最贵的那只叫 COST,跌了 10.44%。但它的基本面 3 分,跟赢家们并列。

把这 9 只票按 P/E 重新排,跌的那 3 只正好也是榜单最贵的 3 只。剩下 6 只赢家的 P/E,没有一个冲过 32。

把这堆数据翻完,最值钱的一课是「这套尺子有个盲区」。Buffett 厉害不厉害,跟你我没关系。下面把 6 个指标、9 张打分表、半年后的真涨跌拆给你看,结尾给你一个能马上拿去用的升级版。

一、巴菲特的六把尺子

先把六个指标认完。每个都是 pass/fail,过线加 1 分,不及格就 0 分,没有「差一点也算过」这种灰度。

这 6 个分两组。先是看公司赚不赚得到钱。

ROE(净资产收益率):股东投的钱一年能赚回多少。阈值 15%。能稳定超过 15% 的公司,通常是在某个生意上有护城河的。

ROA(总资产收益率):公司把全部家当都用起来,能赚回多少。阈值 7%。比 ROE 严,因为它把所有负债也算进去了。

净利率:每收 100 元进账,最后落袋多少。阈值 20%。消费品、科技平台、SaaS 这种品牌型生意容易过这条线。

再看公司账稳不稳、买得贵不贵。

D/E(负债权益比):借的钱和股东的钱的比例。阈值 0.5。银行、保险本身靠负债经营,这道线得给这类公司单独留。

P/E(市盈率):按当前利润多少年回本。阈值 20。同一行业里 P/E 越低,通常意味着市场对它的预期越保守。

P/B(市净率):市价和公司净资产的比。阈值 3。轻资产公司(市净率天然高,比如软件、品牌)容易挂在这里。

六维指标速览

总结成一句话,就是把「这家公司值不值」翻译成六个具体问题。每个问题一刀切,要么 1 分要么 0 分。简单粗暴,但好处是不同行业能放在一张表里横向比。

这套思路是巴菲特几十年选股浓缩出来的。1950 年代他买伯克希尔之前,给每只候选股都过这套流程。区别是当时人工算,今天 Python 一行拉数据出结果。

二、九只票各能打几分

样本是 9 只美股大盘股,从苹果到特斯拉。选它们是因为覆盖面广:科技、消费、金融、零售都有,跨行业不容易撞到「某个行业突然发力」这种运气成分。

打分的口径是年初最新披露的财报数据,每只票总分 0 到 6。

按六维里哪些项过哪些项不过,公开脚本里都能查到。9 只票里最高的是苹果 5 分,最低的是特斯拉 1 分。中间 7 只都在 2 到 4 分之间。没有任何一只票拿到 6 分满分。

单一指标看,9 只票全部过了 ROE 这道,8 只过了 ROA。卡得最严的是 P/B 和 P/E,几只高估的票就挂在这两条上。

到这里还看不出什么。分数是死的,半年真涨跌才是考验。

三、半年后真涨跌

回测窗口是 2026 年 3 月 1 日到 9 月 22 日,差不多 6 个半月。把每只票的起点拉到 100,终点对一下实际股价。

数字如下。

股票起点(3/1)终点(9/22)涨幅
AAPL100127.2+27.2%
MSFT100124.4+24.4%
JPM100118.65+18.65%
V100115.36+15.36%
GOOGL100114.26+14.26%
KO100112.15+12.15%
WMT10084.51-15.49%
COST10089.56-10.44%
TSLA10090.32-9.68%

6 只涨、3 只跌。赢家里最猛的是苹果 +27.2%,输家里最惨的是沃尔玛 -15.49%。

散点图更直观。

九只票的得分 vs 半年涨幅

得分档位和半年涨幅能看出明显分层。总分 3 以上的 7 只票里,6 只正收益,只有 COST 一只例外。总分 2 以下的 2 只票,全部负收益。

这套尺子能分出好坏,到这一步能看出来了。

但有一个点不正常。COST 基本面 3 分,落在赢家那一档里。半年却跌了 10.44%,跟输家站一排。这是必须挖的。

四、那个打破规律的家伙

COST 就是那只打破规律的票。它的基本面 3 分,跟苹果、摩根、维萨、谷歌、可口可乐这些赢家站同一档。

它输在价格上。

打分那一刻,COST 的 P/E 超过 50,P/B 超过 13。比 P/E 那道阈值 20 高了一倍多,比 P/B 的阈值 3 高了三倍多。按规则,这两项都该是 0 分。但 COST 的 ROE 高、净利率高、负债低,硬是靠其他 4 项过线,把总分抬到了 3 分。

问题就出在这。指标打分是平均用力,每项 1 分,6 项各占六分之一。但 P/E > 50 这种价格信号,本质上是「市场已经在抢这家公司的预期」,是个预警信号,不是一个普通指标。

把它和其他项同等打分,等于把预警信号当成普通考题一起出。

半年后 COST 跌了 10.44%,市场给的信号兑现了。

特斯拉更糟。基本面 1 分(只过了 2 项),价格又高,双杀。半年跌 9.68%,排倒数第三。

赢家这一边,苹果 5 分过 5 项、微软 4 分过 4 项、摩根 4 分过 4 项,价格都在合理区间,没有任何一只被价格预警卡住。

这一轮胜出的全是「基本面 + 价格都合理」的。基本面再好,价格离谱,照样出局。

五、三个输家全是同一种贵

把 9 只票按 P/E 从低到高排一排,规律更清楚。

赢家 P/E 都不过 32 · 输家全是榜上最贵

赢家这一边,6 只票的 P/E 都在 32 以下。最便宜的 KO 才 18 倍,最贵的 AAPL 30 倍。

输家这一边,3 只票的 P/E 全部高于 32。COST 52 倍,TSLA 48 倍,WMT 36 倍。三个最贵的,正好是三个跌的。

这是一组极其干净的对照。把筛选阈值改成 P/E ≤ 32 一票否决,连 COST 这种基本面 3 分的票都会被提前挡在外面。结果会变成什么样?6 个赢家还在,3 个输家直接出局。

这套尺子真正漏掉的就是这一项。P/E 应该从「6 个指标里的一项」升级成「硬红线」。

具体怎么改?

第一种,直接把 P/E 阈值从 20 拉到 25 或 30。过了打分,不过出局。简单粗暴,可解释性强。

第二种,P/E 不参与总分,但单独设一道「价格红线」。比如 P/E > 25 的票直接判 0 分,无论其他几项多漂亮。这样 COST 这种「基本面好但被抢」的情况就被抓出来了。

第三种,结合 PEG(市盈率相对盈利增长比率)。PEG = P/E ÷ 盈利增长率。PEG ≤ 1 的票才算便宜。这一项对成长股特别有效,但需要盈利增长率数据,脚本得多拉一列。

我倾向第二种。简单、可解释、能解决这次踩到的坑。

六、怎么自己跑一遍

想做全套,把六维打分在自己电脑上跑一遍,门槛不高。一台能访问海外网络的机器、Python 3.10 以上、`yfinance` 装一下就行。

第一步先装包。

# 终端一行命令(shell,不是 Python):
# pip install yfinance pandas numpy
import yfinance as yf
import pandas as pd

第二步,定义六个指标的阈值。

THRESHOLDS = {
    'roe':       0.15,   # ≥ 15%
    'roa':       0.07,   # ≥ 7%
    'de':        0.05,   # ≤ 0.5
    'net_margin':0.20,   # ≥ 20%
    'pe':        20,     # ≤ 20 倍
    'pb':         3,     # ≤ 3 倍
}

第三步,写一个打分函数。

import yfinance as yf
import pandas as pd

def score_one(ticker: str) -> dict:
    info = yf.Ticker(ticker).info
    roe  = info.get('returnOnEquity', 0)
    roa  = info.get('returnOnAssets', 0)
    de   = info.get('debtToEquity', 0) / 100  # yfinance 返回百分比
    nm   = info.get('profitMargins', 0)
    pe   = info.get('trailingPE', 0)
    pb    = info.get('priceToBook', 0)

    flags = {
        'roe':       roe >= THRESHOLDS['roe'],
        'roa':       roa >= THRESHOLDS['roa'],
        'de':        de  <= THRESHOLDS['de'],
        'net_margin':nm  >= THRESHOLDS['net_margin'],
        'pe':        pe  <= THRESHOLDS['pe'],
        'pb':        pb  <= THRESHOLDS['pb'],
    }
    return {
        'ticker': ticker,
        'score':  sum(flags.values()),
        'details': flags,
        'raw': {'pe': pe, 'pb': pb, 'roe': roe},
    }

第四步,批量跑一组票。

TICKERS = ['AAPL', 'MSFT', 'JPM', 'V', 'GOOGL', 'KO',
           'WMT', 'COST', 'TSLA']

results = pd.DataFrame([score_one(t) for t in TICKERS])
print(results[['ticker', 'score']].sort_values('score', ascending=False))

跑完会拿到 9 只票的总分。和上面那张表一对照,能直接看出 yfinance 拉数和 AAPL 对比的差异在哪。yfinance 自带的财务字段会随财报披露节奏变化,A股票没法直接套,跨市场的字段名也不一样,要按需改字段映射。

第五步是这次最重要的升级版。把 P/E 拎出来当一票否决。

PE_HARD_LIMIT = 32  # P/E 超过这一档直接出局,不进总分

def score_with_pe_redline(ticker: str) -> dict:
    res = score_one(ticker)
    pe = res['raw']['pe']
    if pe > PE_HARD_LIMIT:
        res['score'] = 0   # 一票否决
        res['blocked_by'] = f'P/E={pe:.1f} > {PE_HARD_LIMIT}'
    return res

这次跑下来,COST(WMT、TSLA 都算上)会被这一行直接拦下。剩下的票里 6 只赢家、0 只输家。

整套脚本不到 50 行,复制到本地一个文件就能跑。美股票直接接上面的 TICKERS,A 股票换数据源、字段映射单独写一份。

七、方法论升华

把这件事抽到方法论那一层。

质量不等于不贵。Buffett 六维打分衡量的是「这家公司的商业质量」,盈利能力、效率、负债结构。这套指标对「质量」这一维的回答是及格的。但它对「不算贵」这一项的回答不够有力。原因:当一个票基本面特别好,价格又特别高,6 个指标里 4 个过线,总分还能拿到 3 分、4 分。它本应该出局。

预警信号的权重应该高于普通指标。P/E 高是个预警信号,不是普通考题。预警信号应该是一票否决或者高权重,不应该和「净利率 ≥ 20%」这种描述性指标平起平坐。

半年是足够长的检验窗口,但还不够。6 个月能看出趋势,看不出周期。一轮完整的牛熊至少要 3 到 5 年。这次的结果可以作为起点,要往下验证还需要拉更长的回测。

回到打分清单上。这个工具省掉的是你每天翻 F10 那一页。基本面算清楚 → 公司值不值。剩下半个问题(价格贵不贵)需要单独的硬阈值兜底。

两个升级建议收尾。

P/E 单独设硬红线,不参与总分。这是这次最大的教训。

半年只算开始。要让结论立得住,拉 3 到 5 年的回测看趋势,再加一轮牛熊压力测试。

留个问题。你的自选股清单里,上一次翻盘是因为基本面变差,还是价格太贵?

觉得有用的话,把这篇转给同样在挑票的朋友。


风险提示:文中示例仅用于技术讨论,不构成任何操作建议。量化选股应以学习和技术交流为目的。本公众号不荐股、不卖课、不承诺收益。市场有风险,请合法合规投资。

#Buffett六维打分 #美股选股 #量化选股 #Python筛股 #价值投资 #ROE #财报指标 #P/E指标 #股票筛选 #美股ETF #长期持有 #指标体系

Published inAI&Invest专栏

Be First to Comment

    发表回复