沃伦·巴菲特(Warren Buffett)是投资界的传奇人物,他的选股标准一直被广大投资者视为金科玉律,凭借独特的投资哲学,建立了一个令人瞩目的金融帝国。他的投资风格稳健,注重长期收益而非短期波动,强调基本面分析和风险控制。回溯历史,无论是2000年的互联网泡沫破灭,抑或是2008年的全球金融危机,巴菲特均能在一片哀鸿遍野中寻得机遇,不仅安然无恙,反而从中获利。
巴菲特的投资哲学可以总结为寻找和购买那些具有长期竞争优势、财务健康且价格合理的公司股票,并长期持有,通过公司的内在价值增长和市场价格修正来获得投资回报。
本文介绍巴菲特所看重的财务指标,并手把手教您如何基于这些财务指标,使用 Python 实现自动化筛选符合这些标准的优质股票,完整代码请见文末。
财务指标
1、债务/权益比(Debt/Equity):
债务/权益比应小于0.5,表明公司负债比例低,财务状况健康。
2、流动比率(Current Ratio):
流动比率应在1.5至2.5之间,确保公司有充足的流动资产,但不过度占用资金。
3、市净率(Price/Book):
市净率小于1.5,意味着股价相对于资产价值较为便宜。
4、股东权益回报率(ROE):
ROE应大于8%,且过去10年保持稳定或持续增长,反映公司的盈利能力。
5、资产回报率(ROA):
ROA应大于6%,且账面价值稳定增长,表明公司资产利用效率高。
6、每股收益(EPS):
每股收益应稳定增长,显示公司盈利能力持续增强。
7、股息增长(Dividend Growth):
股息增长应稳定,确保股东获得长期收益。
8、账面价值增长
账面价值的稳定增长意味着持续的资产积累和财务状况,为未来收益和股东价值奠定基础。
9、护城河(Moat)与利息覆盖率:
公司应拥有竞争优势,且利息覆盖率大于5倍,确保公司有能力偿还债务利息。
10.、利息覆盖率
利息覆盖率高于 5 倍表示有足够的收益来支付利息义务,降低财务困境的风险。
这些标准不仅关注公司的财务健康,还考察其盈利稳定性和长期竞争优势。遵循这些标准,可以帮助你筛选出财务稳健、估值合理且具备持续增长潜力的优秀公司,从而实现长期投资收益最大化。
整体流程
获取 S&P 500 股票代码:我们首先抓取 S&P 500 公司名单。这提供了一个全面的大盘股池供分析。
定义财务指标:此函数使用 获取给定股票代码的各种财务指标。我们提取必要的参数,例如债务/权益、流动比率、价格/账面、ROE、ROA、利息覆盖率等。
处理数据检索:该脚本遍历每个代码,收集财务数据,并将其附加到列表中。错误处理可确保单个代码的任何问题都不会停止整个过程。
应用 Buffett 标准:收集完所有数据后,我们将其转换为 Pandas DataFrame 并根据概述的标准应用筛选条件。
输出:最终筛选的 DataFrame 显示符合 Buffett 标准的股票代码及其各自的财务指标。
【 扫描文末二维码加入星球获取完成代码 】
获取数据
def get_financial_data(ticker):
try:
stock = yf.Ticker(ticker, proxy="http://127.0.0.1:33210")
info = stock.info
cashflow = stock.cashflow
earnings = stock.earnings
roic = info.get('returnOnInvestment', np.nan)
roe = info.get('returnOnEquity', np.nan)
gross_margin = info.get('grossMargins', np.nan)
revenue_growth = calculate_revenue_growth(earnings)
free_cash_flow = calculate_free_cash_flow(cashflow)
debt_to_equity = info.get('debtToEquity', np.nan)
earnings_stability = calculate_earnings_stability(earnings)
return {
'Ticker': ticker,
'ROIC': roic,
'ROE': roe,
'Gross Margin': gross_margin,
'Revenue Growth': revenue_growth,
'Free Cash Flow': free_cash_flow,
'Debt to Equity': debt_to_equity,
'Earnings Stability': earnings_stability
}
except Exception as e:
print(f"Error fetching data for {ticker}: {e}")
return None
定义指标
def calculate_revenue_growth(earnings):
try:
if len(earnings) >= 5:
revenue_t0 = earnings['Revenue'].iloc[0]
revenue_t4 = earnings['Revenue'].iloc[4]
growth = (revenue_t4 - revenue_t0) / revenue_t0
return growth
else:
return np.nan
except:
return np.nan
def calculate_free_cash_flow(cashflow):
try:
cfo = cashflow.loc['Total Cash From Operating Activities'][0]
capex = cashflow.loc['Capital Expenditures'][0] if 'Capital Expenditures' in cashflow.index else 0
fcf = cfo + capex
return fcf
except:
return np.nan
def calculate_earnings_stability(earnings):
try:
if len(earnings) >= 5:
earnings_growth = earnings['Earnings'].pct_change().dropna()
if len(earnings_growth) > 1:
std_dev = earnings_growth.std()
return std_dev
else:
return np.nan
else:
return np.nan
except:
return np.nan
def score_roic(roic):
if pd.isna(roic):
return 0
elif roic >= 15:
return 1
elif roic >= 10:
return 0.7
elif roic >= 5:
return 0.4
else:
return 0
def score_roe(roe):
if pd.isna(roe):
return 0
elif roe >= 20:
return 1
elif roe >= 15:
return 0.7
elif roe >= 10:
return 0.4
else:
return 0
def score_gross_margin
(gm):
if pd.isna(gm):
return 0
elif gm >= 50:
return 1
elif gm >= 40:
return 0.7
elif gm >= 30:
return 0.4
else:
return 0
def score_revenue_growth(rg):
if pd.isna(rg):
return 0
elif rg >= 0.15:
return 1
elif rg >= 0.10:
return 0.7
elif rg >= 0.05:
return 0.4
else:
return 0
def score_free_cash_flow(fcf):
if pd.isna(fcf):
return 0
elif fcf > 0:
return 1
else:
return 0
def score_debt_to_equity(de):
if pd.isna(de):
return 0
elif de < 0.5:
return 1
elif de < 1:
return 0.7
elif de < 2:
return 0.4
else:
return 0
def score_earnings_stability(es):
if pd.isna(es):
return 0
elif es < 0.05:
return 1
elif es < 0.10:
return 0.7
elif es < 0.15:
return 0.4
else:
return 0
def compute_moat_score(row):
scores = [
score_roic(row['ROIC']),
score_roe(row['ROE']),
score_gross_margin(row['Gross Margin']),
score_revenue_growth(row['Revenue Growth']),
score_free_cash_flow(row['Free Cash Flow']),
score_debt_to_equity(row['Debt to Equity']),
score_earnings_stability(row['Earnings Stability'])
]
moat_score = np.sum(scores) / len(scores)
return moat_score
筛选股票
def get_interest_coverage(ticker):
"""
Fetches the Interest Coverage Ratio for a given stock ticker.
Parameters:
ticker (str): The stock ticker symbol (e.g., 'AAPL').
Returns:
float or None: The Interest Coverage Ratio, or None if data is unavailable.
"""
try:
stock = yf.Ticker(ticker)
income_statement = stock.financials
if 'Operating Income' in income_statement.index and 'Interest Expense' in income_statement.index:
operating_income = income_statement.loc['Operating Income'][0]
interest_expense = income_statement.loc['Interest Expense'][0]
if interest_expense != 0:
interest_coverage = operating_income / abs(interest_expense)
return round(interest_coverage, 2)
else:
print(f"Interest Expense is zero for {ticker}. Cannot compute Interest Coverage Ratio.")
return None
else:
print(f"Necessary financial data not available for {ticker}.")
return None
except Exception as e:
print(f"Error fetching data for {ticker}: {e}")
return None
def get_financials(ticker):
try:
stock = yf.Ticker(ticker)
balance = stock.balance_sheet
cashflow = stock.cashflow
income = stock.financials
info = stock.info
debt_equity = info.get('debtToEquity', np.nan)
current_ratio = info.get('currentRatio', np.nan)
price_book = info.get('priceToBook', np.nan)
roe = info.get('returnOnEquity', np.nan) * 100
roa = info.get('returnOnAssets', np.nan) * 100
interest_coverage = get_interest_coverage(ticker)
dividend_growth = info.get('dividendRate', np.nan)
eps_growth = info.get('earningsQuarterlyGrowth', np.nan)
book_value_growth = info.get('bookValue', np.nan)
eps = info.get('earningsPerShare', np.nan)
moat = get_moat_stocks(ticker)
return {
'Ticker': ticker,
'Debt/Equity': debt_equity,
'Current Ratio': current_ratio,
'Price/Book'
: price_book,
'ROE (%)': roe,
'ROA (%)': roa,
'Interest Coverage': interest_coverage,
'Moat': moat,
'EPS Growth': eps_growth,
}
except Exception as e:
print(f"Error fetching data for {ticker}: {e}")
return None
financial_data = []
for ticker in sp500_tickers[:10]:
data = get_financials(ticker)
if data:
financial_data.append(data)
df = pd.DataFrame(financial_data)
filtered_df = df[
(df['Debt/Equity'] < 0.5) &
(df['Current Ratio'] > 1.5) & (df['Current Ratio'] < 2.5) &
(df['Price/Book'] < 1.5) &
(df['ROE (%)'] > 8) &
(df['ROA (%)'] > 6) &
(df['Interest Coverage'] > 5) &
(df['Moat'] > 0) &
(df['EPS Growth'] > 0.08)
]
【 扫描文末二维码加入星球获取完成代码 】
我们致力于提供优质的AI服务,涵盖人工智能、数据分析、深度学习、机器学习、计算机视觉、自然语言处理、语音处理等领域。如有相关需求,请私信与我们联系。
请加微信“LingDuTech163”,或公众号后台私信“联系方式”。
关注【灵度智能】公众号,获取更多AI资讯。