본문 바로가기
Trading/Portfolio opt

포트폴리오 잠재 리스크

by bents 2021. 1. 26.

Q. 왜 시뮬레이션을 통해 수익률, 변동성값을 추정하려는 건가?

A. 역사적 수익률과 변동성이 미래에도 지속된다고 보장할 수 없기 때문이다.

 

 “Monte Carlo analysis” vs “Bootstrapping”

in relation to simulating returns series & generating corresponding CI as to a portfolio’s potential risks and rewards.

 

Technically Bootstrapping is a special case of the Monte Carlo simulation.

- Bootstrapping : 역사적 수익률 분포에서 단위기간만큼의 랜덤 추출을 n번한다.

   *sampling with replacement

- parametric MC: 과거 평균수익률과 과거 변동성을 평균과 표준편차로 가지는 정규분포에서 랜덤추출을 n번한다.

 

자산간의 상관관계가 높다면 이는 포트폴리오에 잠재리스크다.

포트폴리오내 자산간 상관관계가 약하거나 다른 방향으로 움직여야 "분산투자"의 의미가 있다. 

개별자산의 높은 변동성을 낮추기 위해서 포트폴리오를 만드는데, 만약 포트폴리오 내 자산이 완전히 똑같이 움직인다면 특정 시장환경에서 높은 변동성을 보인다. 코로나 사태와 같은 시장환경에서 모든 자산의 수익률이 -40%을 찍었다고 생각해보자. 

 

the historic correlations between the constituent assets’ returns in the “asset universe”

it is important to calculate the correlation between the asset’s RETURNS, NOT their prices

 

따라서 MC시뮬레이션할 때, "개별자산간 상관관계"의 정보를 담고 있어야 그 결과가 현실에 보다 적합하다.

MC 시뮬레이션할 때, 개별자산별로 정규분포에서 랜덤추출하면 개별자산은 서로 독립관계가 되어서, 원래 자산간 상관관계 정보를 잃어버기 때문이다. 안전하게 하려면 그냥 Bootstrapping 하자.

 

asset_universe_returns = asset_universe.pct_change()

# 포트폴리오 부트스트랩
portfolio_bootstrapping = (1+pd.DataFrame([random.choices(list(
    portfolio_returns.values), k=252) for i in 
    range(1000)]).T.shift(1).fillna(0)).cumprod()

# 포트폴리오의 개별자산에 대한 부트스트랩 
portfolio_constituents_bootstrapping = \
    pd.DataFrame([((asset_universe_returns.iloc[random.choices(
    range(len(asset_universe)), k=252)]).mean(axis=1)+1).cumprod().values 
    for x in range(1000)]).T
    
# 개별자산간 독립관계 - 비추
asset_returns_dfs = []

for asset in asset_universe_returns.mean().index:
    mu = asset_universe_returns.mean()[asset]
    sigma = asset_universe_returns.std()[asset]
    asset_mc_rets = pd.DataFrame([(np.random.normal(loc=mu, 
                    scale=sigma, size=252)) for x in range(1000)]).T
    
    asset_returns_dfs.append(asset_mc_rets)

weighted_asset_returns_dfs = [(returns_df / len(tickers)) for returns_df in asset_returns_dfs]
portfolio_constituents_mc = (reduce(lambda x, y: x + y,weighted_asset_returns_dfs) + 1).cumprod()

# 포트폴리오의 종합 수익률, 변동성 사용하기
portfolio_mc = pd.DataFrame([(np.random.normal(loc=mu, scale=sigma, size=252)+1) for x in range(1000)]).T.cumprod()