지난 포스팅에서는 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()
먼저 최적화를 위한 라이브러리를 불러들인다.
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]) # 추측치 : 아무값이나 넣는다. ㅎㅎㅎ
method='SLSQP'
bnds = ((0,1), (0,1), (0,1), (0,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 알아보기를 참고하여 작성하였습니다~^^
안녕하세요. 굳헬로 @goodhello 입니다. 테이스팀에 검색 기능이 추가되면서 재미난 주제...