社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

手把手教你用Python实现巴菲特的选股策略

灵度智能 • 3 天前 • 6 次点击  

沃伦·巴菲特(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 倍表示有足够的收益来支付利息义务,降低财务困境的风险。

这些标准不仅关注公司的财务健康,还考察其盈利稳定性和长期竞争优势。遵循这些标准,可以帮助你筛选出财务稳健、估值合理且具备持续增长潜力的优秀公司,从而实现长期投资收益最大化。

Python 代码实现

整体流程


  1. 获取 S&P 500 股票代码:我们首先抓取 S&P 500 公司名单。这提供了一个全面的大盘股池供分析。


  2. 定义财务指标此函数使用 获取给定股票代码的各种财务指标。我们提取必要的参数,例如债务/权益、流动比率、价格/账面、ROE、ROA、利息覆盖率等。


  3. 处理数据检索:该脚本遍历每个代码,收集财务数据,并将其附加到列表中。错误处理可确保单个代码的任何问题都不会停止整个过程。


  4. 应用 Buffett 标准:收集完所有数据后,我们将其转换为 Pandas DataFrame 并根据概述的标准应用筛选条件。


  5. 输出:最终筛选的 DataFrame 显示符合 Buffett 标准的股票代码及其各自的财务指标。


【 扫描文末二维码加入星球获取完成代码 】


获取数据


def get_financial_data(ticker):    try:        stock = yf.Ticker(ticker, proxy="http://127.0.0.1:33210")        info = stock.info        # financials = stock.financials        # balance_sheet = stock.balance_sheet        cashflow = stock.cashflow        earnings = stock.earnings
# Extract necessary metrics 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


定义指标


# Calculate Revenue Growth over the last 5 yearsdef 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

# Calculate Free Cash Flow (Simplified as Cash from Operations - Capital Expenditures)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 # Capex is usually negative return fcf except: return np.nan

# Calculate Earnings Stability (Standard Deviation of Earnings Growth)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

# Define scoring functions for each metricdef 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']) ] # Assign equal weights or customize as needed moat_score = np.sum(scores) / len(scores) # Average score 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
# Ensure the necessary data is present 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]
# Handle cases where Interest Expense is zero to avoid division by zero 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
# Extract necessary metrics 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 # Convert to percentage roa = info.get('returnOnAssets', np.nan) * 100 # Convert to percentage interest_coverage = get_interest_coverage(ticker) dividend_growth = info.get('dividendRate', np.nan) # Simplified eps_growth = info.get('earningsQuarterlyGrowth', np.nan)
# Book value and EPS growth could be more complex to calculate # Here we'll use simplified placeholders book_value_growth = info.get('bookValue', np.nan) # Placeholder eps = info.get('earningsPerShare', np.nan) # Latest EPS
# Economic moat is not directly available; using 'moat' information if available 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, # Additional fields can be added as needed } except Exception as e: print(f"Error fetching data for {ticker}: {e}") return None

# Fetch financial data for all tickersfinancial_data = []for ticker in sp500_tickers[:10]: # For demonstration, we're limiting to the first 10 tickers data = get_financials(ticker) if data: financial_data.append(data)
# Convert to DataFramedf = pd.DataFrame(financial_data)
# Apply Buffett's criteriafiltered_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) # Assuming 8% EPS growth ]

【 扫描文末二维码加入星球获取完成代码 】




▌关于我们

我们致力于提供优质的AI服务,涵盖人工智能、数据分析、深度学习、机器学习、计算机视觉、自然语言处理、语音处理等领域。如有相关需求,请私信与我们联系。

▌商务合作

请加微信“LingDuTech163”,或公众号后台私信“联系方式”。


关注【灵度智能】公众号,获取更多AI资讯。


Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/178207
 
6 次点击