#### 1) ( Simulation을 이용한 Portfolio 최적화 ) * \(P_t\) : t 시점의 주식가격, \(t=0,1,2,...\)

이때,

매년 총자산중 일정비율 a ,\(0≦ a ≦\) 1 만큼은 위험자산(risky asset) 주식(stock)에 투자하고 나머지는 연 \(100*r_0\)%인 정기예금에 투자할 경우 미래 \(t\) 시점의 펀드의 자산가치 \(V_t\)는 아래와 같이 주어진다.

\(V_1=V_0(1+r_{p1})\)
\(V_2=V_1(1+r_{p2})=V_0(1+r_{p1})(1+r_{p2})\)
\(....\)
\(V_4 = V_0 \prod_{j=1}^{t} (1+r_{pj}) , t=1,2,...\)

단,\(t\)시점의 Portfolio a의 수익률 \(r_{pt} (a)\)

\(r_{pt}(a) = (1-a)*i + a*r_t, t=1,2,...\) 로 주어진다.

Portfolio의 투자성과를 판단하는 객관적 기준으로 만기(n)시점의 Portfolio의 자산가치 \(V_n(a)\)가 연평균 목표 수익률(\(r^*\))을 초과할 확률(Roy 의 Safety First Criterion):
\(RSFC(a)=P(V_n(a)>V_0(1+r^*)^n )\) 을 설정하고 이 확률값을 Simulation 방법으로 구한다.

Setup

library(tidyverse)
library(knitr)
library(kableExtra)
  1. a= 0.5 이고 Simulation 반복 횟수가 \(M=1000\)경우 목표달성확률을 구하시오.
  1. 난수 생성 시 1000*20개의 정규 확률난수(normal random number) 를 생성
total <- 20; sim <- 1000

#given data
mu <- 0.05
sigma <- 0.3
v0 <- 1
maturity <- 5
risk.free.interst <- 0.02
target.return <- 0.04
a <- 0.5

# 비율, 목표수익률, 만기에 따른 함수 생성
portfolio <- function(mu, sigma, a, target.return, total) {
  set.seed(1234)
    #random.matrix         
    random.matrix <- matrix(rnorm(sim*total, 0, 1), sim, total)
    #v0~v20 value matrix
    value.matrix <- matrix(1, sim, total+1) #v0~v20 
    colnames(value.matrix) <- c(0:total) #assign Colnames   
    value.matrix[,1] <- c(1)         #set V0 to 1
    #Calculate rates
    rt <- exp(mu + sigma * random.matrix) - 1  #Stock return at t
    rpt_a <- (1 - a)*risk.free.interst + a * rt   #t시점의 Portfolio a의 수익률
    for (i in 1:total) { 
      value.matrix[,i+1] <- value.matrix[,i]*(1+rpt_a[,i])
     }
return(value.matrix)
}
  1. 1000번의 Simulation 중 목표달성조건을 만족하는 경우의 횟수를 구한 후 1000으로 나누어 해당 확률값을 구함
#만기시점의 portfolio의 자산가치가 연평균 목표 수익율을 초과할 확률 (Roy의 Safety First Criterion)
rsfc <- function(mu, sigma, a, target.return, total) {
  # maturity matrix (1~20년)
  maturity.matrix <- matrix(1:total, 1, total)
  # n=1~20/ 목표 수익율
  target.matrix <- matrix(1*(1+target.return)^maturity.matrix, sim, total, byrow = TRUE)
  value.matrix <- portfolio(mu, sigma, a, target.return, total)
  rsfc <- colMeans(matrix(as.numeric(value.matrix[,-1]>target.matrix), sim, total))
  return(rsfc)
}

목표 달성 확률

rsfc(mu, sigma, a, target.return, total)
##  [1] 0.470 0.497 0.514 0.518 0.534 0.542 0.544 0.567 0.568 0.568 0.571
## [12] 0.561 0.571 0.570 0.584 0.572 0.569 0.566 0.565 0.568
  1. 처음 5번의 Simulation에 대하여 \(V_t(a), t=1,...10\) 의 시계열도표를 겹처서 그려보시오.
v.1_5 <- portfolio(mu, sigma, a, target.return, total)[1:5, 1:11] #choose v1 to v10
df <- data.frame(Simulation=c('S1','S2','S3','S4','S5'),v.1_5)
newdf <- gather(df, type, value, -Simulation)
ggplot(newdf,aes(x = type, y = value, group = Simulation, color = Simulation) ) +
  geom_line() +
  labs(x='t years',y='Vt(a)', title = 'Vt(a)') +
  scale_x_discrete(limit=c("X0","X1","X2","X3","X4","X5","X6","X7","X8","X9","X10")) +
  theme_bw()

  1. Portfolio \(a=0, 0.1, ..., 1\) \(0 \leq a \leq 1\) 일 때 목표달성확률을 구하고 이 값들의 그래프를 그리시오.
