수익을 높이기 위한 현금 보유 비율은 어느 정도가 좋을까요?


이전 포스팅 '켈리의 공식'에서 현금이라는 종목을 어느 정도 유지하는 것이 수익률을 높이는 있음을 얘기했습니다. 그러면 어느 정도가 좋을까요?


비율을 결정하는 캘리의 공식은 다시 살펴보겠습니다.


     (적정 투자 비율) = (p*W - q*L)/ ( W* L)

     p  : 성공 확률

     q  : 실패확률

     W : 성공시 이익 비율

      L :  실패시 손해 비율


비율을 결정하기 위해서는 p, q, W, L의 값을 알아야 합니다. 특정 종목이 오를 확률, 내릴 확률, 오르는 폭, 내리는 폭을 알 수는 없습니다. 특정 종목의 값 대신 주식 시장의 지수를 이용해 보면 어떨까요?


지수가 상승한 날을 성공으로, 상승폭을 이익 비률로, 하락한 날을 실패로, 하락폭을 손해 비율로 대응을 시켜서 투자 비율을 찾아보겠습니다. 계산에는 2010년 1월 1일부터 오늘까지의 코스피(KOSPI) 지수를 사용했습니다.




  (성공확률) = p = (상승일수)/(전체일수) = 0.516

  (실패확률) = q = (하락일수)/(전체일수) = 0.483

  (이익비율) = W = 0.00655

  (손해비율) = L =  0.00691

  (적정 투자 비율) = (p*W - q*L)/(W*L) = 0.93 


코스피 지수로 계산한 결과는 93% 투자하고, 7% 정도의 현금 유지로 계산되었습니다. 상승확률은 하락확률보다 높고, 상승폭은 하락폭보다 작습니다.


위의 계산은 하루하루를 한번의 투자로 계산한 결과입니다.



매주마다 투자 결정을 한다고 하면 어떻게 될까요?


  (성공확률) = p = (상승주)/(전체주) = 0.567

  (실패확률) = q = (하락주)/(전체주) = 0.433

  (이익비율) = W = 0.013

  (손해비율) = L =  0.017

  (적정 투자 비율) = (p*W - q*L)/(W*L) = 0.92


각 주를 한번의 투자로 생각한다면 92%를 투자하고, 8% 현금 유지로 계산됩니다. 상승확률은 높아졌으나, 손해비율과 이익비율의 차가 커지면서 다소 높은 현금보유로 계산된 것 같습니다.



매달마다 투자 결정을 한 결과도 살펴봅니다.

  (성공확률) = p = (상승달)/(전체달) = 0.570

  (실패확률) = q = (하락달)/(전체달) = 0.430

  (이익비율) = W = 0.026

  (손해비율) = L =  0.031

  (적정 투자 비율) = (p*W - q*L)/(W*L) = 2.05


매달 데이터로 계산하면 켈리의 공식에서 투자비율은 2.05로 갖고있는 돈보다 더 많이 투자하도록 계산됩니다. 투자금의 105%를 대출(?? ^^;) 받아서 투자하도록 계산되었습니다.... 


그런데, 위의 값은 계산을 위한 데이터의 기간을 변경하면, 크게 바뀝니다. 특히나 2008년 금융위기, 1998년 외환위기 시절을 포함하면 음수(-)가 나오기도 합니다. 투자하지 말라는 겁니다....^^;


내년(2019년)이 이전 어느 기간과 비슷할 것인지에 따라서 기초 데이터의 기간을 정해보면 어떨까요?


개인적인 경험으로는 90% ~ 99% 사이에서 유지하는 것이 좋은 것 같습니다.

주가가 올랐을 경우에는 일부 매도해서 현금 비중을 높이고

주가가 하락하면 관심 종목을 좋은 가격에 매수하여 현금 비중을 낮추는 방법입니다.


금일(12월 24일) 9%의 보유현금으로 관심을 갖던 O사를 예약한 가격에 매수할 수 있었습니다.

현금 보유 비율은 7.7%로 줄었습니다.

해당 종목은 장중 하락 후에 상승하여 0.7% 수익을 보이고 있습니다.


참고로, 코스피 지수에 대해서 켈리의 비율을 사용한 경우와 전체 투자한 경우의 수익을 그려보았습니다. 최근 시장이 폭락해서 인지 수익의 큰 차이는 보이지 않습니다. 다만, 월단위로 재조정한 경우에 시장이 좋았던 시점에서는 제법 차이를 보입니다.





( 계산에 사용한 R 스크립트 )

=============================================================

library(quantmod)
library(dplyr)
library(ggplot2)


# 1. KOSPI 2010년 부터 현재까지 변화 값 가져오기
#    KOSDAQ 자료는 제공되지않음.

my_symbol <- "^KS11"       ## KOSPI

src_loc     <- "yahoo"
from_day    <-"2010-01-01"
to_day      <- "2018-12-31"

