0
PresentValue <- function(interest.rate, number.periods, frequency) {

    if (interest.rate > 1) {interest.rate = interest.rate/100} else {"input interest.rate as a    whole number"}
    if (frequency < 1 || frequency > 12 ) {"frequency must be between 1 and 12"} else {interest.rate = interest.rate/frequency}

    (1+interest.rate)^number.periods  
}

上面的代码很简单,但我需要捕获用户输入错误。我看了看,tryCatch但对我来说毫无意义。另外,我认为这不是我目前需要的。

基本上,我需要做以下事情

首先,确保用户输入的利率是一个整数(即 5% 而不是 .05)其次我需要“询问”用户如何按月、按年等方式支付(频率)利率。然后将利率除以频率。

奇怪的是,第一个条件仅在其他 if 语句被标记时检查。

这个函数将是一个更大的函数集合中的一个对象,所以我认为我需要将这些视为最终将与 try catch 一起使用的警告。最后,如果在利率错误时函数没有终止,而只是要求用户正确输入利率,那就太好了。

提前为简单而道歉,但找不到我要找的东西。

编辑添加一些conetxt

下面是更大的功能。这显示了凸性表输出,我需要合并持续时间,然后是收益率和价格表,并使用 swerve 输出到页面。这是一本关于结构性融资的教科书。所以它需要对学生很好地工作

Bond.Cash.Flow <-function(issue.date, start.date, end.date, coupon, principal, 
frequency,  price){

library(lubridate)
  issue.date <- as.Date(c(issue.date), "%m-%d-%Y")
  start.date <- as.Date(c(start.date), "%m-%d-%Y")
  end.date <- as.Date(c(end.date), "%m-%d-%Y")
  price = price/100


  # 30/360 day count calculation 
    d1 = day(issue.date)
    m1 = month(issue.date)
    y1 = year(issue.date)
    d2 = day(end.date)
    m2 = month(end.date)
    y2 = year(end.date)


 diff = (max(0, 30 - d1) + min(30, d2) + 360*(y2-y1) + 30*(m2-m1-1))/360
 ncashflows = diff * frequency
 cf.period = seq(1:ncashflows)
 pmtdate = seq(start.date, end.date, by = "6 months")

time.period = (cf.period * 6)/12

 couponincome = rep(coupon/frequency * principal, ncashflows)
 principalincome = rep(0,ncashflows)
 principalincome[ncashflows] = principal
cashflow = couponincome + principalincome


  # Yield to maturity
     irr <- function(rate, time.period, cashflow, principal, price){
      pv = cashflow * 1/(1+rate)^time.period
      proceeds = principal * price
      sum(pv) - proceeds
  }

ytm = uniroot(irr, interval = c(lower = -.20, upper = .20), tol =.000000001, 
time.period = time.period, cashflow = cashflow, principal = principal, price = price)$root

 ytm.vec = c(rep(ytm,ncashflows))
 pv.factor = 1/(1+ytm.vec)^time.period
 pv.cashflow = cashflow*pv.factor
 pv.price = pv.cashflow /(principal * (price/100))
 pv.period = pv.price * time.period
 cvx.time = time.period*(time.period + 1)
 cf.cvx = (cashflow/(1+ytm)^(time.period + 2))/(principal * (price/100))
 cf.cvx.period = cf.cvx * cvx.time

cashflow.table <- data.frame(Period = cf.period, Time = time.period, 
Cashflow = cashflow,  PVFactor = pv.factor,PV = pv.cashflow, PV.Price = pv.price, 
pv.period = pv.period, cvx.time = cvx.time, cf.cvx = cf.cvx, 
cf.cvx.period = cf.cvx.period)


cashflow.table
(sum(pv.period) / (price * 100))/( 1+ (ytm/frequency))
.5 * ((sum(cf.cvx.period)/(price * 100)))
print(xtable(cashflow.table, digits = 4))
}  

