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けど意味不明。さらに、現時点では必要なものではないと思います。

基本的に、私は次のことをする必要があります

最初に、ユーザーが利率を整数で入力したことを確認します (つまり、0.05 ではなく 5%)。次に、利率がどのように支払われるか (頻度)、毎月、毎年などをユーザーに「尋ねる」必要があります。次に、利率を周波数。

奇妙なのは、最初の条件は、他の if ステートメントが除外された場合にのみチェックされることです。

この関数は、より大きな関数セットのオブジェクトになるため、最終的には try catch で機能する警告としてこれらを考慮する必要があると思います。最後に、利率のエラーで関数が終了せず、ユーザーに利率を正しく入力するように求めるだけであればよいでしょう。

事前に単純さをお詫び申し上げますが、探していたものが見つかりませんでした。

EDITいくつかの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, cacheflow, principal, price){ pv = cacheflow * 1/(1+rate)^time.period 収益 = 元本 * price sum(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. stopand/orを使用し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 に答える