output <- getSymbols(Symbols=my_symbol, src = src_loc, from = from_day, to = to_day, auto.assign = FALSE)
names(output) <- c("Open", "High", "Low", "Close", "Volume", "Adjusted")

attr(output, "dimnames")
plot(output)

table(is.na(output$Close))
output <- output[!is.na(output$Close),]

head(output$Close)
str(output)

output[[1]]
index(output)
plot(output$Close, col = "grey50")


# 전일 Close 값과의 차이 구하기
output$Close_1   <- lag(output$Close)
output$diff      <- output$Close - output$Close_1
output$diff_rate <- output$diff/output$Close

# 변동율 구하기
plus.mean <- mean(output$diff_rate[output$diff_rate>0,]$diff_rate)
plus.prob <- mean(output$diff_rate > 0, na.rm = TRUE )
plus.sd   <- sd(output$diff_rate[output$diff_rate >0 ,]$diff_rate)

minus.mean <- abs(mean(output$diff_rate[output$diff_rate<0,]$diff_rate))
minus.prob <- mean(output$diff_rate <0, na.rm = TRUE)
minus.sd   <- abs(sd(output$diff_rate[output$diff_rate <0, ]$diff_rate))

kelly.rate <- (plus.prob*plus.mean - minus.prob*(minus.mean))/(plus.mean*minus.mean)


## 100원이 얼마나 될까?
my.money <- rep(0,length(output$Close))
my.money[1] <- 100

for( i in c(1:(length(output$Close)-1))){
  if( !is.na(output$diff_rate[i+1]))
    my.money[i+1] <- my.money[i]*( 1 + output$diff_rate[i+1] )
  else
    my.money[i+1] <- my.money[i]
}
table(is.na(output$diff_rate))
tail(my.money)

# kelly 법칙을 따르면 얼마나 될까?
my.money.kelly <- rep(0,length(output$Close))
my.money.kelly[1] <- 100

for( i in c(1:(length(output$Close)-1)) ){
  if( !is.na(output$diff_rate[i+1]))
    my.money.kelly[i+1] <- my.money.kelly[i]*( 1 + output$diff_rate[i+1] ) * kelly.rate + my.money.kelly[i]*(1-kelly.rate)
  else
    my.money.kelly[i+1] <- my.money.kelly[i]
}

tail(my.money.kelly)

index(output)
output$my_money <- my.money
output$my_money_kelly <- my.money.kelly
output$date <- c(1:length(output$my_money))

text_pos_idx <- round(length(output$date)/2)
output %>% ggplot(aes(x=date)) +
  geom_line(aes(y=my_money), color="blue") +
  geom_line(aes(y=my_money_kelly), color = "red") +
  geom_text(aes(x=date[text_pos_idx], y=(my_money[text_pos_idx]-5)), label = "My Money", col="blue") +
  geom_text(aes(x=date[text_pos_idx], y=(my_money_kelly[text_pos_idx]+ 5)), label = "My Money Kelly", col="red") +
  labs(x=" 투자 경과 기간(일)", y="수익",title= " 매일 재조정 ")

# re-ballancing 주기를 얼마로 해야 할까?
# 매일 re-balancing은 비용이 높다
# monthly re-balancing으로 할까?
# ==> monthly data로 변환해야


# 변동율의 평균과 표준편차 구하기, + 확률과 - 확률 구하기
#  + 확률 : 이길 확률,  + 평균 : 얻는 량
#  - 확률 : 질 확률 ,   - 평균 : 읽는 량
#  얼마나 걸어야 할까?
#



output.weekly <- to.weekly(output)
names(output.weekly) <- c("Open", "High", "Low", "Close", "Volume", "Adjusted")
output.weekly$Close_1 <- lag(output.weekly$Close)
head(output.weekly)

output.weekly$diff_rate <- (output.weekly$Close - output.weekly$Close_1)/output.weekly$Close

# weekly 변동율 구하기
plus.mean.weekly <- mean(output.weekly$diff_rate[output.weekly$diff_rate>0,]$diff_rate)
plus.prob.weekly<- mean(output.weekly$diff_rate > 0, na.rm = TRUE )

minus.mean.weekly <- abs(mean(output.weekly$diff_rate[output.weekly$diff_rate<0,]$diff_rate))
minus.prob.weekly <- mean(output.weekly$diff_rate <0, na.rm = TRUE)

kelly.rate.weekly <- (plus.prob.weekly*plus.mean.weekly - minus.prob.weekly*minus.mean.weekly)/(plus.mean.weekly*minus.mean.weekly)

kelly.rate.weekly

str(output.weekly)

plot(output.weekly$Close)


## 100원이 얼마나 될까?
my.money.weekly <- rep(0,length(output.weekly$Close))
my.money.weekly[1] <- 100

for( i in c(1:(length(output.weekly$Close)-1))){
  if( !is.na(output.weekly$diff_rate[i+1]))
    my.money.weekly[i+1] <- my.money.weekly[i]*( 1 + output.weekly$diff_rate[i+1] )
  else
    my.money.weekly[i+1] <- my.money.weekly[i]
}
table(is.na(output.weekly$diff_rate))
tail(my.money.weekly)


