[Day2] 포트폴리오 최적화 with Python
지난 포스팅에서는 SPY, TLT, IAU, DBC의 주가 데이터를 파이썬으로 읽어들여 포트폴리오의 수익률과 분산을 계산해보았다.
위험과 수익의 관계
이제 포트폴리오의 비중을 변경할 때 수익률과 분산이 어떻게 변하는지 알아보자. 이미 수익률과 분산을 계산하는 방법을 알고 있으므로 비중을 변경하면서 자료를 쌓아나가면 된다.
자료를 쌓아나갈 장소를 지정해주자.
prets = [] # 리스트 형태로 수익을 쌓을 장소
pvols = [] # 리스트 형태로 위험(표준편차)을 쌓을 장소
지정한 장소에 3000개의 시뮬레이션 자료를 쌓아보자.
for p in range (3000): # 3000회 반복
weights = np.random.random(4) # 랜덤한 4개의 숫자를 생성함(4개의 자산에 대응하는..)
weights /= np.sum(weights) # 4개의 숫자의 합계가 1이 되도록 조정함(각 자산의 비중)
prets.append(np.sum(rets.mean() * weights) * 12) # 계산된 포트폴리오 수익을 prets에 저장
covmat = rets.cov() * 12 # cov matrix 만들기
pvols.append(np.sqrt(weights.T @ covmat @ weights)) # 계산된 포트폴리오 위험을 pvols에 저장한다.
저장된 자료의 형태를 계산하기 쉬운 형태로 바꿔준다.
prets = np.array(prets)
pvols = np.array(pvols)
위험과 수익의 관계를 그래프로 출력해보자.
plt.scatter(pvols, prets, c=prets/pvols, marker='o')
plt.grid(True)
plt.xlabel('expected volatility')
plt.ylabel('expected return')
plt.colorbar(label='Sharpe ratio')
plt.show()
최소위험 포트폴리오(Minimum Volatility Portfolio)
먼저 최적화를 위한 라이브러리를 불러들인다.
import scipy.optimize as sco
최적화 대상 함수를 만든다. 여기서는 위험을 최소화 할 것이므로 다음과 같이 함수를 구성한다.
def minvar(weights):
return np.sqrt(weights.T @ covmat @ weights)
최적화를 위한 입력조건을 설정한다.
- 추측값 : 최적화 추측값이 있으면 설정, 없으면 아무값이나 넣는다.
w = np.array([0.25, 0.25, 0.25, 0.25]) # 추측치 : 아무값이나 넣는다. ㅎㅎㅎ
- 최적화 방법 : 최적화를 위한 다양한 방법이 있다는데, 여기서는 SQP를 선택.
method='SLSQP'
- 변수범위설정 : 투자 비중이므로 0~1사이로 설정
bnds = ((0,1), (0,1), (0,1), (0,1))
- 제약조건 설정 : 비중의 합이 1이되도록 설정
cons = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1}) # 합계가 1이 되도록.. eq는 같다를 의미.
최적화 코드
def minvar(weights):
return np.sqrt(weights.T @ covmat @ weights)
w = np.array([0.25, 0.25, 0.25, 0.25])
cons = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1})
bnds = ((0,1), (0,1), (0,1), (0,1))
opt = sco.minimize(minvar, w, method='SLSQP', bounds=bnds, constraints=cons)
결과값(opt)출력
마지막 x가 최적화 결과.
최적화 결과를 이용해 수익과 위험을 측정해보자.
orets = np.sum(rets.mean() * opt['x']) * 12
ovol = np.sqrt(opt['x'].T @ covmat @ opt['x'])
최소위험 포트폴리오를 그래프에 나타내보자.
plt.scatter(pvols, prets, c=prets/pvols, marker='o')
plt.grid(True)
plt.xlabel('expected volatility')
plt.ylabel('expected return')
plt.colorbar(label='Sharpe ratio')
plt.scatter(ovol, orets, marker="*", s=500, alpha=0.5)
plt.show()
오늘은 여기까지. 지난글은 아래 링크를 참고.
[Day1] 포트폴리오 최적화 with Python
10스파임대 | 50스파임대 | 100스파임대
위의 링크는 @wonsama님의 [steemit] 스팀커넥트 sign link 알아보기를 참고하여 작성하였습니다~^^
Sponsored ( Powered by dclick )
[Tasteem][테이스팀 검증단] 검증이 필요없다!! 최고의 맛집!! 마산 오시면 대접해 드리겠습니다. 마산 밋업 가즈아~ 호야 메기 매운탕을 소개합니다.
안녕하세요. 굳헬로 @goodhello 입니다. 테이스팀에 검색 기능이 추가되면서 재미난 주제...
이 글은 스팀 기반 광고 플랫폼
dclick 에 의해 작성 되었습니다.
유용한 정보 감사합니다!
방문 감사합니다~^^
어맛 너무어려워요 ㅋㅋㅋㅋ
저도 언젠가는
저도 아직 다 알지는 못해요 ㅎㅎ
일부는 정확히 이해가 안되는데 그냥 쓰고 있습니다 ^^
형아 파이썬 공부하자나 ㅋㅋㅋㅋ
코딩 보자마자 그냥 내려와서 댓글 씁니다
어려워서..ㅋㅋㅋㅋ
저도 어렵습니다. 그저 한줄 한줄 열심히 따라가볼 뿐이지요^^
즐거운 한주 보내세요~ ^^
이거저거 누르고 갑니다 ㅋㅋ
으아~ 반가운 글자들~ 이제는 거의 잊어버린 글자들.. +_+;;
새로운 한 주 시작이네요~ 아침 저녁으로 많이 추워요~
감기 조심하시고 즐거운 한 주 보내세요 thrufore님.
감사합니다~전엔 코딩을 공부하셨나봐요~^^전 이제 조금씩 공부중입니다~minigate님도 한주 즐겁게 시작하세요^^
흐흐, 저에겐 좀 어렵군요^^;
Posted using Partiko iOS
저도 아직은 많이 어렵습니다~
그저 관심이 있어서 한줄한줄 따라갈 뿐이지요~
pediatrics님은 따로 전문분야가 있으시잖아요^^
올려주신는 글들은 흥미롭게 잘 읽고 있습니다~