利率

計算有效年利率和年利率及費用(R)

  • February 13, 2022

問題

如何計算有效年利率 (EAR)年利率 (APR)以及費用(以 R 為單位)?

我有興趣了解在考慮費用時我實際支付了多少利息,我認為 EAR 是要走的路,但如果我錯了,請糾正我。

我嘗試按照投資百科描述在下面實施 APR,但 APR 低於名義利息,所以它肯定不正確(應該在 3.5% 左右)

我試過的

下面是一個 MVE,它也更詳細地解釋了這個問題:

rm(list=ls())
library(reprex)

# define costs, fees and interests
price <- 24800
monthly_payment <- 280
deposit <- 4000
loan_term <- 5*12 #in months
initial_fee <- 300
monthly_fee <- 12
nominal_interest <- 2/100
monthly_interest <- nominal_interest/12

# initiate fixed costs, interest fees and total costs for the loop
handling_charges <- initial_fee
interest_fees <- 0
total_costs <- handling_charges

# substracting initial payment from the what is left variable
left <- price - deposit

#calculating how much of dept is left after loan period and how much interest has accumulated
for (i in 1:loan_term) {
 left_last_month   <- left
 left              <- left*(1+monthly_interest)
 interest_fees_mo  <- (left-left_last_month)
 interest_fees     <- interest_fees + interest_fees_mo 
 handling_charges  <- handling_charges + monthly_fee
 total_costs       <- total_costs+ interest_fees_mo + monthly_fee
 left              <- left+monthly_fee-monthly_payment
}

#https://www.investopedia.com/terms/a/apr.asp
#https://www.investopedia.com/terms/e/effectiveinterest.asp

apr_100 <- 
 ((
   (total_costs/price)
   /(loan_term*30.4375) # number of days in the loan term
   )
  *365.25)             # number of days in a year

apr <- apr_100*100

# ear ???


share_of_loan_100 <- (total_costs/price)*100
share_of_loan_100
#> [1] 9.632864

left # after loan period ends
#> [1] 6088.95
interest_fees
#> [1] 1368.95
handling_charges
#> [1] 1020
total_costs
#> [1] 2388.95
apr   # wrong
#> [1] 1.926573
# ear # ????

reprex 包於 2022-01-20 創建(v2.0.1)

來自投資百科的定義:

年利率

年利率

EAR,不考慮費用

EAR,不考慮費用

編輯2:

根據base64的建議,我認為它現在可以工作,儘管程式碼很醜。你認為它現在給出正確的 apr 和 apy 嗎?

我添加了一個選項來預定義每月付款或根據最終付款計算它(通過將每月付款設置為 FALSE,它將是近似值)。還有一個選項可以選擇利息複合的時間(例如,每月 1:12,一年中的第一個月為 1,一年中的第 6 個月和第 12 個月為 c(6,12),自貸款期限)。

執行程式碼後,您只需在interest.F-function 中插入值即可。請參閱末尾的兩個範例 ( stack_example_monthly& stack_example_annual)

rm(list=ls())
library(reprex)
library(gtools)

# We need 3 helper functions
# 1. a precise enough binary search function
# 2. Payments function to calculate payments during the loan period
# 3. Apr to calculate the real interest rate

##########################################################
# 1. Binary search - helper function
##########################################################
# gtools binsearch-function modified for more accurate search results
# source: Gregory R. Warnes, Ben Bolker and Thomas Lumley (2021). gtools: Various R Programming Tools. R package version 3.9.2. https://CRAN.R-project.org/package=gtools