# kelly 법칙을 따르면 얼마나 될까?
my.money.kelly.weekly <- rep(0,length(output.weekly$Close))
my.money.kelly.weekly[1] <- 100

for( i in c(1:(length(output.weekly$Close)-1)) ){
  if( !is.na(output.weekly$diff_rate[i+1]))
    my.money.kelly.weekly[i+1] <- my.money.kelly.weekly[i]*( 1 + output.weekly$diff_rate[i+1] ) * kelly.rate.weekly + my.money.kelly.weekly[i]*(1-kelly.rate.weekly)
  else
    my.money.kelly.weekly[i+1] <- my.money.kelly.weekly[i]
}

tail(my.money.kelly.weekly)

output.weekly$my_money_weekly <- my.money.weekly
output.weekly$my_money_kelly_weekly <- my.money.kelly.weekly
output.weekly$date <- c(1:length(output.weekly$my_money_weekly))

text_pos_idx <- round(length(output.weekly$date)/2)
output.weekly %>% ggplot(aes(x=date)) +
  geom_line(aes(y=my_money_weekly), color="blue") +
  geom_line(aes(y=my_money_kelly_weekly), color = "red") +
  geom_text(aes(x=date[text_pos_idx], y=(my_money_weekly[text_pos_idx]-5)), label = "My Money", col="blue") +
  geom_text(aes(x=date[text_pos_idx], y=(my_money_kelly_weekly[text_pos_idx]+ 5)), label = "My Money Kelly", col="red") +
  labs(x=" 투자 경과 기간(주)", y="수익",title= " 매주 재조정 ")


########### Monthly Rebalancing
output.monthly <- to.monthly(output)
names(output.monthly) <- c("Open", "High", "Low", "Close", "Volume", "Adjusted")
output.monthly$Close_1 <- lag(output.monthly$Close)
head(output.monthly)

output.monthly$diff_rate <- (output.monthly$Close - output.monthly$Close_1)/output.monthly$Close

# monthly 변동율 구하기
plus.mean.monthly <- mean(output.monthly$diff_rate[output.monthly$diff_rate>0,]$diff_rate)
plus.prob.monthly<- mean(output.monthly$diff_rate > 0, na.rm = TRUE )

minus.mean.monthly <- abs(mean(output.monthly$diff_rate[output.monthly$diff_rate<0,]$diff_rate))
minus.prob.monthly <- mean(output.monthly$diff_rate <0, na.rm = TRUE)

kelly.rate.monthly <- (plus.prob.monthly*plus.mean.monthly - minus.prob.monthly*minus.mean.monthly)/(plus.mean.monthly*minus.mean.monthly)

kelly.rate.monthly


plot(output.monthly$Close)


## 100원이 얼마나 될까?
my.money.monthly <- rep(0,length(output.monthly$Close))
my.money.monthly[1] <- 100

for( i in c(1:(length(output.monthly$Close)-1))){
  if( !is.na(output.monthly$diff_rate[i+1]))
    my.money.monthly[i+1] <- my.money.monthly[i]*( 1 + output.monthly$diff_rate[i+1] )
  else
    my.money.monthly[i+1] <- my.money.monthly[i]
}
tail(my.money.monthly)

# kelly 법칙을 따르면 얼마나 될까?
#kelly_rate.weekly <- 0.6
my.money.kelly.monthly <- rep(0,length(output.monthly$Close))
my.money.kelly.monthly[1] <- 100

for( i in c(1:(length(output.monthly$Close)-1)) ){
  if( !is.na(output.monthly$diff_rate[i+1]))
    my.money.kelly.monthly[i+1] <- my.money.kelly.monthly[i]*( 1 + output.monthly$diff_rate[i+1] ) * kelly.rate.monthly + my.money.kelly.monthly[i]*(1-kelly.rate.monthly)
  else
    my.money.kelly.monthly[i+1] <- my.money.kelly.monthly[i]
}

tail(my.money.kelly.monthly)

output.monthly$my_money_monthly <- my.money.monthly
output.monthly$my_money_kelly_monthly <- my.money.kelly.monthly
output.monthly$date <- c(1:length(output.monthly$my_money_monthly))

text_pos_idx <- round(length(output.monthly$date)/2)
output.monthly %>% ggplot(aes(x=date)) +
  geom_line(aes(y=my_money_monthly), color="blue") +
  geom_line(aes(y=my_money_kelly_monthly), color = "red") +
  geom_text(aes(x=date[text_pos_idx], y=(my_money_monthly[text_pos_idx]-10)), label = "My Money", col="blue") +
  geom_text(aes(x=date[text_pos_idx], y=(my_money_kelly_monthly[text_pos_idx]+ 12)), label = "My Money Kelly", col="red") +
  labs(x="개월수", y="수익",title= " 매월 재조정 ")

===============================================================


+ Recent posts