3장. 평균-분산 포트폴리오 이론

 

Remarks

이 글은 파이썬으로 배우는 포트폴리오을 정리한 자료입니다.


평균-분산 포트폴리오 이론의 가정

  1. 모든 투자자의 투자 기간은 1 기간이다.
  2. 투자자는 위험을 회피하고, 기대효용을 극대화하려 한다.
  3. 기대수익률표준편차에 따라 투자를 결정하며, 지배원리에 따라 투자 대상을 선택한다.
  4. 거래비용과 세금은 없으며, 모든 투자자는 무위험이자율로 한도 없는 차입과 대출을 할 수 있다.

3.1 포트폴리오의 기대수익률과 위험


https://thebook.io/080227/ch03/01/

포트폴리오(portfolio)
여러 개의 투자 대상을 모은 집합

  • 두 자산의 상관계수가 0에 가까울수록 투자기회집합선은 왼쪽으로 휘어진다.
    즉, 분산 투자의 효과를 통해 위험을 줄일 수 있다.
  • 평균-분산 포트폴리오 이론에서 제시하는 최적 포트폴리오를 구하는 간략한 과정

    포트폴리오 수익률의 기대수익률과 리스크를 계산하고 지배원리에 따라 포트폴리오를 걸러낸다.
    그리고 무차별곡선을 이용해 최적 포트폴리오를 결정한다.

포트폴리오의 기대수익률
$E[r_p] = \sum_i w_i E[r_i] = W’R$
- $W$: 자산의 투자 비중 $([n, 1])$
- $R$: 자산의 기대수익률 $([n, 1])$

포트폴리오의 위험
$\sigma_p^2 = \sum_i \sum_j w_i w_j \sigma_{ij} = \sum_i w_i^2 \sigma_i^2 + \sum_i \sum_{j \neq i} w_i w_j \rho_{ij} \sigma_i \sigma_j = W’\Sigma W$
- $W$: 자산의 투자 비중 $([n, 1])$
- $\Sigma$: 자산 수익률에 대한 공분산 행렬 $([n, n])$
- $\rho_{ij}$: 자산 $i$와 $j$간의 상관계수 $(\rho_{ij} = \frac{\sigma_{ij}}{\sigma_i \sigma_j})$

https://thebook.io/080227/ch03/01/02-07/

3.2 최소분산포트폴리오

분산 효과(포트폴리오 효과)
포트폴리오를 구성함으로써 같은 기대수익률하에 위험이 줄어드는 효과

최소분산포트폴리오(Minimum Variance Portfolio, MVP)
자산 간의 상관계수가 0인 경우, 가장 위험이 적은 투자 비중 조합을 가진 포트폴리오

https://thebook.io/080227/ch03/02/

  • 주식 A와 B에 대한 투자 비중은 다음 공식을 통해 구할 수 있다.
    $w_A = \frac{\sigma_B^2 - \sigma_{AB}}{\sigma_A^2 + \sigma_B^2 - 2\sigma_{AB}}$
    $w_B = 1 - w_A$

실전 예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import numpy as np
import pandas as pd
from pykrx import stock
from datetime import datetime
import matplotlib.pyplot as plt
import seaborn as sns

df = pd.DataFrame()
dates = pd.date_range(start='2022-01-01', end='2022-02-01').strftime("%Y%m%d")
for date in dates:
    df_cur = df.append(stock.get_market_ohlcv_by_ticker(date=date, market='KOSPI'))
    if (df_cur == 0).all(None):
        continue
    df_cur['날짜'] = date
    df_cur = df_cur[['날짜', '등락률']]
    df = df.append(df_cur)