binsearch_decimal <- function(fun, range, ..., target = 0, lower = ceiling(min(range)),
                            upper = floor(max(range)), maxiter = 1000, showiter =FALSE) 
{
lo <- lower
hi <- upper
counter <- 0
val.lo <- fun(lo, ...)
val.hi <- fun(hi, ...)
if (val.lo > val.hi) {
  sign <- -1
}
else {
  sign <- 1
}
if (target * sign < val.lo * sign) {
  outside.range <- TRUE
}
else if (target * sign > val.hi * sign) {
  outside.range <- TRUE
}
else {
  outside.range <- FALSE
}
while (counter < maxiter && !outside.range) {
  counter <- counter + 1
  if (hi - lo <= 0.00001 || lo < lower || hi > upper) # 1 -> 0.00001
    break
  center <- round((hi - lo)/2 + lo, 6) # 0 -> 6
  val <- fun(center, ...)
  if (showiter) {
    cat("--------------\n")
    cat("Iteration #", counter, "\n")
    cat("lo=", lo, "\n")
    cat("hi=", hi, "\n")
    cat("center=", center, "\n")
    cat("fun(lo)=", val.lo, "\n")
    cat("fun(hi)=", val.hi, "\n")
    cat("fun(center)=", val, "\n")
  }
  if (val == target) {
    val.lo <- val.hi <- val
    lo <- hi <- center
    break
  }
  else if (sign * val < sign * target) {
    lo <- center
    val.lo <- val
  }
  else {
    hi <- center
    val.hi <- val
  }
  if (showiter) {
    cat("new lo=", lo, "\n")
    cat("new hi=", hi, "\n")
    cat("--------------\n")
  }
}
retval <- list()
retval$call <- match.call()
retval$numiter <- counter
if (outside.range) {
  if (target * sign < val.lo * sign) {
    warning("Reached lower boundary")
    retval$flag <- "Lower Boundary"
    retval$where <- lo
    retval$value <- val.lo
  }
  else {
    warning("Reached upper boundary")
    retval$flag <- "Upper Boundary"
    retval$where <- hi
    retval$value <- val.hi
  }
}
else if (counter >= maxiter) {
  warning("Maximum number of iterations reached")
  retval$flag <- "Maximum number of iterations reached"
  retval$where <- c(lo, hi)
  retval$value <- c(val.lo, val.hi)
}
else if (val.lo == target) {
  retval$flag <- "Found"
  retval$where <- lo
  retval$value <- val.lo
}
else if (val.hi == target) {
  retval$flag <- "Found"
  retval$where <- hi
  retval$value <- val.hi
}
else {
  retval$flag <- "Between Elements"
  retval$where <- c(lo, hi)
  retval$value <- c(val.lo, val.hi)
}
return(retval)
}


##############################################3
# 2.payments - helper function 
##############################################
#calculating how much of dept is left after loan period and how much interest has accumulated
# includes an option to calculate monthly payment with binary search
payments.F <- function(monthly_payment, #
                     binary_search, 
                     monthly_fee, #
                     nominal_interest,
                     price, #
                     deposit, #
                     initial_fee,
                     loan_term,
                     compounding) {#

# substracting initial payment and initial fees to get principal    
principal <- price - deposit                     
left <- principal                                      


# initiate parameters for the loop
handling_charges <- initial_fee
interest_fees <- 0
total_costs <- handling_charges
monthly_interest <- nominal_interest/12
month <- 1
no_of_compoundings <- length(compounding)
compounding_period_interest <- nominal_interest/length(compounding)

#defining a "not in" operator
`%!in%` <- Negate(`%in%`)

if ( (sum(compounding %in% 1:12) >0) & (sum(compounding %!in% 1:12) ==0) ) {
  #print('--a valid compounding period set--')
} else {
  stop("Error: Invalid compoumding value. Set it to a vector of months when you want it to compound, e.g. 1:12, c(6,12),5")
}

for (i in 1:loan_term) {
  left_last_month   <- left
  
  if (month %in% compounding) {
    left <-left*(1+compounding_period_interest) 
  }
  interest_fees_mo  <- (left-left_last_month)
  interest_fees     <- interest_fees + interest_fees_mo
  handling_charges  <- handling_charges + monthly_fee
  total_costs       <- total_costs+ interest_fees_mo + monthly_fee
  left              <- left+monthly_fee-monthly_payment
  
  # incrementing or resetting monthly counter
  month <- month+1
  if (i %% 12 == 0) {
    month <- 1
  }
  
}
if (binary_search==T) {
  return(left)
} else {
  return(list("principal"=principal,
              "left"=left,
              "total_costs"=total_costs,
              "interest_fees"=interest_fees,
              "handling_charges"=handling_charges
  ))
}
}


############################################################################
# 3. APR - helper function
############################################################################
#apr will be later solved with binary search

apr.F <- function(APR,PMT,N,FV,PV) {
(PMT*((1-(1/(1+(APR/12))^N))/(APR/12)))+(FV/(1+(APR/12))^N)-(PV)
}


###########################################################################
# main function where we plug in the values

