본문 바로가기
python/금융데이터분석

python 증권데이터 분석 - 샤프지수, 포트폴리오 최적화 python구현

by orangecode 2022. 12. 27.
728x90
샤프지수(Shape Ratio)

현대 포트폴리오 이론에 따르면 포트폴리오 별 개별 리스크가 주어졌을 때, 효율적 투자선보다 높은 수익률은 기대할 수 없다는 한계점을 가지고 있다.

 

리스크를 최소화하고 수익률을 최대화하는 포트폴리오는 어떻게 찾을 수 있을까?

 

현대 포트폴리오 이론을 개발한 해리 마코위츠의 초기 이론으로는 해결하기 힘들지만

 

해리 마코위츠의 제자인 윌리엄 샤프(William Shape)의 샤프지수로 해결할 수 있다.

 

 

윌리엄샤프 역시 샤프지수Shape Ratio를 개발하여 노벨상을 수상하였고, 현대 포트폴리오 이론에서 매우 중요한 요소가 되었다.

 

샤프지수는 측정된 위험단위당 수익률을 계산한다는 점에서 수익률의 표준편차와 다른 점을 가진다.

 

샤프 지수 구현은 계산 편의를 고려해 무위험률 = 0, 샤프지수는 포트폴리오의 예상 수익률을 수익률의 표준편차로 나누어서 구한다.

 

예를 들어, 예상 수익률이 10% 이고 수익률의 표준편차가 4% 인 경우 

샤프지수는 10 / 4 = 2.5 가 된다.

 

샤프지수 포트폴리오 최적화

효율적 투자선에서 임의로 만들었던 20000개의 포트폴리오 중에서

Shape Ratio를 이용하여 포트폴리오 중에서 측정된 위험단위당 수익이 가장 높은 포트폴리오를 구할 수 있다.

 

기존에 생성했던 20000개의 포트폴리오를 만드는 코드에 shape ratio를 구하는 코드와 그래프 코드를 추가하여 작성할 것이다.

 

20000개 임의 포트폴리오를 제작하는 코드는 아래 포스팅에 있다.

https://kwonkai.tistory.com/111

 

python 증권데이터 분석 - 현대 포트폴리오 이론, 효율적 투자선 python 구현

현대 포트폴리오 이론 현대 포트폴리오 이론 해리 맥스 마코위츠(Harry Max Markowitz)가 1952년 발표한 논문 [포트폴리오 셀렉션]에서 평균-분산 최적화(MVO : Mea-Variance-Optimization)를 제시했다. 평균-분

kwonkai.tistory.com

 

샤프지수 포트폴리오 최적화 전체 코드

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# 모듈경로 지정
import sys
sys.path.append(r'C:\Users\kwonk\Downloads\개인 프로젝트\juno1412-1\증권데이터분석\DB_API')

# 모듈 가져오기
import Analyzer

mk = Analyzer.MarketDB()

# KOSPI 시가총액 5위
stocks = ['삼성전자', 'LG에너지솔루션', '삼성바이오로직스', 'SK하이닉스', 'LG화학']

# 종목별 일별 시세 dataframe 생성
df = pd.DataFrame()
for i in stocks:
    df[i] = mk.get_daily_price(i, '2018-10-13', '2022-12-23')['close']

# 데이터를 토대로 종목별, 일간 수익률, 연간수익률, 일간리스크, 연간리스크를 구하기
# 5종목 일간 변동률
daily_ret = df.pct_change()
# 5종목 1년간 변동률 평균(252는 미국 1년 평균 개장일)
annual_ret = daily_ret.mean() * 252

# 5종목 연간 리스크 = cov()함수를 이용한 일간변동률 의 공분산
daily_cov = daily_ret.cov()
# 5종목 1년간 리스크(252는 미국 1년 평균 개장일)
annual_cov = daily_cov * 252

# 시가총액 5순위 주식의 비율을 다르게 해 20,000개 포트폴리오 생성
# 1. 수익률, 리스크, 비중 list 생성
# 수익률 = port_ret
# 리스크 = port_risk
# 비  중 = port_weights
port_ret = []
port_risk = []
port_weights = []
# 샤프지수 추가
shape_ratio = []