df = df.pivot_table(index='날짜', columns='티커', values='등락률')
df
티커	000020	000040	000050	000060	000070	000075	000080	000087	000100	000105	...	383220	383800	38380K	395400	396690	400760	402340	404990	900140	950210
날짜
20220103	2.400000	1.270000	0.000000	2.830000	-0.920000	-0.580000	0.330000	1.050000	2.090000	1.020000	...	0.000000	1.500000	1.640000	0.970000	-1.080000	0.190000	0.150000	-0.400000	1.240000	2.160000
20220104	1.035000	1.950000	1.090000	5.255000	0.155000	-0.580000	0.250000	-0.510000	0.100000	0.510000	...	-1.375000	2.230000	2.440000	-0.080000	-0.540000	0.000000	2.705000	-0.150000	0.415000	0.375000
20220105	0.530000	1.792500	0.635000	4.142500	-0.330000	-0.435000	-0.122500	0.272500	0.130000	0.217500	...	-0.960000	1.370000	1.160000	0.242500	-0.630000	0.047500	0.532500	-0.250000	0.312500	0.072500
20220106	0.566250	1.378750	0.633750	3.363750	-0.612500	-0.508750	0.272500	0.107500	0.146250	0.385000	...	-1.318750	1.250000	1.235000	0.182500	-0.631250	-0.001250	-0.130000	-0.187500	0.277500	0.033750
20220107	0.848750	1.467500	0.611875	4.021875	-0.367500	-0.499375	0.219375	0.123750	0.321250	0.374375	...	-0.820625	1.370625	1.335000	0.253125	-0.608125	0.023125	0.345000	-0.206250	0.424375	0.248125
20220108	0.771875	1.464063	0.611875	3.786562	-0.397188	-0.485625	0.188438	0.123750	0.285000	0.374375	...	-0.945938	1.355312	1.325000	0.227813	-0.608125	0.023125	0.380313	-0.203125	0.385312	0.232500
20220109	0.771875	1.464063	0.611875	3.786562	-0.397188	-0.485625	0.188438	0.123750	0.285000	0.374375	...	-0.945938	1.355312	1.325000	0.227813	-0.608125	0.023125	0.380313	-0.203125	0.385312	0.232500
20220110	0.771875	1.431328	0.617422	3.836406	-0.401250	-0.489062	0.183359	0.117578	0.281172	0.373047	...	-0.982109	1.362891	1.327500	0.217734	-0.611016	0.020078	0.335469	-0.210156	0.363906	0.210938
20220111	0.765195	1.445000	0.616016	3.822969	-0.402070	-0.485586	0.183359	0.118594	0.288906	0.389609	...	-0.957266	1.355352	1.326250	0.221484	-0.613164	0.023867	0.355859	-0.207422	0.371289	0.211641
20220112	0.768535	1.447930	0.617383	3.828145	-0.397539	-0.482695	0.189453	0.121699	0.288867	0.377207	...	-0.959316	1.356269	1.324375	0.223086	-0.611367	0.022734	0.364395	-0.207832	0.375996	0.220293
20220113	0.766836	1.447139	0.616699	3.826279	-0.399697	-0.484150	0.188145	0.121182	0.286494	0.376992	...	-0.957666	1.356269	1.324043	0.222451	-0.611182	0.022168	0.358330	-0.207832	0.374746	0.216201
20220114	0.766821	1.447139	0.617031	3.822598	-0.400215	-0.485215	0.186738	0.120669	0.286411	0.378130	...	-0.958823	1.356269	1.323716	0.222529	-0.611455	0.022070	0.360322	-0.207632	0.373521	0.216563
20220115	0.767254	1.447139	0.616780	3.823540	-0.399805	-0.484790	0.187166	0.120796	0.286687	0.378171	...	-0.958823	1.356389	1.324197	0.222529	-0.611365	0.022261	0.359902	-0.207632	0.374065	0.216953
20220116	0.767254	1.447139	0.616780	3.823540	-0.399805	-0.484790	0.187166	0.120796	0.286687	0.378171	...	-0.958823	1.356389	1.324197	0.222529	-0.611365	0.022261	0.359902	-0.207632	0.374065	0.216953
20220117	0.767033	1.446949	0.616780	3.823679	-0.399987	-0.484907	0.187047	0.120715	0.286627	0.378109	...	-0.959025	1.356299	1.324176	0.222539	-0.611422	0.022201	0.359934	-0.207738	0.373890	0.216821
20220118	0.767075	1.447015	0.616769	3.823739	-0.399929	-0.484839	0.187091	0.120756	0.286642	0.378124	...	-0.958900	1.356359	1.324125	0.222539	-0.611393	0.022237	0.360103	-0.207679	0.373982	0.216794
20220119	0.767056	1.447004	0.616780	3.823719	-0.399897	-0.484855	0.187091	0.120756	0.286634	0.378127	...	-0.958924	1.356352	1.324156	0.222529	-0.611399	0.022240	0.359996	-0.207682	0.373978	0.216776
20220120	0.767095	1.447017	0.616780	3.823704	-0.399898	-0.484844	0.187103	0.120758	0.286644	0.378131	...	-0.958900	1.356348	1.324158	0.222532	-0.611392	0.022243	0.360006	-0.207684	0.373990	0.216838
18 rows × 942 columns
1
2
3
4
n = 10
codes = np.random.choice(df.columns, n)
corr = df[codes].corr()
sns.heatmap(np.triu(corr.loc[codes, codes], k=1), cmap='coolwarm', center=0, annot=True);