a.table <- matrix(c(seq(0, 1, 0.1), rep(0,11)), 11, 2)
for (i in 0:10){
a.table[i+1, 2] <- rsfc(mu, sigma, i/10, target.return, maturity)[maturity]
}
colnames(a.table) <- c("a", "prob.")
a.table
##         a prob.
##  [1,] 0.0 0.000
##  [2,] 0.1 0.188
##  [3,] 0.2 0.393
##  [4,] 0.3 0.479
##  [5,] 0.4 0.516
##  [6,] 0.5 0.534
##  [7,] 0.6 0.540
##  [8,] 0.7 0.543
##  [9,] 0.8 0.545
## [10,] 0.9 0.540
## [11,] 1.0 0.539
ggplot(data.frame(a.table), aes(a, prob.)) + 
  geom_point() + geom_line() + 
  labs(title = 'Roy Criterion', x="Portfolio a", y='Pr(Vn(a)>Vn*)')  +
  theme_bw()

  1. 목표달성확률을 최대로 하는 a값 a* 및 목표달성확률을 구하시오.
sensitivity <- function(mu, sigma, target.return, maturity) {
  prob <- NA
  for (i in 0:10){
    prob[i+1] <- rsfc(mu, sigma, i/10, target.return, maturity)[maturity]
  }
  a.star_prob <- max(prob)
  a.star <- sprintf('%.1f',0.1*(which.max(prob)-1))
  opt.a <- data.frame("a.star"=a.star, "prob"=a.star_prob)
    return(opt.a)
}
kable(sensitivity(mu, sigma, target.return, maturity)) %>%  
  kable_styling(full_width = F,
                position = "left")
a.star prob
0.8 0.545
  1. (Sensitivity Analysis) 위 방법을 이용하여 목표수익률 \(r^*\) 와 만기 \(n\)가 아래와 같이 주어질 경우,
    최적 Portfolio a*및 예상되는 목표 달성 활률을 구하는 표를 오나성하시오.
e.sensitivity <- rbind(sensitivity(mu, sigma, target.return=0.03, maturity=5),
                       sensitivity(mu, sigma, target.return=0.03, maturity=10),
                       sensitivity(mu, sigma, target.return=0.04, maturity=5),
                       sensitivity(mu, sigma, target.return=0.04, maturity=10),
                       sensitivity(mu, sigma, target.return=0.06, maturity=5),
                       sensitivity(mu, sigma, target.return=0.06, maturity=10))

kable(cbind("r*"=c(0.03, 0.03, 0.04, 0.04, 0.06, 0.06), "만기 n"=rep(c(5,10),3),e.sensitivity))%>%  kable_styling(full_width = FALSE, position="left")
r* 만기 n a.star prob
0.03 5 0.5 0.592
0.03 10 0.4 0.638
0.04 5 0.8 0.545
0.04 10 0.7 0.584
0.06 5 1.0 0.482
0.06 10 0.9 0.489



2) (Stock Price Model)


Problem : (KOSPI 수익률분포 찾기)
#1 에서 최적 Portfolio를 구하기 위해 필요한 주식의 로그수익률 \(ln(1+r_t)\) 분포를 2004.1-2018.1. 기간의 매 월말 KOSPI 시계열자료를 이용하여 구한다.
setup

#setting
library(lubridate)
setwd("D:\\0_grad\\data")
kospi <- read.csv("kospi.csv", skip=3)  
  1. 2004.1-2018.1 기간 월별 KOSPI 주가지수자료에 대해 \(P_t\)\(lnPt\) 의 시계열도표(Time Series Plot)를 각 각 그리시오.
#data setting
colnames(kospi) <- c("Date", "P")
kospi$P <- as.numeric(gsub( ",", "", kospi$P))
kospi$Date <- as.POSIXlt(paste(kospi$Date, 1, sep="/"), format="%Y/%m/%d")
kospi$Date <-as.Date(kospi$Date)
kospi <- kospi %>% mutate(lnPt=log(as.numeric(P)))

#Time Series Plot
#Pt 
ggplot(kospi, aes(Date, P)) + 
  geom_point() + geom_line() +
  theme_bw() + labs(title="P(t) time series", x="Date", y="P(t)")