interest.F <- function(price,
                     loan_term=5*12,
                     initial_fee=0,
                     nominal_interest=2/100,
                     monthly_fee=12,
                     deposit=4000,
                     monthly_payment=F, # Set to false if you want to calculate monthly payment
                     final_payment=0, # If monthly payment is set, it will overrun this
                     compounding=1:12
) {



# running binary search to monthly cost if we have not defined it
if (monthly_payment==F) {
  print('--Calculating monthly payment by binary search--')
  (binsearch_monthly_payment <- binsearch_decimal(function(x) 
                                                  payments.F(x, #
                                                  binary_search=T, 
                                                  monthly_fee=monthly_fee, #
                                                  nominal_interest=nominal_interest,
                                                  price=price, #
                                                  deposit=deposit, #
                                                  initial_fee=initial_fee,
                                                  loan_term=loan_term,
                                                  compounding=compounding), 
                                range = c(0,2000),
                                target=final_payment,
                                showiter = F))
  
  
  monthly_payment <- mean(binsearch_monthly_payment$where)
  
} else {
  print('--Using pre-fixed monthly payment amount--')
}

# assigning a payment scheme based on monthly payment (binary search or predefined)
(payments <- payments.F(monthly_payment,
                        binary_search = F,
                        monthly_fee=monthly_fee, #
                        nominal_interest=nominal_interest,
                        price=price, #
                        deposit=deposit, #
                        initial_fee=initial_fee,
                        loan_term=loan_term,
                        compounding=compounding))


paid_excluding_fees <- payments$principal-payments$left

# running a binary search to find apr given that we know how much we have repayed the loan (excluding fees)
(binsearch_apr <- binsearch_decimal(function(x) 
                                    apr.F(x,
                                    PMT=monthly_payment,
                                    N=loan_term,
                                    FV=payments$left,
                                    PV=payments$principal-initial_fee)
                  , range = c(-1,100),target=0))

#taking the mean value of the binary search to approximate apr
apr <- mean(binsearch_apr$where)

apr <- apr

#calculating apy based on apr
#https://www.investopedia.com/terms/a/apy.asp
apy <- (1+apr/12)^12-1



share_of_price <- (payments$total_costs/(price-initial_fee))*100
#payments$paid_excluding_fees <- paid_excluding_fees
payments$all_payments <- payments$total_costs + paid_excluding_fees +deposit
payments$monthly_payments <- monthly_payment
payments$share_of_price <- share_of_price
payments$apr <- apr*100
payments$apy <- apy*100

return(payments)
}


(stack_example_monthly <- interest.F(
price=24800,
loan_term=5*12,
initial_fee=300,
nominal_interest=2/100,
monthly_fee=12,
deposit=4000,
monthly_payment=F, # 280 # Set to false to estimate monthly payment
final_payment=6088.95, #  6088.95 If monthly payment is set, it will overrun this
compounding=1:12 # a vector, eg. 1:12, c(6,12), 5.
))
#> [1] "--Calculating monthly payment by binary search--"
#> $principal
#> [1] 20800
#> 
#> $left
#> [1] 6088.95
#> 
#> $total_costs
#> [1] 2388.95
#> 
#> $interest_fees
#> [1] 1368.95
#> 
#> $handling_charges
#> [1] 1020
#> 
#> $all_payments
#> [1] 21100
#> 
#> $monthly_payments
#> [1] 280
#> 
#> $share_of_price
#> [1] 9.750817
#> 
#> $apr
#> [1] 3.5069
#> 
#> $apy
#> [1] 3.56382

(stack_example_annual <- interest.F(
  price=24800,
  loan_term=5*12,
  initial_fee=300,
  nominal_interest=2/100,
  monthly_fee=12,
  deposit=4000,
  monthly_payment=280, # 280 # Set to false to estimate monthly payment
  final_payment=NA, #  6088.95 If monthly payment is set, it will overrun this
  compounding=12 # a vector, eg. 1:12, c(6,12), 5.
))
#> [1] "--Using pre-fixed monthly payment amount--"
#> $principal
#> [1] 20800
#> 
#> $left
#> [1] 5921.857
#> 
#> $total_costs
#> [1] 2221.857
#> 
#> $interest_fees
#> [1] 1201.857
#> 
#> $handling_charges
#> [1] 1020
#> 
#> $all_payments
#> [1] 21100
#> 
#> $monthly_payments
#> [1] 280
#> 
#> $share_of_price
#> [1] 9.068805
#> 
#> $apr
#> [1] 3.2841
#> 
#> $apy
#> [1] 3.333986