다운로드 (1)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
pair_pos  = df[codes].columns[[3, 8]]
pair_zero = df[codes].columns[[2, 6]]
pair_neg  = df[codes].columns[[4, 8]]

def exp_return(r1, r2, w1):
    exp_r1 = r1.mean()
    exp_r2 = r2.mean()
    return w1*exp_r1 + (1-w1)*exp_r2

def risk(r1, r2, w1):
    var1 = r1.var(ddof=1)
    var2 = r2.var(ddof=1)
    cov  = np.cov(r1, r2, ddof=1)[0, 1]
    return np.sqrt(w1**2 * var1 + (1-w1)**2 * var2 + 2*w1*(1-w1)*cov)

def mv_plot(df, pair, ax):
    A, B = pair
    r_A, r_B = df[A].values, df[B].values

    for w in np.arange(0, 1, 0.01):
        X, y = risk(r_A, r_B, w), exp_return(r_A, r_B, w)
        ax.plot(X, y, '.')
    ax.set_xlabel('risk'), ax.set_ylabel('expected return')

fig, axes = plt.subplots(1, 3, figsize=(15, 5))
for ax, pair, title in zip(axes, [pair_pos, pair_zero, pair_neg], ['corr = 0.97', 'corr = 0.025', 'corr = -0.9']):
    mv_plot(df, pair, ax)
    ax.set_title(title)

다운로드

3.3 체계적 위험과 비체계적 위험

위험의 구분
\1. 체계적 위험(systematic risk, market risk): 모든 기업에 공통적으로 영향을 미치는 요인에 의해 발생하는 위험 (분산 투자로 제거 불가능)
- 경제변수(이자율, 환율, 경기선행지수, 실업률, 경제정책 등)의 불리한 움직임
\2. 비체계적 위험(unsystematic risk): 특정 기업에 의해 발생하는 위험 (분산 투자로 제거 가능)
- 개별 주식과 관련된 고유의 위험(어닝쇼크(실적 부진), 소송, 노사분규 등)

3.3.1 체계적 위험의 측정

  1. 체계적 위험은 주식시장 전체 변동에 대한 개별 종목의 변동 정도로 측정
  2. 구체적으론, 주식시장 전체 변화율과 개별 종목 변화율 간 회귀방정식의 기울기(베타, $\beta$)를 의미

3.3.2 구성 종목수가 많을수록 개별 종목의 분산은 무의미해진다

\(\begin{equation} \begin{aligned} \sigma_p^2 &= \sum_i \sum_j w_i w_j \sigma_i \sigma_j \\ &= \sum_i w_i^2 \sigma_i^2 + \sum_i \sum_{i \neq j} w_i w_j \sigma_{ij} \\ &= \sum_i (\frac{1}{n})^2 \sigma_i^2 + \sum_i \sum_{i \neq j} (\frac{1}{n})^2 \sigma_{ij} \quad \cdots \quad \forall_i w_i = \frac{1}{n} \\ &= \frac{1}{n} \sum_i \frac{1}{n} \sigma_i^2 + \frac{n-1}{n} \sum_i \sum_{i \neq j} \frac{1}{n(n-1)} \sigma_{ij} \\ &= \frac{1}{n} \bar \sigma_i^2 + (1 - \frac{1}{n}) \bar \sigma_{ij} \\ &= \frac{1}{n}(\bar \sigma_i^2 - \bar \sigma_{ij}) + \bar \sigma_{ij} \\ &= \bar \sigma_{ij} \quad \cdots \quad \lim n \rarr \infty \end{aligned} \end{equation}\)

  1. 포트폴리오의 위험은 각 종목의 분산종목간의 공분산으로 구성됨
  2. 동일 가중치 포트폴리오를 구성하는 경우,
    종목의 개수를 늘릴수록 개별 종목의 분산은 의미를 잃고 종목 간 공분산만이 포트폴리오의 위험을 나타냄

3.4 무위험자산과 최적 자산배분

무위험자산(risk-free asset)
이자율, 인플레이션 변화에도 영향을 받지 않아 미래의 현금흐름에 불확실성이 없는 자산