Python을 활용한 포트폴리오 최적화: 삼성전자, SK하이닉스, 현대자동차, NAVER 분석
주식 포트폴리오의 최적화는 투자자에게 중요한 결정 요소입니다. 적절한 포트폴리오 구성은 위험을 최소화하면서 예상 수익률을 극대화하는 데 도움이 됩니다. 이번 블로그에서는 Python을 사용해 삼성전자, SK하이닉스, 현대자동차, NAVER의 주식 포트폴리오를 최적화하는 방법을 알아보겠습니다.
우리는 yfinance 라이브러리를 이용해 주식 데이터를 가져오고, numpy와 pandas로 데이터 분석을 수행하며, matplotlib으로 결과를 시각화할 것입니다.
1. 필요한 라이브러리 설치
이 분석에는 numpy, pandas, matplotlib, yfinance가 필요합니다. 아래 명령어를 사용해 필요한 라이브러리를 설치할 수 있습니다.
pip install numpy pandas matplotlib yfinance
2. 데이터 다운로드
먼저, yfinance를 사용하여 각 주식의 조정 종가를 다운로드합니다.
import yfinance as yf
# 주식 심볼과 날짜 설정
stock = ['삼성전자', 'SK하이닉스', '현대자동차', 'NAVER']
tickers = ['005930.KS', '000660.KS', '005380.KS', '035420.KS'] # 삼성전자, SK하이닉스, 현대자동차, NAVER
start_date = '2023-08-27'
end_date = '2024-08-27'
# 주식 데이터 다운로드
df = yf.download(tickers, start=start_date, end=end_date)['Adj Close']
이 코드는 yf.download() 함수를 사용하여 주식 데이터를 다운로드합니다. start_date와 end_date를 설정하여 분석 기간을 지정하고, ['Adj Close']를 통해 조정 종가를 가져옵니다.
3. 수익률 및 공분산 계산
포트폴리오 최적화를 위해 각 주식의 일일 수익률과 공분산을 계산합니다.
import numpy as np
import pandas as pd
# 일일 수익률 계산
daily_ret = df.pct_change()
# 연간 수익률 및 공분산 계산
annual_ret = daily_ret.mean() * 252
daily_cov = daily_ret.cov()
annual_cov = daily_cov * 252
- pct_change(): 일일 수익률을 계산합니다. 현재 값과 이전 값의 비율 변화로 수익률을 구합니다.
- mean(): 각 주식의 평균 수익률을 계산합니다.
- cov(): 일일 수익률의 공분산을 계산하여 주식 간의 관계를 파악합니다.
- * 252: 연간 수익률과 공분산을 계산합니다. 주식 시장의 거래일 수는 보통 252일로 가정합니다.
4. 포트폴리오 생성 및 최적화
무작위로 생성한 20,000개의 포트폴리오를 통해 최적의 포트폴리오를 찾습니다.
# 포트폴리오 파라미터 초기화
port_ret = []
port_risk = []
port_weights = []
sharpe_ratio = []
for _ in range(20000):
# 무작위로 포트폴리오 가중치 생성
weights = np.random.random(len(tickers))
weights /= np.sum(weights)
# 포트폴리오 수익률 및 위험 계산
returns = np.dot(weights, annual_ret)
risk = np.sqrt(np.dot(weights.T, np.dot(annual_cov, weights)))
port_ret.append(returns)
port_risk.append(risk)
port_weights.append(weights)
sharpe_ratio.append(returns/risk)
- np.random.random(): 무작위로 포트폴리오 가중치를 생성합니다.
- np.dot(): 가중치와 수익률의 행렬 곱을 계산하여 포트폴리오의 예상 수익률을 구합니다.
- np.sqrt(): 포트폴리오의 위험(표준편차)을 계산합니다.
5. 포트폴리오 데이터프레임 생성 및 최적 포트폴리오 찾기
최적의 포트폴리오를 찾고, 이를 데이터프레임으로 정리합니다.
# 포트폴리오 데이터프레임 생성
portfolio = {'Returns': port_ret, 'Risk': port_risk, 'Sharpe': sharpe_ratio}
for i, s in enumerate(stock):
portfolio[s] = [weight[i] * 100 for weight in port_weights]
df = pd.DataFrame(portfolio)
df = df[['Returns', 'Risk', 'Sharpe'] + [s for s in stock]]
# 최대 샤프 비율과 최소 위험의 포트폴리오 찾기
max_sharpe = df.loc[df['Sharpe'] == df['Sharpe'].max()]
min_risk = df.loc[df['Risk'] == df['Risk'].min()]
print(max_sharpe)
print(min_risk)
print(daily_cov)
- pd.DataFrame(): 포트폴리오 데이터를 데이터프레임으로 변환합니다.
- loc[]: 최대 샤프 비율과 최소 위험의 포트폴리오를 찾습니다.
6. 포트폴리오 시각화
포트폴리오의 위험과 수익률을 산점도로 시각화합니다.
import matplotlib.pyplot as plt
# 포트폴리오 시각화
df.plot.scatter(x='Risk', y='Returns', c='Sharpe', cmap='viridis', edgecolors='k', figsize=(11,7), grid=True)
plt.scatter(x=max_sharpe['Risk'], y=max_sharpe['Returns'], c='r', marker='*', s=300)
plt.scatter(x=min_risk['Risk'], y=min_risk['Returns'], c='r', marker='X', s=200)
plt.title('Portfolio Optimization')
plt.xlabel('Risk')
plt.ylabel('Expected returns')
plt.show()
- plot.scatter(): 위험과 수익률을 산점도로 그립니다. 샤프 비율에 따라 색상을 표시합니다.
- plt.scatter(): 최대 샤프 비율과 최소 위험 포트폴리오를 강조 표시합니다.
7. 전체 코드 및 결과
전체코드는 다음과 같습니다.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import yfinance as yf
# 주식 심볼과 날짜 설정
stock = ['삼성전자', 'SK하이닉스', '현대자동차', 'NAVER']
tickers = ['005930.KS', '000660.KS', '005380.KS', '035420.KS'] # 삼성전자, SK하이닉스, 현대자동차, NAVER
start_date = '2023-08-27'
end_date = '2024-08-27'
# 주식 데이터 다운로드
df = yf.download(tickers, start=start_date, end=end_date)['Adj Close']
# 일일 수익률 계산
daily_ret = df.pct_change()
# 연간 수익률 및 공분산 계산
annual_ret = daily_ret.mean() * 252
daily_cov = daily_ret.cov()
annual_cov = daily_cov * 252
# 포트폴리오 파라미터 초기화
port_ret = []
port_risk = []
port_weights = []
sharpe_ratio = []
for _ in range(20000):
# 무작위로 포트폴리오 가중치 생성
weights = np.random.random(len(tickers))
weights /= np.sum(weights)
# 포트폴리오 수익률 및 위험 계산
returns = np.dot(weights, annual_ret)
risk = np.sqrt(np.dot(weights.T, np.dot(annual_cov, weights)))
port_ret.append(returns)
port_risk.append(risk)
port_weights.append(weights)
sharpe_ratio.append(returns/risk)
# 포트폴리오 데이터프레임 생성
portfolio = {'Returns': port_ret, 'Risk': port_risk, 'Sharpe': sharpe_ratio}
for i, s in enumerate(stock):
portfolio[s] = [weight[i] * 100 for weight in port_weights]
df = pd.DataFrame(portfolio)
df = df[['Returns', 'Risk', 'Shar
결론
이번 블로그에서는 Python을 사용해 삼성전자, SK하이닉스, 현대자동차, NAVER의 포트폴리오를 최적화하는 방법을 살펴보았습니다. 이를 통해 무작위로 생성된 포트폴리오의 수익률, 위험, 샤프 비율을 분석하고, 최적의 포트폴리오를 시각적으로 확인할 수 있었습니다.
포트폴리오 최적화는 투자 전략을 세우는 데 중요한 도구가 될 수 있으며, Python과 데이터 분석 도구를 활용하여 보다 정교한 투자 결정을 내릴 수 있습니다. 이러한 분석 기법을 활용하여 여러분만의 투자 전략을 구체화해보세요!