Post List

2016년 3월 10일 목요일

Risk Parity: Equal Risk Contribution

전통적 자산배분의 형태는
주식과 채권의 비율을 70:30 혹은 60:40 정도로 유지한다.

기존에 작성한
에서 설명한것 처럼 CPPI 라는 전략도 있지만,
주식에 비중이 쏠린다는 공통점이 있다.

Edward QianRisk Parity and Diversification의 논문을 통해
이러한 배분의 문제점을 지적한다.

주식의 위험이 채권에 비해 훨씬 큰 반면,
이러한 형태의 자산배분은
포트폴리오 전체의 위험을 증가시킨다는 것이다.


먼저 주식과 채권에 대한 수익률, 변동성
상관관계, Risk free rate를 다음과 같이 두자.

 
Return
St.dev
stock
6.25%
15.00%
bond
2.75%
5.00%

corr
0.2
risk free
1%


아래 그래프는 주식과 채권 비중에 따른
포트폴리오의 변동성과 샤프지이다.

주식의 비중과 위험은 비례하여 증가하지만,
샤프지수는 그렇지 않다.


전통적인 60:40 포트폴리오의 샤프지수는 0.40인 반면,
Edward Qian 설명하는 Risk Parity 포트폴리오 (25:75의 비중)가
0.45로써 가장 높은 샤프지수를 기록하였다.


그렇다면 Risk Parity Portfolio란 무엇인가?


각 자산별의 Risk contribution to portfolio 를 동일하게 만드는,
위의 예에서는 주식과 채권의 RC가 0.5로 동일하게 만드는 것이다.

직관적으로 생각하면, 주식의 위험이 더 큰 만큼
비중을 줄여, 위험 기여도를 같게 만들어 준다.

위험 기여도 (RC)는
(자산의 분산+공분산 / 포트폴리오의 분산)
으로 계산된다.

위의 예를 대입해보면,
Risk parity portfolio의 주식 RC는 50% 인 반면,
Traditional portfolio (60/40)의 RC는 92%가 나온다.

아래 그래프는 주식의 비중에 따른 주식 RC이다.



아래 그림은 주식의 기대수익 및 기대변동성에 따른
RC=0.5가 되게 만드는 주식 비중의 변화량이다.

다른 조건이 같을때,
주식의 기대수익률이 늘어날수록, 변동성이 낮아질수록
주식 비중이 높아진다.




RC가 자산별로 같게 만드는
Optimal Weight 를 구하는 방법은 다음과 같다.


그러나 다행히도, simply 역변동성으로 계산해도
위의 값과 거의 비슷한 결과가 나온다.



다음은, Risk parity 전략과 Constant Mix 전략 (60:40비중),
그리고 KOSPI200 ETF를 100% 투자한 포트폴리오의
백테스트 결과이다.

전기 1년의 변동성을 이용해, stock과 bond의 비중을 조정하였으며,
Stock의 대용치로는 KODEX KOSPI200 ETF를,
Bond의 대용치로는 국고채 총수익 지수를 사용하였다.



각 전략의 년도별 수익률

각 전략의 누적 수익률과 년도별 주식 비중



모든 기간에서 (+) 수익률을 기록하였으며,
특히 금융위기가 발생한 2008년에도 8% 수익을 기록하여,
뛰어난 하락방어를 능력을 보여주었다.

굉장히 stable 한 수익률을 보여주어
가장 높은 수익률과 가장 낮은 변동성을 기록하였다.

인터넷에 검색해보면,
Leverage ETF를 이용한 비중전략,
수시로 비중을 조절하는 Dynamic Risk Parity Portfolio 방법론도
많이들 개발되고 있습니다.

관심 있으신 분은 찾아 보시길...


Equal Risk Contribution을 활용한 비중조정전략은
자산간 배분을 넘어, 자산 내 비중조정전략에도 많이 쓰이며,

특히 Smart Beta Multi-Strategy 분야에 응용되고 있습니다.

댓글 3개:

  1. 안녕하세요 선생님.
    DAA에서 Risk Parity 코드를 가지고 실습을 좀 하고 있는데 PERC나 PGMV 코드를 쓰면 계속 최적화 값을 찾는 오류가 발생하네요. 정확히 말하면 싸이클이 돌다가 멈춘 후 R은 계속 코드 실행상태입니다.....
    어쩔때는 바로바로 찾고 어쩔때는 뻑나서 한시간이 걸려도 못찾는데 이게 패키지 문제인건지 제 컴퓨터 문제인건지 모르겠네요.
    혹시 저만 이러는걸까요? ㅠㅠ

    답글삭제
    답글
    1. 아... 원인이 뭔지 알거 같습니다.

      prices = list()
      for(i in 1:length(symbols)) {
      tmp = Ad(get(symbols[[i]]))
      prices[[i]] = tmp
      }
      prices = do.call(cbind, prices)

      num = 4
      mom = 6

      ret_d = as.matrix(Return.calculate(prices[, 1:(ncol(prices)-1)]))
      ret_cash = as.matrix(Return.calculate(prices[, ncol(prices)]))

      ret_m = as.matrix(apply.monthly(ret_d, Return.cumulative))
      ret_cash_m = as.matrix(apply.monthly(ret_cash, Return.cumulative))

      ret_mom_m = matrix(NA,nrow(ret_m),ncol(ret_m))
      for (i in mom: nrow(ret_m)) {
      ret_mom_m[i,] = Return.cumulative( ret_m [(i-mom+1):i, ] )
      }
      rownames(ret_mom_m) = rownames(ret_m)
      colnames(ret_mom_m) = colnames(ret_m)

      여기서 ret_d 혹은 ret_m 구하는데 R이 수익률을 이상하게 구해버리네요....
      몇몇 티커들을 말도안되는 return 값들로 뱉어내버리는데 R 패키지 자체가 문제인건지 잘 모르겠습니다.
      ex) SPY 5월 수익률이 500% 상승
      티커 조합을 노가다로 몇개씩 바꿔보면 정상이었다가 또 다시 이상한 return으로 돌아가고....
      return 값을 정상으로 뱉어낼때만 PERC 구문이 돌아가네요.

      삭제
    2. 요새 야후가 가격데이터 url을 바꿔버리면서 quantmod 에서 데이터 불러오는거 자체가 제대로 워킹되고 있지 않습니다. quantmod 패키지 만든분이 해결하고 있긴 하는데 어떻게 될지 모르겠고, 일단은 google 에서 데이터 읽는걸로 바꿔서 테스트 하면 될겁니다.

      삭제