#lnPt
ggplot(kospi, aes(Date, lnPt)) + 
  geom_point() + geom_line() +
  theme_bw() + labs(title="lnP(t) time series", x="Date", y="lnP(t)")

  1. 월별 로그주가지수 \(lnP_t\) 자료의 차분 (Difference) \(\triangledown lnP_t = lnP_t - lnP_{t-1}\)를 계산하고
    \(r_t=(P_t - P_{t-1})/P_{t-1} = P_t/P_{t-1} - 1, t=1,...,m\)
    \(ln(1+r_t)=\triangledown lnP_t\)
    을 이용하여 로그수익률 \(ln(1+r_t)\) 시계열도표 및 히스토그램을 그려보시오.
kospi$dlnPt[1] <- NA
for (i in 2:nrow(kospi)){
  kospi$dlnPt[i] <- kospi$lnPt[i] -kospi$lnPt[i-1]
}
#time series 
ggplot(kospi, aes(Date, dlnPt)) + geom_point() + geom_line() + 
  theme_bw() +labs(title="dlnP(t) time series", x="Date", y="dlnP(t)")

#Histogram
ggplot(kospi) + geom_histogram(aes(dlnPt), stat="bin") + geom_rug(aes(dlnPt)) +
  theme_bw() +labs(title="ln(1+r(t)) histogram", x="dlnP(t)")


c) (정규성 검정) 로그수익률 \(ln(1+r_t)\) 분호가 정규분포를 따르는지 정규 Q-Q plot을 그려보고 정규성 가정이 성립 하는지 검토하시오.

kospi <- kospi %>% mutate(rank=rank(dlnPt), pr=rank/(nrow(kospi)+1)) %>% mutate(norm=qnorm(pr))
ggplot(kospi, aes(norm, dlnPt)) + geom_point(size=2) + 
  geom_smooth(method="lm", se=F) +
  labs(title = "Normal Q-Q Plot", 
       subtitle = paste("R.sq = ", round(summary(lm(dlnPt ~ norm, kospi))$r.squared,4)*100, "%", sep = ""),
       x="", y="dlnPt") + theme_bw() 


직선에 가까우므로 정규성 가정이 성립한다.

  1. 로그 수익률 \(ln(1+r_t)\)의 분포가 서로 독립이고 아래와 같은 정규분포를 따른다고 가정할때
    \(ln(1+r_t)=lnP_t - lnP_{t-1}\) ~ \(N(\mu dt , \sigma^2 dt),\) \(t=1,2,...\)
    단, \(dt=1/12\) (월별자료)
    미지 모수 \((\mu, \sigma)\) 추정하시오.
mu.kospi <- 12*mean(kospi$dlnPt, na.rm=TRUE)  
sd.kospi <- sqrt(12)*sd(kospi$dlnPt, na.rm=TRUE)
c(mu.kospi, sd.kospi)
## [1] 0.07905805 0.17885606
  1. 위에서 구한 추정값 \((\hat{\mu}, \hat{\sigma})\)을 이용하고 #1을 활용하여 만기 n=10, 목표수익률 r=0.04인경우 ㅋ정기예금과 KOSPI에 매년 각각 (1-a, a)만큼 투자하는 포트폴리오중 최적 포트폴리오 a 및 해당 목표달성확률을 각각 구하시오.
kable(sensitivity(mu=mu.kospi, sigma=sd.kospi, target.return=0.04, maturity=10)) %>%  
  kable_styling(full_width = F,
                position = "left")
a.star prob
1.0 0.752
  1. (Sensitivity Analsis) 위 방법을 이용하여 목표수익률 \(r^*\)와 만기 n이 아래와 같이 주어질 경우 최적 Portfolio \(a^*\)및 예상되는 목표 달성 확률을 구하는 표를 완성하시오.
f.sensitivity <- rbind(sensitivity(mu=mu.kospi, sigma=sd.kospi, target.return=0.04, maturity=5),
                       sensitivity(mu=mu.kospi, sigma=sd.kospi, target.return=0.04, maturity=10),
                       sensitivity(mu=mu.kospi, sigma=sd.kospi, target.return=0.04, maturity=20),
                       sensitivity(mu=mu.kospi, sigma=sd.kospi, target.return=0.05, maturity=5),
                       sensitivity(mu=mu.kospi, sigma=sd.kospi, target.return=0.05, maturity=10),
                       sensitivity(mu=mu.kospi, sigma=sd.kospi, target.return=0.05, maturity=20))

kable(cbind("r*"=c(0.04, 0.04, 0.04, 0.05, 0.05, 0.05), "만기 n"=rep(c(5,10,20),2),f.sensitivity))%>%  kable_styling(full_width = FALSE, position="left")
r* 만기 n a.star prob
0.04 5 1.0 0.680
0.04 10 1.0 0.752
0.04 20 1.0 0.855
0.05 5 1.0 0.638
0.05 10 1.0 0.701
0.05 20 1.0 0.792