投资学的一些例题代码演示

张剑

2020/03/13

Categories: 投资学 Tags: 作业

投资决策之——内部收益率法则

IRR计算思路演示

这里我们只需使用tidyverse包绘图

pacman::p_load(tidyverse)
x <-c() # 建立两个空集,用于存储循环数据
y <-c()
for ( i in seq(0,0.2,by = 0.0001)){ # 建立for循环,起点终点步长
  npv = -100+ 30/(1+i)+60/(1+i)^2+40/(1+i)^3
  x = append(x,i)
  y = append(y,npv)
}
res <- tibble(irr=x,npv=y) #将循环数据存储为数据集
#作图
ggplot(res,aes(x=irr,y=npv)) + geom_line()+
  geom_hline(yintercept = 0 ,color='red',alpha=0.6) +
  geom_vline(xintercept = 0.137,size=1.3,color='blue') +
  tidyquant::theme_tq() + xlab('贴现率')+ylab('对应NPV') +
  ggtitle('演示内部收益率IRR的求解思路')
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo

支付宝借呗内部收益率计算

R之所以强大是因为用的人多,包多。我们这里调用jrvFinancez这个包来帮助我们直接计算irr

pacman::p_load(jrvFinance,tidyverse,DT)
cf <- tibble(cf=c(-50000,190,310,300,310,310,300,
                  310,300,310,310,280,50310),t=seq(0:12))
cf %>% datatable()
xlhb_irr <- irr(cf$cf,cf.freq = 12)
paste('先利后本的IRR是',xlhb_irr)
## [1] "先利后本的IRR是 0.0730734556310215"

那么先利后本的还款方式的IRR是7.31%

接下来我们计算每月等额的IRR

cf_2 <- tibble(cf = c(-50000,rep(4324.16,12)),t=seq(0,12))
cf_2 %>% datatable()
myde_irr <- irr(cf_2$cf,cf.freq = 12)
paste('每月等额的IRR是',xlhb_irr)
## [1] "每月等额的IRR是 0.0730734556310215"

那么先利后本的还款方式的IRR是7.13%,和先利后本的差距不到0.2%

接下来可结合其他信贷产品,考虑借款便利性与承受能力确定是否选择使用借呗借款,以及选择何种方式借款。

纯储蓄(投资型)保险是否值得购买

# 该保险现金流分布
cf <- tibble(period= 0:65,exp = 0)
cf <- cf %>%
  mutate(exp = if_else(period %in% seq(0,9),-6000,0)) %>%
  mutate(income  = if_else(period %in% seq(3,65,by = 2),3000,0))
cf[66,"income"] <- 300000
#上一行是为最后一期赋值

#展示一下现金流
cf<-cf %>%  mutate(pmt = exp+income) %>%
  mutate(cum = cumsum(pmt)) 

cf %>% datatable(rownames = F, caption = "该保险的现金流",
      colnames = c('年份','支出','收益','净收益','累计收益'))
#计算净收益的irr
irr <- cf %>%
  select(pmt) %>% 
  pull() %>%
  irr()
#利用jrv包进行计算,注意40行用了一个pull函数
paste("该保险产品的IRR是:",irr)
## [1] "该保险产品的IRR是: 0.0428546906155038"
ggplot(cf,aes(x=period,y=cum))+geom_point()+
  geom_line()+theme_bw()+geom_hline(yintercept = 0,color='red')+
  xlab('时间')+ylab('累计收益')+ggtitle('该保险的非贴现的累计收益')

那么这项保险产品的现金流的IRR不到5%左右,是否值得选择呢?需要结合投资者面临的投资环境综合分析。


最后补充一个小小的内容:

在R中使用for循环是非常慢的,一般不要大量使用for循环,比如我们前面用for循环来演示irr求解的时候,如果把步长设置的较小,会导致运算速度很慢,这时建议大家使用apply函数,会大幅提升运算性能。

具体演示如下:

pacman::p_load(microbenchmark)
fun1 <- function(){
  x <-c()
  y <-c()
  for ( i in seq(0,0.2,by = 0.0001)){
    npv = -100+ 30/(1+i)+60/(1+i)^2+40/(1+i)^3
    x = append(x,i)
    y = append(y,npv)
  }
  res <- tibble(irr=x,npv=y)
  return(res)
}


fun2<-function(){
  irr <-seq(0,0.2,by=0.0001)
  myfun <- function(i){
    npv = -100+ 30/(1+i)+60/(1+i)^2+40/(1+i)^3
  }
  npv <- sapply(irr,myfun)
  res <- tibble(irr=irr,npv=npv)
  return(res)
}

res<-microbenchmark(fun1(),fun2())
res
## Unit: milliseconds
##    expr     min      lq     mean  median       uq     max neval cld
##  fun1() 10.3038 10.8384 13.32147 13.3481 13.66435 68.9810   100   b
##  fun2()  1.9464  1.9748  2.17579  1.9983  2.05075 12.0258   100  a
autoplot(res) + theme_bw() + ggtitle('性能差异')
## Coordinate system already present. Adding new coordinate system, which will replace the existing one.