S&P 500 지수의 주식 데이터를 분석하고 원하는 지표(예: 시가총액, PER, PBR)에 따라 상위 N개의 주식을 추출하고 CSV 파일로 저장하는 코드를 소개합니다.
이전글
앞에서 주식 평가 지표인 PER(Price-to-Earnings Ratio)와 PBR(Price-to-Book Ratio)은 무엇이고, 미국 주식 시장에서 낮은 PER 및 PBR을 가진 주식을 찾는 방법을 살펴보았습니다.
이번 글에서는 파이썬을 사용하여 PER과 PBR 순위를 찾는 방법에 대해 소개하겠습니다.
이번 코드는 riverKangg의 Github을 바탕으로 작성되었습니다.
GitHub - riverKangg/stock-report
Contribute to riverKangg/stock-report development by creating an account on GitHub.
github.com
1. 라이브러리 설정
import os
import warnings
import pandas as pd
from numerize import numerize
from stock_report.stock_analyzer import StockAnalyzer
from stock_report.sp500_list_fetcher import SP500ListFetcher
warnings.filterwarnings('ignore')
이 스크립트는 필요한 라이브러리를 가져옵니다. os
모듈은 파일 및 디렉토리 관리를 위해 사용되며, pandas
는 데이터 프레임을 다루기 위해 사용됩니다. numerize
는 숫자를 읽기 쉽게 포맷팅하기 위한 라이브러리입니다. StockAnalyzer
와 SP500ListFetcher
는 사용자 정의 모듈로, 주식 분석과 S&P 500 목록을 가져오기 위해 사용됩니다.
2. S&P500 데이터 수집
def fetch_or_load_sp500_data(save_directory):
data_file_path = os.path.join(save_directory, 'sp500_valuation_data.csv')
# Check if the data file already exists
if os.path.exists(data_file_path):
# Load and return the existing data
valuation_data = pd.read_csv(data_file_path, index_col=0)
return valuation_data
# Step 1: Get S&P 500 tickers
sp500_data = SP500ListFetcher().get_sp500_data()
sp500_tickers = sp500_data.index.tolist()
# Step 2: Fetch S&P 500 stocks
analyzed_data = {}
error_tickers = [] # 에러가 발생한 티커 목록
for ticker in sp500_tickers:
try:
stock_analyzer = StockAnalyzer(ticker)
analyzed_data[ticker] = stock_analyzer.last_quarter_ratios().iloc[0]
except Exception as e:
error_tickers.append(ticker)
print(f"Error analyzing {ticker}: {str(e)}")
for error_ticker in error_tickers:
sp500_tickers.remove(error_ticker) # 에러 티커 제외
# Step 3: Sort by PER in descending order
valuation_data = pd.DataFrame(analyzed_data).T
# Step 4: Save the data to a CSV file
if not os.path.exists(save_directory):
os.makedirs(save_directory)
valuation_data.to_csv(data_file_path)
return valuation_data
이 함수는 S&P 500 주식 데이터를 수집하거나 이미 수된 데이터를 로드합니다. 데이터 파일이 존재하는 경우, 파일을 읽어옵니다. 그렇지 않은 경우, S&P 500 목록을 가져오고 각 주식을 분석합니다. 에러가 발생한 경우, 해당 티커를 에러 목록에 추가하고 로그에 출력합니다. 마지막으로, 분석된 데이터를 PER을 기준으로 정렬하여 CSV 파일로 저장합니다.
3. S&P 500 정보 추가
def add_sp500_info(valuation_data):
sp500_data = SP500ListFetcher().get_sp500_data()
valuation_data = valuation_data.join(sp500_data)
return valuation_data
이 함수는 S&P 500의 섹터, 산업군 정보를 추가합니다.
4. 상위 주식을 CSV 파일로 저장하는 함수
def save_top_stocks_to_csv(top_stocks, metric, save_directory, group_by=None):
if group_by:
csv_file_name = f'top_{metric}_{group_by}.csv'
else:
csv_file_name = f'top_{metric}.csv'
csv_file_path = os.path.join(save_directory, csv_file_name)
top_stocks.to_csv(csv_file_path, sep="\t", index=False)
이 함수는 상위 N개 주식을 지정된 지표(예: 시가총액)에 따라 CSV 파일로 저장합니다. group_by
매개변수를 사용하여 섹터에 따라 그룹화된 데이터를 저장할 수 있습니다.
5. 그룹화된 데이터를 CSV 파일로 저장하는 함수
def save_grouped_data_to_csv(grouped_data, metric, save_directory):
csv_file_name = f'GRP_{metric}.csv'
csv_file_path = os.path.join(save_directory, csv_file_name)
grouped_data.to_csv(csv_file_path, sep="\t")
이 함수는 그룹화된 데이터를 CSV 파일로 저장합니다. 주로 섹터별 평균 지표를 저장하는 데 사용됩니다.
6. 상위 N개 주식을 가져오는 함수
def get_top_n_stocks(valuation_data, metric, n=10, ascending=True, group_by=None):
if metric not in valuation_data.columns:
print(f"Column '{metric}' not found in the data.")
return None
if group_by:
valuation_data = add_sp500_info(valuation_data)
valuation_data = valuation_data[valuation_data[metric]>0]
top_stocks = valuation_data.groupby(group_by).apply(lambda x: x.nsmallest(n, metric))[[metric,'MarketCap']].reset_index()
top_stocks.columns = [group_by, 'Symbol', metric, 'MarketCap']
top_stocks[metric] = top_stocks[metric].apply(lambda x: round(x, 1))
top_stocks['MarketCap'] = top_stocks['MarketCap'].apply(lambda x: numerize.numerize(x))
# Calculating the Number of Companies and Average Metric by Sector.
grouped_data = valuation_data.groupby(group_by)[metric].agg(['count', 'mean'])
grouped_data = grouped_data.sort_values(by='mean')
grouped_data['mean'] = grouped_data['mean'].apply(lambda x: round(x, 1))
save_grouped_data_to_csv(grouped_data, metric, save_directory)
else:
top_stocks = valuation_data.nlargest(n, metric)[[metric]]
top_stocks[metric] = top_stocks[metric].apply(lambda x: numerize.numerize(x))
top_stocks = top_stocks.reset_index()
top_stocks.columns = ['Symbol', metric]
return top_stocks
이 함수는 이미 분석된 데이터에서 상위 N개 주식을 가져옵니다. 지표(예: PER, PBR) 및 그룹화(섹터별) 옵션을 설정할 수 있습니다.
7. 메인 코드 블록
if __name__ == "__main__":
save_directory = "sp500_data"
analyzed_data = fetch_or_load_sp500_data(save_directory)
if analyzed_data is not None:
print(analyzed_data.shape)
# Get the top 10 MarketCap stocks and save to CSV:
top_10_market_cap_stocks = get_top_n_stocks(analyzed_data, 'MarketCap', n=10, ascending=False)
save_top_stocks_to_csv(top_10_market_cap_stocks, 'MarketCap', save_directory)
# Get the top 10 PER Sector and save to CSV:
top_10_per_sector = get_top_n_stocks(analyzed_data, 'PER', n=5, ascending=True, group_by='Sector')
save_top_stocks_to_csv(top_10_per_sector, 'PER', save_directory, 'Sector')
# Get the top 10 PBR Sector and save to CSV:
top_10_pbr_sector = get_top_n_stocks(analyzed_data, 'PBR', n=5, ascending=True, group_by='Sector')
save_top_stocks_to_csv(top_10_pbr_sector, 'PBR', save_directory, 'Sector')
메인 코드 블록에서는 위에서 정의한 함수들을 호출하여 S&P 500 주식 데이터를 분석하고 상위 주식을 CSV 파일로 저장합니다. 시가총액, PER, PBR 등 다양한 지표를 기반으로 상위 주식을 추출하고 섹터별 그룹화 데이터를 저장합니다.
'배당 주식 투자자 > 파이썬으로 배당 투자 분석하기' 카테고리의 다른 글
yfinance 패키지로 재무제표 불러오기 (0) | 2023.09.16 |
---|---|
재무 비율 공식 정리 (0) | 2023.09.15 |
파이썬으로 주식 데이터 가져오기(yfinance, FinanceDataReader) (0) | 2023.09.06 |