Bond.Cash.Flow <-function(issue.date, start.date, end.date, coupon, principal, 
frequency,  price){

library(lubridate)
  issue.date <- as.Date(c(issue.date), "%m-%d-%Y")
  start.date <- as.Date(c(start.date), "%m-%d-%Y")
  end.date <- as.Date(c(end.date), "%m-%d-%Y")
  price = price/100

# 30/360 天计数计算 d1 = day(issue.date) m1 = month(issue.date) y1 = year(issue.date) d2 = day(end.date) m2 = month(end.date) y2 = year (结束日期)

 diff = (max(0, 30 - d1) + min(30, d2) + 360*(y2-y1) + 30*(m2-m1-1))/360
 ncashflows = diff * frequency
 cf.period = seq(1:ncashflows)
 pmtdate = seq(start.date, end.date, by = "6 months")

time.period = (cf.period * 6)/12

 couponincome = rep(coupon/frequency * principal, ncashflows)
 principalincome = rep(0,ncashflows)
 principalincome[ncashflows] = principal
cashflow = couponincome + principalincome

# 到期收益率 irr <- function(rate, time.period, cashflow, principal, price){ pv = cashflow * 1/(1+rate)^time.period 收益 = 本金 * 价格总和 (pv) - 收益 }

ytm = uniroot(irr, interval = c(lower = -.20, upper = .20), tol =.000000001, 
time.period = time.period, cashflow = cashflow, principal = principal, price = price)$root

 ytm.vec = c(rep(ytm,ncashflows))
 pv.factor = 1/(1+ytm.vec)^time.period
 pv.cashflow = cashflow*pv.factor
 pv.price = pv.cashflow /(principal * (price/100))
 pv.period = pv.price * time.period
 cvx.time = time.period*(time.period + 1)
 cf.cvx = (cashflow/(1+ytm)^(time.period + 2))/(principal * (price/100))
 cf.cvx.period = cf.cvx * cvx.time

cashflow.table <- data.frame(Period = cf.period, Time = time.period, 
Cashflow = cashflow,  PVFactor = pv.factor,PV = pv.cashflow, PV.Price = pv.price, 
pv.period = pv.period, cvx.time = cvx.time, cf.cvx = cf.cvx, 
cf.cvx.period = cf.cvx.period)


cashflow.table
(sum(pv.period) / (price * 100))/( 1+ (ytm/frequency))
.5 * ((sum(cf.cvx.period)/(price * 100)))
print(xtable(cashflow.table, digits = 4))

}

4

1 回答 1

3

目前尚不清楚您要做什么,因为您没有给出函数调用的精确上下文。所以我的回答将是片面的。

  1. 请为您的参数分配默认值,尤其是您有多个参数要验证的参数。默认参数在 R 中使用惰性求值,并且确实是该语言的一个强大功能。
  2. 使用stop和/或warning抛出错误/警告并在其最终调用上下文中捕获它,以向用户提供人工消息。
  3. 看一下match.call(对于初学者来说很难)以有效地调用您的函数。

这是一个使用示例stop

PresentValue <- function(interest.rate, number.periods=1, frequency=1) {
if (missing(interest.rate))
  stop("Need to specify interest.rate as number between 0 and 1 for calculations.")
if (!is.numeric(interest.rate)  )
  stop("No numeric  interest.rate specified.")
if (interest.rate <0 | interest.rate > 1)
  stop("No valid  interest.rate specified.")
 ## you do the same thing for other arguments

}

一些测试:

PresentValue()
Error in PresentValue() : 
  Need to specify interest.rate as number between 0 and 1 for calculations.
> PresentValue("a")
Error in PresentValue("a") : No numeric  interest.rate specified.
> PresentValue(5)
Error in PresentValue(5) : No valid  interest.rate specified.
> PresentValue(0.9)  ## normal use
于 2013-07-07T01:20:47.793 回答