reprex 包於 2022-02-13 創建(v2.0.1)

首先,您可以將 Investopedia APR 公式扔出窗外。該公式僅適用於 1 年以下的一次性付款,例如信用卡付款。

其次,對於目前的程式碼,我可以確認以下是正確的:

  • 每年 2% 的名義利率,每月復利,確實會導致24800-4000=20800 的貸款每月支付 268 美元(不包括費用)。268 美元 + 12 美元月費 = 280 美元,這是一致的。
  • 60 個月後,考慮到每月利息,但不包括初始費用並忽略每月費用,剩餘本金為6088.95 美元,用於計算下一個每月利息。

問題在於(1)您使用了錯誤的 APR 公式(實際上沒有公式)和(2)您忽略了 300 美元的初始費用。

  • (1):按月還款貸款(尤其是超過 12 個月)的 APR,根據世界各地不同的消費貸款法規,通過找到正確的 APR(稱為 I/Y)計算得出 Principal = Present Value of All付款,即攤銷表。這個答案解釋了為什麼它不能“手工解決”或公式。必須使用財務庫(很確定 R 有第三方包)、“蠻力”、“二進制搜尋”或Excel 的 RATE() 來完成
  • (2):300 美元的初始費用應該從 20800 美元的初始本金中扣除,因為雖然銀行在第 0 天給了您 20800 美元,但銀行也在第 0 天拿走了 300 美元,儘管是從另一個交易條目中提取的。因此,從銀行流出的實際金額為 20500 美元。但是,沒有必要更改“left <- price - deposit”,因為它會扭曲您的“left # after loan period ends”。由於 2% 的名義利率適用於 20800 的總貸款,300 美元的初始費用不作為本金資本化。

考慮 (1) 和 (2),使用財務計算器計算 60 個月的年利率為3.507%,假設 300 美元的初始費用僅在 60 個月內攤銷(即提前終止貸款,銀行同意未償還本金是 6088.95),而不是超過83.181個月(從 2% 名義和 268 美元的月付款逆向工程總月數)。如果您確實在 83.181 個月內攤銷 300 美元,則 APR 為3.723%超過 83.181 個月,由於更頻繁的 12 美元月費,該百分比更高。這裡進一步證明,假設 83.181 個月,根據美國法規的3.723% APR 是正確的。

有效 APR(包括初始費用和月費),也稱為 APY,僅在 60 個月內攤銷 300 美元時為 (1+0.03507/12)^12-1 = 3.564%,為 (1+0.03723/12)^如果在 83.181 個月內攤銷 300 美元,則12-1 = 3.787% 。

編輯

在我上面的回答中,我明確表示無需更改 “left <- price - deposit”

宇宙中有兩張桌子。

  • 根據銀行的說法,“未償本金”(即 FV)取決於 2% 的名義利率,不取決於 300 美元的初始費用,而無論“未償本金”如何,月費都固定為 12 美元。
  • 另一個根據法律規定,財務人員說所有利息和費用必須取決於“傑出本金”。隨著“未償本金”的減少,“利息和費用”也必須隨著時間的推移而減少。非本金的一切都稱為利息(不是費用、收費、成本等)。

如果您在3.507%連結中仔細注意到,該頁面顯示Total Interest: $2,388.95。這“巧合”等於您第一次嘗試的程式碼:

interest_fees
#&gt; [1] 1368.95
handling_charges
#&gt; [1] 1020
total_costs
#&gt; [1] 2388.95

攤銷表僅用於分配(即分配)每個固定每月付款的本金部分和利息部分(包括費用)。這只是每個財務人員都接受的統一分配方式。在此期間,攤銷從未改變總付款或總利息(包括費用)。

因此我再次強調,不要更改程式碼部分“#從剩餘變數中減去初始付款”,因為您需要根據銀行而不是法律來計算“60個月後的未償本金” 。

一旦你得到這個正確的“60 個月後的傑出校長”:

left # after loan period ends
#&gt; [1] 6088.95

您將嘗試從 0.0000000 到 1.0000000 的 r 的所有可能值(或通過二分搜尋有選擇地):

