아래 3개는 순서대로 정규분포, 라플라스분포, T분포를 데이터에 fitting한 것입니다.
마지막은 실제 주가분포와 각각의 확률분포 실험을 비교했어요. 결과는..재밌네요! 다시 코드로 돌아가죠.
# imaginary daily price return distribution by Normal distribution
norm_fit_param = norm.fit(log_ret_SPY_close)
print(f'Norm dist fit param: {norm_fit_param}')
img_log_ret0 = norm.rvs(*norm_fit_param, size=count_bday, random_state=None)
print(f'Norm rvs: {img_log_ret0}')
ax2.hist(img_log_ret0, density=True, histtype='stepfilled', alpha=0.5, bins=bin_div10)
# ax2.legend(loc='best', frameon=False)
이제 본격적으로 확률분포를 위 데이터에 fitting시켜봅니다.
정규분포(normal distribution) 먼저 해보죠.
scipy.stats.norm에 내장된 fit 메서드를 사용해서 수익률 데이터를 넣고, 결과를 norm_fit_param 변수에 받아옵니다. 정규분포의 경우 loc(평균)과 scale(분산) 순서로 튜플로 반환할 것입니다.
그리고 해당 확률분포를 따르는 난수를 만들어봅시다. norm.rvs는 주어진 param을 따르는 난수를 생성해주는 메서드입니다. size에 넣는 수 만큼 list에 원소로 집어넣어서 반환해줘요. 지금은 SPY 거래일 수 만큼 난수를 생성해봅시다!
rvs 메서드로 만든 상상의 수익률을 히스토그램으로 plot합니다.
결과는 위에 그림 참고~
# imaginary daily price return distribution by Laplace distribution
laplace_fit_param = laplace.fit(log_ret_SPY_close)
print(f'Laplace dist fit param: {laplace_fit_param}')
img_log_ret1 = laplace.rvs(*laplace_fit_param, size=count_bday, random_state=None)
print(f'Laplace rvs: {img_log_ret1}')
ax3.hist(img_log_ret1, density=True, histtype='stepfilled', alpha=0.5, bins=bin_div10)
# ax3.legend(loc='best', frameon=False)
라플라스분포에 대해서도 똑같이 해줘요. 라플라스 분포도 인자가 loc과 scale 두개이므로 fitting parameter를 튜플로 반환합니다.
# imaginary daily price return distribution by Student's T distribution
t_fit_param = t.fit(log_ret_SPY_close)
print(f'T dist fit param: {t_fit_param}')
img_log_ret2 = t.rvs(*t_fit_param, size=count_bday, random_state=None)
print(f'T rvs: {img_log_ret2}')
ax4.hist(img_log_ret2, density=True, histtype='stepfilled', alpha=0.5, bins=bin_div10)
# ax4.legend(loc='best', frameon=False)
마지막으로 Student's T분포입니다. 정규분포랑 대표적으로 비교되는 확률변수인데, Fat-tail이 두드러지는 확률모델이에요.
S&P500 수익률과 확률분포 비교
사실 정규분포는 꼬리쪽 분포에 사건이 발생할 확률이 매우 낮습니다. Fat-tail 사건(하루만에 폭락, 폭등)에 대한 설명이 너무 설득력이 없는데 주식판에서는 정말 흔하게 발생하는 일입니다. 예를 들면 1929 대공황, 1987 블랙 먼데이, 2000년 닷컴버블, 2008 세계금융위기, 그리고 2020 코로나 붕괴까지..
그리고 평범한 날들은 수익률이 0에 가깝게 움직이는 경우가 훨씬 많았어요.
그림만 봐도.. 주황색 선은 실제 수익률에 잘 fitting이 되지 않아요.
대신 Student's T 분포나 Laplace분포를 이용해 피팅하면 훨씬 설득력있는 확률모형을 만들 수 있을것 같습니다.
Student's T분포는 특성상 fat-tail이 나름 설명돼요. 근데 0에 가까운 움직임은 약간 모자란게 조금 아쉽습니다.
포트폴리오를 주식, 채권, 금 등 여러 자산으로 구성할 때는 포트폴리오의 기대 수익률과 리스크(변동성)를 알고 싶을 경우가 있다.
기대수익률을 구하는 것은 본능적으로 이해할 수 있다. 이미 실전 주식투자를 할 때 지나간 기간의 손익에 대해서 비슷한 계산을 하고있었을 것이다. 각 자산의 보유 비율 w1, w2, ..., wn이 있을 때 각 자산의 기대수익률에 가중치를 둬서 더해주면 된다.
리스크는 조금 더 어렵다. 리스크는 변동성과 동치는 아니지만(리스크는 더 넓은 개념이다), 리스크를 설명하는데 변동성모델링이 종종 사용되는 것 같다. 포트폴리오의 변동성은 포트폴리오의 분산(variance)으로 모델링 할 수 있겠는데, 분산의 정의에 따라 위와 같이 수식을 전개할 수 있다.
솔직히 수학을 안한지 너무 오래돼서 진짜 어려웠다. 구글링을 해도 저렇게 간단하게 수식 전개를 해놓은 데를 찾을 수가 없었다. ㅠ 이 쉬운 수식 전개를 하는데 반나절이 걸려서 바보가 된 기분이다. 학생때 선형대수 A도 받았는데. 아 그게 벌써 8년전이네
변동성이라는 것은 포트폴리오의 수익률에 대한 변동성이다. 그리고 그 수익률 데이터(표본)는 결국 각 자산의 과거 히스토리에 의존할 수 밖에 없는 듯 하다. 정의에 따라 Cr은 수익률에대한 공분산 행렬이라고 보면 된다.
이 공분산행렬이 적절하지 않으면 포트폴리오의 리스크 모델링도 잘못된다는 것이다. 그러면 결국 표본부터가 제대로 되어야한다. 위에 링크한 문서처럼 이에 대한 논의는 많이 되고있는것 같다(제대로 읽지는 않음ㅎ) 단순히 과거 수익률을 표본으로 하여 공분산행렬을 만들어야 하는 것인가? 그게 가장 쉽긴 쉬운데, 좀 불완전해보이는 기분을 지울수 없다. Lookback period는 어떻게 정할 것인가? 전체 기간을 보더라도 EMWA(Exponential Weighted Moving Average)를 사용해서 최근 수익률 데이터에 더 가중치를 줄 수도 있지 않을까? 그리고 수익률을 구하기 위한 표본은 어떻게 구할 것인지? 월간 종가 데이터만 갖고? 아니면 중간값? 아니면 좀더 대표값을 잘 추출하기 위한 모델이 존재할까?..
근무가능 시간이 부족해서 강제퇴근 생활이 시작됐다. 걱정이다. 프로젝트가 잘 끝나려면 시간이라도 내놓고 엄청 매달려야 하는데. 덕분에 주말에 공부한 것에 대해 글 한편을 마음놓고 썼다.
글 한편을 쓰는데 굉장히 오래 걸렸다. 공부한 시간은 몇 배로 걸렸다는 건 당연한 얘기지만, 덕분에 다른 공부 할 것 진도를 나가지 못했다. 내가 생각해도 너무 이것 저것 많은 내용을 담으려고 했던게 아닐까 싶다. 누군가가 볼 것을 염두에 두고 써서 그런가? 다음부턴 그냥 개인적인 정리 수준으로 마무리해야겠다. 나름 정성껏 쓰고는 싶지만 그래선 안되겠다.
바로 이전 글에서 어떤 API를 사용해서 증권 가격 정보를 파이썬으로 받아올 까 고민을 했었다.
이런 고민의 배경에는 미래의 공부를 위해 수정 종가(adjusted close price) 정보 뿐 아니라, 흔히 OHLC라고 부르는 시고저종가의 수정가격을 전부 알고 싶었기 때문이다.
과거의 가격 정보를 가지고 데이터를 뽑아낼 때는 반드시 수정 가격을 사용해야한다. 그렇지 않으면 이런 사태가 벌어진다.
Apple(APPL) historical close price
위는 애플의 10년 종가 차트다. 2014년 6월 9일 애플의 주가가 한순간에 떡락을 해버린걸까?... 당연히 아니다. 그 날 너무 비싼 주당 가격을 1대 7로 액면분할 했을 뿐이다. 그 사실은 애플의 투자자를 위한 공식 자료에서도 볼 수 있다. (링크)
수정 가격을 사용하면 이런 과거의 절대 가격도 현재 가격의 시점으로 볼 수 있게 된다.
Apple(APPL) historical adjusted close price
애플의 위엄이 이제야 제대로 보인다. 현재 시점으로 과거 가격에다 과거 발생한 액면분할(stock split)과 현금배당(cash dividends)을 반영한 가격이 수정가격(adjusted price)이라고 보면 된다.
안타깝게도 모든 수정 OHLC 가격을 그냥 뿌려주는 API는 없었다. 그래서 희망을 가져본 것이 FinanceDataReader 패키지였다. 잘은 몰라도 investing.com 등에서 이미 수정된 가격을 가져오는 것 같았다. 그런데 아무리 봐도 아쉬운 점이 있었으니, 과거 데이터로 갈수록 실제 수정 가격이랑 약간 오차가 있었다.*
*오차가 있다고 스스로 결론지었지만, 잘못된 정보를 드렸을 가능성이 있으므로 여러분도 직접 계산을 해보길 바랍니다.
import datetime as dt
from dateutil.relativedelta import relativedelta
import pandas_datareader as web
import numpy as np
from pandas import DataFrame, Series
import pandas as pd
%matplotlib inline
import matplotlib.pyplot as plt
plt.rcParams["figure.figsize"] = (14,8)
plt.rcParams['font.size'] = 16
plt.rcParams['lines.linewidth'] = 1
plt.rcParams["axes.grid"] = True
plt.rcParams['axes.axisbelow'] = True
import mplfinance as mpf
먼저 패키지들을 import해오자.
datetime 및 relativedelta는 정확히 현재 시점으로 과거 10년의 데이터를 가져오기 위해서 가격 정보 수집을 위해서 pandas_datareader를, 벡터 연산을 위해 numpy를, 가격정보를 담을 자료구조를 위해 pandas DataFrame을, 차트를 그리기 위해 matplotlib과 mplfinance를 import했다.
plt.rcParams...부분은 앞으로 그릴 플롯의 형태를 미리 전역 설정해주는것이다. 자세한건 나중에 따로 공부해야지.
10년 전 오늘의 날짜를 정확하게 가져오려면 이러한 방식을 사용해야 한다. 이해가 안 가는 것이 있다면 datetime 패키지의 timedelta 클래스를 사용해서는 1년 이상의 날짜 연산이 안된다. timeutil의 relativedelta 클래스를 사용해줌으로써 해결.
중요한 부분이다. 애플의 10년 가격 정보와 수정 정보를 받아오는것인데, 그 전에 먼저 alpha-vantage(이하 av)에 무료 회원가입을 하고서 API 키를 받아야한다(링크). 가입하면서 알려주는 API 키는 한번 창을 끄면 다시는 알려주지 않으므로 반드시 따로 저장해놓도록 한다. 이렇게 받은 API키는 av_apikey 변수에 string으로 할당해놓자. pandas_datareader의 DataReader 메서드를 통해 av API를 사용할 수 있다. 첫 번째 패러미터로 티커를, 두번째는 'av-daily-adjusted'를 입력해줌으로써 av의 일간 수정 가격을 받아오겠다고 명시하자. 세 번째에는 아까 받은 API key를 꼭 제공해야 한다.
그리고 약간의 가공을 해주자. av에서는 데이터의 인덱스(날짜)를 string type으로 주는데, 호환성 높은 시계열 데이터로 만들기 위해서는 to_datetime을 사용해 datetime type으로 인덱스를 바꿔주는 게 좋을 것이다.
그러면 다음과 같이 10년치 애플 가격이 받아와진다.
처음에 여기서 한번 실망을 했다. 왜 수정 종가밖에 없는거지? 하고. 그런데 알고보니 오른쪽 두 열이 힌트였다. dividend amount가 배당이고 split coefficient가 액면분할계수다. 참고로 기업의 주식배당(stock dividends)는 원 글을 참고하면, 주식 지출이 (회사 장부로부터 주주에게로) 이미 존재하는 주식의 소유권만 변경하기 때문에 과거의 가격 수정이 필요하지 않다고 한다. 즉 기업의 시가 총액이 변하는 것이 아니므로 가격을 수정할 필요가 없는 것이다.
배당 및 주식 액면분할 효과란 즉 액면분할하면 액면분할계수대로 나누고, 배당을 주면 주당 현금 배당금만큼 주가에서 빼면 된다. 상식적이다. 위는 그것을 공식화한 것인데, 주의할 점은 'S(Split ratio)'다. 1대 7 액면분할을 하면 S=1/7이 된다. 그래서 공식에서는 바로 위에서 말한 것과 다르게 '곱하기'로 표시되어 있는 것이다.
이제 이것을 코드화하는 일만 남았다.
def calculate_adjusted_prices(df: DataFrame, column: str, split_coefficient: str, dividend: str):
"""
Refer to https://joshschertz.com/2016/08/27/Vectorizing-Adjusted-Close-with-Python/
Vectorized approach for calculating the adjusted prices for the
specified column in the provided DataFrame. This creates a new column
called 'adj_<column name>' with the adjusted prices. This function requires
that the DataFrame have columns with dividend and split_ratio values.
:param df: DataFrame with raw prices along with dividend and split_ratio
values
:param column: String of which price column should have adjusted prices
created for it
:param split_coefficient: String of split coefficient column.
e.g. split_coefficient=7 means that 1 stock is split into 7 stocks.
:param dividend: String of dividend column
:return: DataFrame with the addition of the adjusted price column
"""
adj_column = 'adj_' + column
# Remove redundant column
if adj_column in df.columns:
del df[adj_column]
# Reverse the DataFrame order, sorting by date in descending order
df.sort_index(ascending=False, inplace=True)
# Extract values
price_col = df[column].values
split_col = df[split_coefficient].values
dividend_col = df[dividend].values
adj_price_col = np.zeros(len(df.index))
adj_price_col[0] = price_col[0]
# Calculate adjusted prices
for i in range(1, len(price_col)):
adj_price_col[i] = \
round(
number=(adj_price_col[i - 1] + adj_price_col[i - 1] * (((price_col[i] / split_col[i - 1]) - price_col[i - 1] - dividend_col[i - 1]) / price_col[i - 1])),
ndigits=4
)
df[adj_column] = adj_price_col
# Change the DataFrame order back to dates ascending
df.sort_index(ascending=True, inplace=True)
return df
위 공식을 벡터화하여 계산하는 방법이다. 사실 원작자는 처음엔 loop를 사용해서 현재부터 과거까지 하나하나 계산했는데, 긴 시계열에서 아주 오랜 시간이 걸렸다고 한다. 그래서 이 연산을 벡터화(링크)한 코드가 위의 코드다. 이론적인 부분까지 깊게 들어가긴 어렵다. 그의 헌신을 감사히 여기고 그의 코드를 사용하자. 위 코드는 원본에서 약간의 수정을 거쳤다. av의 split coefficient column에는 1대 n 액면분할시에 1/n이 아닌 n이 그대로 들어가있었다. 해당 부분을 수정했다. (나의 헌신도 한방울 포함되어있다.)
코드 자체는 이해하기 어렵지 않다. dataframe의 필요한 각 column을 numpy에 넣어서 열벡터로 각각 만들고, 위에 언급한 공식을 그대로 적용해주는 것이다. 인접한 가격이 수정되는것을 반영해주어야 하므로 시계열 길이만큼 반복해준다.
메서드는 만들어져있으니 적용해본다.
for price in ['open', 'high', 'low', 'close']:
ret_df = calculate_adjusted_prices(df_AAPL_av, price, 'split coefficient', 'dividend amount')
이런 dataframe이 만들어진다.
av에서 기본으로 제공하는 adjusted close column과 직접 계산한 adj_close column의 값을 비교해보면, 아주 먼 과거에서도 별로 큰 차이가 없다. 내가 FinanceDataReader를 아쉬워했던것이 이 부분이다. FinanceDataReader에서는 먼 과거 시점의 가격 정보가 꽤 틀어져있었기 때문이다. 원본 OHLC가격 정보, 배당금이나 액면분할계수는 그냥 과거의 사실 그 자체임에도 불구하고 계산한 값과 다르다는 것을 받아들이기 어려웠다.
오늘도 12시간 근무를 찍었지만 집에 와서도 체력이 좀 남아있다. 살인적인 스케줄에 좀 적응이 된걸까. 그저 곧 자야한다는 게 아쉽다. 랜덤벡터 공부 하고싶은데. 이 말도 안되는 과제가 어떻게든 해결되면 연차도 좀 쓰고, 투자 공부에 다시 힘을 쓰고 싶다. 그건 아마 7월 중순, 혹은 그 이후? 그 때 까진 이 미친 생활을 계속해야겠지.
투자 공부를 할수록 내가 지향하는 투자 스타일에 방점이 찍힌다. 나는 다양한 자산군에 분산투자를 통해 위험조정수익률을 극대화하고, 가능하다면 변동성 타게팅 등의 기법을 사용해서 레버리지를 적절히 활용하고싶다. 이런 아이디어에 회의적인 의견도 많이 보인다. 인정한다. 뭐 할 수 있는 데 까지 해보는거지. 현재의 목표를 달성하는 것은 그리 오래 걸리지 않을거라 기대해본다.
자가 한 채는 있어야할텐데. 서른 전에 가능한 일인가 과연? 빚 내면 안될 거야 없겠지. 부동산 매매는 바로 위에서 말한 내 투자 방법론(?)과 너무 떨어져있는 문제같다. 마치 단일 종목에 레버리지 몰빵 투자를 하는 것 같은 느낌. 부동산 공부도 필요하겠구나.
적어도 지금의 삶은 날 행복하게 해주지 못한다. 퇴근 후 이렇게 보내는 한 시간이 나머지 12시간보다 행복하다. 나의 바람처럼 나의 의지대로 살기 위해선 퇴근 후에 이런 정리의 시간이 필요하다.
할 수 있다면 오늘처럼 다음 하나를 꾸준히 지켜보자. 집에 도착한 후 첫 15분동안 눕지 않기.
먼저 라이브 트레이딩을 위해서는 실시간으로 주가를 수집해야 할 수 있고, 백테스팅을 위해서라면 과거 데이터를 한꺼번에 불러올 수 있어야 한다. 나는 우선 안정적으로 과거 데이터를 수집할 방법이 필요하다.
몇몇 방법들을 시험해 봤는데. 아직도 확실한 방법을 못 찾겠다. 몇 가지 방법은 있다. 1. 증권사 API와 트랜잭션하기 2. FinanceDataReader 패키지(git 링크) 3. pandas_datareader 패키지(doc 링크) 4. alpha-vantage API(doc 링크)
우선 1번은 다른 방법에 비해서 가장 디테일한 정보를 받을 수 있다. 하지만 다루기가 다른 방법들에 비해서 좀 까다롭다. 증권사마다 계좌도 파야 하고, 무엇보다 해외 시장 데이터는 가져올 수 없다. 게다가 파이썬에서 직접적으로 COM 트랜잭션 할 방법은 없기 때문에 PyQt같은 패키지를 통해 간접적으로 접근해야 하는 등... 귀찮다. 결국엔 이용해야 하는 종착지라 현재는 보류중. 난 좀 더 간단한 방법이 필요하다.
2번은 정말 간편하다. 간단한 import문 한방에 한국, 미국 전 세계 다양한 시장의 증권 수정가격을 dataframe으로 불러올 수 있다. 게다가 미국/한국의 채권 수익률, 환율이나 암호화폐 시계열도 지원한다! 정말 좋은 패키지다. 문제는 데이터의 양이 조금만 많아지면 데이터를 불러오다 말고 끝난다. 정말 사용하기 간편하고 좋은데 S&P500같은 긴 시계열에서는 불완전하다고 느꼈다. 결국 온전히 불러오기 위해선 추가적인 품이 들어간다. https://financedata.github.io/posts/finance-data-reader-users-guide.html
위 문서를 보니 한번에 가져오는 데이터의 건 수가 5000개라고 되어있다. 여러번에 나누어 불러오는 메서드가 필요할 것 같다.
3번은 가장 일반적인 방법으로 보통 Yahoo Finanace API랑 연동해서 불러오는 경우가 많다. 조금만 손쓰면 국내 주식시장 가격도 불러오는 게 가능하다. 그런데 야후파이낸스 API 지원이 끊겼다는 얘기가 있다(링크). 그래서 구글링을 좀만 해도 야후파이낸스 API의 대체수단을 찾는 사람이 좀 있다. 사실 얘 아직 열심히 써보진 못했다. 또한 해당 패키지를 통해 quandl API, Fama/French API등등을 사용할 수도 있다.
4번은 3의 대안으로 찾은 것. 미국 시장/외환 시장 정보를 불러올 수 있다. 이 패키지(링크)를 사용하면 alpha-vantage의 데이터를 좀 더 손쉽게 가져올 수 있다. 완전 자유롭게 데이터를 읽어오려면 유료이나 약간의 시간적 제약과 함께 무료로 사용할 수도 있다. 사용성도 간편한 편이고 가장 큰 장점은 intra-day(장중)가격 데이터를 1분, 5분, 15분, 30분, 60분 간격으로 읽어올 수도 있다는 점이다! 물론 모든 정보를 다 저장하려면 공간 제약이 있을 것이다. 그리고 기술적 지표를 함께 제공하는 것도 큰 장점이다. 단점은 사이트에 가입해서 받을 수 있는 API키가 강제된다는 것이며, 불러올 수 있는 가장 먼 가격 데이터가 20년 전이었던 것 같다.
Investopedia: 변동성은 자산의 가격이 평균가격을 중심으로 얼마나 크게 변동하는지를 나타낸다. 이는 자산의 수익 분산에 대한 통계적 척도인 것이다. 베타계수, 옵션가격결정모형, 수익의 표준편차 등 변동성을 측정하는 몇 가지 방법이 있다. 변동성이 큰 자산은 종종 변동성이 작은 자산보다 더 위험하다고 여겨지는데, 그 이유는 가격 예측 가능성이 낮을 것으로 생각할 수 있기 때문이다.
변동성이란?
증권 가격은 OHLC라고 해서 일정 기간의 시/고/저/종가를 이어붙이는 것으로 묘사할 수 있다. 그것을 시각화 한 것이 흔히들 보는 가격 차트다. 차트를 보면 쉽게 보이듯 증권 가격은 시시때때로 출렁인다. 근데 같은 '주식' 카테고리에 있어도 회사나 업종이 다르면 출렁이는 정도가 다른 것을 볼 수 있다. 이 출렁임의 정도가 투자자들에게는 위험(risk)으로 받아들여지기 때문에, 같은 기대 수익률을 가진 여러 증권이 있다면 가장 위험이 적은 증권이 당연히 더 매력이 있을 것이다(참고: CAPM). 따라서 위험은 정량적으로 파악할 필요가 있다. 계량된 위험을 나는 변동성(volatility)이라고 부르겠다*.
* 이 글을 쓰는 사람은 비전문가/비전공자/투자 초보/일반인입니다. 틀린 부분은 지적 부탁드립니다!!!
그런데 정석적으로는 3번의 '로그 수익률의 표준편차'를 변동성이라고 정의한다. 구체적으로 말하면 이것은 역사적 또는 사후적(ex-post) 변동성이다. 수 많은 재무론 교과서에서 변동성을 그렇게 정의하고 그것을 토대로 많은 이론을 설명한다더라. 물론 나는 재무론 교과서를 본 적은 없다. 잘은 몰라도 아마 그 근간에는 해리 마코위츠(Harry Markowitz)의 현대 포트폴리오 이론(Modern Portfolio Theory; MPT)이 있을 것이다. 최초의 포트폴리오 이론에서 변동성을 그렇게 정의했고, 충분히 설득력이 있었기 때문일 것이다.
로그 수익률의 표준편차
먼저 표준편차의 개념과 표준편차를 구하는 방법은 여기를 참고하자. 시간이 많지 않아서...
Investopedia: 표준편차는 데이터 집합의 평균에 상대적인 분포를 측정하는 통계량이며 분산의 제곱근으로 계산된다. 평균에 상대적인 각 데이터 지점 사이의 변동을 결정하여 분산의 제곱근으로 계산한다. 데이터 점이 평균에서 멀리 떨어져 있으면 데이터 집합 내에서 더 높은 편차가 존재하기 때문에 데이터가 더 많이 분산될수록 표준 편차가 커진다.
표준편차를 변동성의 대표값으로 사용하는 데는 로그 수익률의 분포가 정규분포(normal distribution)를 따른다는 가정이 필요하다. 즉 과거를 바탕으로 앞으로 나타날 수익률의 약 68.3%정도는 기대 수익률(기대값)의 ±1 표준편차 이내로 발생하고, 약 95%정도는 ±2 표준편차 이내에 발생한다는 얘기다.
숫자를 들어 설명해보자. 자본금이 $50000이 있다 치고, 내가 투자할 자산의 연간 변동성(로그 수익률의 표준편차)이 30%라 하고, 수익률이 정규분포를 따른다면 1년 뒤의 수익금이 $65000~$35000 이내로 변할 확률이 68%쯤 된다.
반대로, 흔히 얘기하는 '위험 감내도'를 30%로 설정한다는 것은 보통 'MDD(Max Drawdown) 30%까지 버틸수 있다'는 얘기겠지만, 실제 체감상 감내할 수 있는 변동성은 그보다 낮을 것이다. 그 자산이 30%안쪽으로 변할 확률은 68%정도 밖에 안되기 때문이다.
쓰다 보니 단순히 표준편차에 대해서도 생각할게 많아서 파이썬 구현은 다음에 해야겠다. 별 거 없는 내용일거라 생각했는데 꽤 의미있는 복습이었다.