for i in range(20000):
    # 2. 랜덤 숫자 4개 생성 - 랜덤숫자 4개의 합 = 1이되도록 생성
    weights = np.random.random(len(stocks))
    weights /= np.sum(weights)
    
    # 3. 랜덤 생성된 종목뵹 비중 배열과 종목별 연간 수익률을 곱해 포트폴리오의 전체 수익률(returns)를 구한다.
    returns = np.dot(weights, annual_ret)

    # 4. 종목별 연간공분산과 종목별 비중배열 곱하고, 다시 종목별 비중의 전치로 곱한다.
    # 결과값의 제곱근을 sqrt()함수로 구하면 해당 포트폴리오 전체 risk가 구해진다. 
    risk = np.sqrt(np.dot(weights.T, np.dot(annual_cov, weights)))

    # 5. 20,000개 포트폴리오의 수익률, 리스크, 종목별 비중을 각각 리스트에 추가한다.
    port_ret.append(returns)
    port_risk.append(risk)
    port_weights.append(weights)
    shape_ratio.append(returns/risk)

# 포트폴리오 결과에 샤프지수 추가
portfolio = {'Returns' : port_ret, 'Risk' : port_risk, 'Shape' : shape_ratio}
for j, s in enumerate(stocks):
    # 6. portfolio 4종목의 가중치 weights를 1개씩 가져온다.
    portfolio[s] = [weight[j] for weight in port_weights]

# 7. 최종 df는 시총 상위 5종목의 보유 비중에 따른 risk와 예상 수익률을 확인할 수 있다.
df = pd.DataFrame(portfolio)
df = df[['Returns', 'Risk', 'Shape'] + [s for s in stocks]]


# 8. 샤프지수로 위험단위당 예측 수익률이 가장 높은 포트폴리오 구하기
# 샤프지수 칼럼에서 가장 높은 샤프지수 구하기
max_shape = df.loc[df['Shape'] == df['Shape'].max()]

# 리스크칼럼에서 가장 낮은 리스크 구하기
min_risk = df.loc[df['Risk'] == df['Risk'].min()]

# 샤프지수 그래프 그리기
df.plot.scatter(x='Risk', y='Returns', c='Shape', cmap='viridis', edgecolors='k', figsize=(10,8), grid=True)
plt.scatter(x=max_shape['Risk'], y=max_shape['Returns'], c='r', marker='X', 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 Return')
plt.show()

포트폴리오 변수에 샤프지수인 Shape가 포함된 것을 확인할 수 있다.

샤프 지수가 포함된 포트폴리오의 수익률, 리스크, 샤프지수를 데이터 프레임으로 보면 위 사진과 같다.

 

가장 높은 샤프지수를 가진 포트폴리오는 15916번 포트폴리오로 나타났다.

 

비율은 삼성전자 0.8%, LG에너지솔루션 27.2%, 삼성바이오로직스 14.6%,  SK하이닉스 1.56%, LG화학 55.67% 포트폴리오가 가장 샤프지수가 높았다.

 

리스크가 가장 낮은 포트폴리오는 17890번 포트폴리오였다.

 

포트폴리오 비율은 삼성전자 44.32%, LG에너지솔루션 9.36%, 삼성바이오로직스 43.3%,  SK하이닉스 2.66%, LG화학 0.3% 포트폴리오가 가장 RISK가 낮았다.

 

샤프지수 그래프

참고도서

http://www.yes24.com/Product/Goods/90578506

 

파이썬 증권 데이터 분석 - YES24

투자 기법과 프로그래밍 기술로 자신만의 퀀트 투자 시스템을 완성하라『파이썬 증권 데이터 분석』은 웹 스크레이핑으로 증권 데이터를 주기적으로 자동 수집, 분석, 자동 매매, 예측하는 전

www.yes24.com

https://github.com/INVESTAR/StockAnalysisInPython

 

GitHub - INVESTAR/StockAnalysisInPython

Contribute to INVESTAR/StockAnalysisInPython development by creating an account on GitHub.

github.com

 

 

 

 

반응형

댓글