(280*((1-(1/(1+(r/12))^60))/(r/12)))+(6088.95/(1+(r/12))^60)-20500

目標是在這個公式中找到結果為 0 的 r。請注意,除非您指定 0 < r < 1 ,否則即使 Wolfram Alpha 也不知道如何解決它。但是如果你將 r = 0.03507 插入上面(0.035068 更準確),你就會明白這個公式是正確的

與答案的每個百分比相關的所有這些連結都假定您完全了解金錢的時間價值,包括何時在付款中包含費用(即 PMT),何時從初始本金中扣除預付費用(即 PV)。

一般方程為:

(PMT*((1-(1/(1+(r/12))^N))/(r/12)))+(FV/(1+(r/12))^N)-PV=0

在哪裡:

PMT = Fixed Monthly Payment
     (Including fixed and variable interest and fees, whatever "costs" you call doesn't matter, as long as entire monthly payment is FIXED)
r = APR
N = Months paid so far
FV = Outstanding Principal according to the Bank at the end of N ($0 if fully repaid)
PV = Initial Principal - Upfront Fees paid by the borrower

請注意使用幾何級數(即上述)或普通求和之間的區別。

(PMT*((1-(1/(1+(r/12))^N))/(r/12))) = Sum of PMT/(1+(r/12))^n where n = 1 to N

在得到 r (APR) 後,如果您想知道每個固定月供的本金和利息(包括費用)的分配部分**,**只需執行您的原始程式碼:

# define costs, fees and interests
**upfront_interest &lt;- 300**
price &lt;- 24800 **-upfront_interest**
monthly_payment &lt;- 280
deposit &lt;- 4000
loan_term &lt;- 5*12 #in months
initial_fee &lt;- **0**
monthly_fee &lt;- **0**
nominal_interest &lt;- **r**
monthly_interest &lt;- nominal_interest/12

share_of_loan_100 &lt;- (total_costs/(price**+upfront_interest-deposit**))*100

結果與“非本金的一切都稱為利息(不是費用、收費、成本等)”和“攤銷從未改變期間的總付款或總利息(包括費用)”相呼應。

share_of_loan_100
#&gt; [1] 11.48533
left # after loan period ends
#&gt; [1] 6088.948
interest_fees
#&gt; [1] 2388.948
handling_charges
#&gt; [1] 0
total_costs
#&gt; [1] 2388.948

300 美元的“upfront_interest”已經通過嵌入 APR 分散在 60 個月內。無需手動向總利息添加 300 美元。

編輯 2

實際上,對於歐盟來說,儘管付款是按月支付的,但看起來複合是按小數計算的,而不是按月計算的。所以你需要做的就是先到達6088.95,然後在二分查找中修改為:

D=280
target=0
apr_100: ... + (6088.95*(1+APR/(100*100))^-(MONTHS/12)) - 20500

但是,通過了解此歐盟 APR,您無法真正直接製作有意義的攤銷表並分配每月利息。即使是歐洲人也必須將其轉換回超過 1 個月的利率才能創建每月攤銷表。

“當支付週期和復利週期相互不同時,建議計算每個支付週期的實際利率。原因是,要進行等價分析,複利週期和支付週期必須相同。”

<https://wps.prenhall.com/ecs_park_fee_2/87/22279/5703599.cw/content/index.html>

無論如何,歐盟 APR =美國 APY,每年 12 個付款期和每年 1 個複利

將 US APY 轉換為 US APR,您將擁有與我最初編輯相同的攤銷表。

$call
binsearch(fun = apr_100, range = c(0, 100 * 100), target = 0)
$numiter
[1] 14
$flag
[1] "Between Elements"
$where
[1] 3.56 3.57
$value
[1]  2.282236 -3.853403
[1] 3.565

2 位小數的利率是不夠的。

很確定這是在查看這些計算後的答案。在您 apr_100 的計算中,“價格”不正確。它應該等於債務的初始本金,在您的範例中為“價格減去存款”。借入的金額為 20,800 美元,這是計算利息 + 費用的金額,而不是債務 + 股權(即“價格”)。

如果您對其進行調整,則 APR 等於 2.3%,並考慮了費用。如果然後將 2.3% 代入 EAR 公式,則應將 2.32% 從年度調整為每月。

引用自:https://money.stackexchange.com/questions/148690