Abstract
This is a solution for Workshop 2. Not all the workshop activities will be displayed; only the sections were students needed to work on an exercise/challenge or respond questions.In the following section I describe one or two approaches to solve the challenges of this workshop. Remember that these solutions are not the unique or the best solutions. You can use these solutions as guidelines to keep improving your programming skills.
Remember that the only way to learn programming is PRACTICE, PRACTICE AND PRACTICE… AND LEARN FROM YOUR MISTAKES …
You have to write a program to calculate the number of months needed to finish paying a mortgage loan. The information about the loan is the following:
Loan amount = $3,000,000.00 pesos
APR (Annual % rate) = 11% (compounded monthly)
Monthly Fixed Payment = $40,000.00 (includes interests and capital)
Your program has to provide 2 results: the number of months needed to finish paying the loan, and the amount of the last payment if the payment is less than the fixed payment amount. Your program has to be able to run with any change in any of the values of the above variables.
This is a quite challenging exercise!
Hint: if you are familiar with Excel, start solving the problem in Excel, and then try to write your program in R.
My general approach was the following. The inputs of the problem are
The outputs are:
My approach is to write a while loop that will end when the balance ($ owned) is zero or less than zero. Each iteration will simulate each month of the loan period where interest, principal and balance for the the month will be calculated.
Before I do the iterations for the loop, I initialize:
For each iteration of this loop I will do the following:
Here is my code and its documentation:
# To avoid scientific notation for numbers:
options(scipen=999)
<- 3000000
LOAN <-LOAN
BALANCE<- 0.11
APR<-40000
PAYMENT<-0
Nwhile (BALANCE>0) {
# I use N to count the number of months
<-N+1
N# I calculate interest compounded monthly
<-BALANCE*(APR/12)
INTERESTS# I calculate the principal of the payment by subtracting interests
# from the payment:
<-PAYMENT - INTERESTS
PRINCIPAL# I update the balance after subtracting the principal of the period:
<-BALANCE-PRINCIPAL
BALANCE# I check whether BALANCE is zero or negative
if (BALANCE<=0) {
# The BALANCE will be negative or zero in the last iteration of the loop,
# then if I sum PAYMENT + BALANCE I am getting a difference that
# actually represents the amount of the last payment that might
# be less than the fixed PAYMENT amount
= PAYMENT + BALANCE
LASTPAYMENT cat("The last payment will be less than the rest, and will be ",LASTPAYMENT, "in the period ",N)
} }
## The last payment will be less than the rest, and will be 18840.27 in the period 128
cat("The number of periods(months) to finish paying the loan is ",N)
## The number of periods(months) to finish paying the loan is 128
Another approach to solve this problem is to look at the Annuity formula and try to see if there is an analytic way to calculate the N, the number of periods. You can see my Note Basics of Return and Risk to review basic formulas of Time value of Money.
This mortgage problem can be solved using the formula for the Annuity. An annuity is a fixed cash flow that is payed each period (monthly or annual) and the interest rate is the same for all periods
The formula to get the present value (PV) of fixed payments C in N periods with a period rate R is the following:
\[PV=\frac{C}{R}*\left[1-\frac{1}{(1+R)^{N}}\right]\]
I will do basic algebra to get N, the number of periods:
I multiply both sides times \(\frac{R}{C}\):
\[PV*\frac{R}{C}=1-\frac{1}{(1+R)^{N}}\] I try to leave \((1+R)^N\) in the left side of the equation:
\[\frac{1}{(1+R)^{N}}=1-PV*\frac{R}{C}\]
\[(1+R)^{N}=\frac{1}{\left[1-\frac{PV(R)}{C}\right]}\] Now I can apply natural logs to both sides of the equation, so that I can leave N alone:
\[ln(1+R)^{N}=ln\left(\frac{1}{\left[1-\frac{PV(R)}{C}\right]}\right)\] Following basic rules of logarithms:
\[N*ln(1+R)=ln(1)-ln\left(1-\frac{PV(R)}{C}\right)\] Note that \(ln(1)=0\). Then, finally I got N as: \[N=\frac{-ln\left(1-\frac{PV(R)}{C}\right)}{ln(1+R)}\] Now I can easily implement this formula in R as follows:
# N = (-ln(1 - (PV*r/C))) / ln(1+r)
<-3000000
BALANCE<-40000
PAYMENT<- 0.11
APR# I will use N2 instead of N to check whether N2 will be equal to the
# N I had calculated previously
# For the period rate R I will use (APR/12) since each period is 1 month:
<- (-log(1 -(BALANCE*(APR/12)/PAYMENT))) / log(1+(APR/12))
N2cat("The number of months (in decimal) I need to finish paying my mortgage is ")
## The number of months (in decimal) I need to finish paying my mortgage is
N2
## [1] 127.4699
# In this case the response is in decimals, so the decimals represent
# a percentage to calculate the last payment.
# I can get the integer part of N2 with the trunc function:
<-trunc(N2)
Nmonths# If N2 is an integer (with NO decimals), then I do not need to add an extra month
# I Nmonths is less than N2 that means that N2 has decimals:
if (Nmonths<N2) {
= (N2-Nmonths) * PAYMENT
lastpayment =Nmonths+1
Nmonths
} cat("In other words, I need ",Nmonths, " months to pay the mortgage \n")
## In other words, I need 128 months to pay the mortgage
cat("The last payment must be = ",lastpayment)
## The last payment must be = 18794.81
I got the same result as in the first approach!
In this approach I will encapsulate the program into afunction so that I can re-use my code with different values of the same type of problem. This approach is very convenient when we need to do the same calculation for several examples. I will use the loop code for this approach. (I can also do a function using the formula approach).
Once the function is defined, I just need to CALL the function to do the calculation for specific parameters.
<- function(loan,apr,payment){
periodcalculation # I receive the loan amount, the annual % rate, and the monthly
# payment as parameters. This will be the INPUT of the algorithm/
# function.
# I initialize a variable that will be the ending balance equal to
# the initial loan amount
=loan
endingbalance# I use a counter for the month
=0
month_counter#Now I do the loop with a while. I will do iterations and I will
# stop when the ending balance is zero or negative. So, I can indicate
# that the loop has to continue while endingbalance is greater than
# zero:
while (endingbalance>0) {
# All instructions /statements within the loop will be run
# in each iteration.
# I add 1 to the month counter. The first iteration, month_counter
# will go from zero to one.
=month_counter+1
month_counter# Now I calculate the interest of the period using the corresponding
# ending balance and the interest rate of the month, which is
# equal to apr/12
=endingbalance*(apr/12)
interest
# Now I calculate how much of the payment is principal (capital)
=payment-interest
principal# Then the principal + interest will be always equal to the fixed
# monthly payment
=endingbalance - principal
endingbalance# I can display the payments to know what the function is doing.
# In this case, I will put this as comments:
# cat("Month #: ",month_counter, " ")
# cat("Principal payed=",principal, " ")
# cat("Interest payed=",interest, "\n")
}# At the end of the loop, endingbalance will be either zero or negative
# If endingbalance is zero, then the last payment will be equal to all payments
# If endingbalance is negative, then only the last payment will be less
# than the rest payments
=payment + endingbalance
lastpayment # I create a vector with the number of months of the mortgage
# and also the last payment amount
<- c(month_counter,lastpayment)
vectorresult# I return this vector as result
return(vectorresult)
}
## Now I run my function with the exampe of Challenge 1:
<-periodcalculation(3000000,0.11,40000)
result# I got a vector with 2 values, the # of months needed to pay the
# mortgage and the last payment amount:
cat("The total months to pay the mortgage is ", result[1], "\n")
## The total months to pay the mortgage is 128
cat("The last payment amount is ", result[2], "\n")
## The last payment amount is 18840.27
# I can try another example for a loan of $1 million, APR=15% and
# payments of $14,000
<-periodcalculation(1000000,0.15,14000)
result2 result2
## [1] 180.00 11239.86
cat("The total months needed to pay the loan is ", result2[1], "\n")
## The total months needed to pay the loan is 180
cat("The last payment is : ", result2[2] )
## The last payment is : 11239.86
Write a program that calculates the price of the following bond issued by the company ABC. ABC needs to finance an important project to develop a new technological device. To get the money, ABC issued a bond with the following characteristics:
Calculate the price of this bond if the stated annual interest rate is:
You have to get the price for the bond for each of these 3 interest rates.
Since I have to calculate the price bond for 3 different interest rates, it is a good idea to write a function that receives the principal, time to maturity, coupon rate and interest rate.
In this approach I will use a vector with the cash flows, calculate the present values of each cash flow, and then I add them all to get the bond price. I will solve this problem using vectorization instead of a loop.
<-function(principal,ttm,couponrate,interestrate,periods) {
bondprice# periods is the # of periods in the year for the compounding of interests
# I calculate the coupon amount per period:
=(couponrate/periods)*principal
coupon# I create a vector for the cashflows. The last cashflow must be equal to
# the coupon plus the principal
<-c(rep(coupon,ttm*periods-1),coupon+principal)
cf# I used the rep function that repeats ttm*periods-1 times the coupon amount
# Then the vector cf will have all fixed coupon payments, and the end payment
# will be equal to the coupon plus the principal
# I create a vector for the exponents that I need to use for the discount factor:
# I use the seq function that creates sequential numbers from 1 to the last period
<-seq(1,ttm*periods)
exponents# I create a vector with the discount factors (1/(1+periodrate)^t)
<- 1 / (1+interestrate/periods)^exponents
discountfactors
# I get the sum of all present values. The present values are equal to
# the cash flow times the corresponding discount factor:
<- sum(cf*discountfactors)
presentvalue # Since the output of this function is this value, then
# I return this present value as the bond price:
return(presentvalue)
}
# Once I have my function, I just call my function with the parameters specified
# in the problem.
# I run my function 3 times for the 3 interest rates:
<- bondprice(3000000,20,0.11,0.08,2)
bond1 print("The bond price when interest rate is 7% is ")
## [1] "The bond price when interest rate is 7% is "
sprintf("$ %3.2f", bond1)
## [1] "$ 3890674.82"
# The sprintf function prints numbers on the screen with a specific format
# I run the bondprice function with the last parameter=2 since the problem specifies
# that the compounded is semi-annually, then periods in the year=2
<- bondprice(3000000,20,0.11,0.11,2)
bond2print("The bond price when interest rate is 11% is ")
## [1] "The bond price when interest rate is 11% is "
sprintf("$ %3.2f", bond2)
## [1] "$ 3000000.00"
<- bondprice(3000000,20,0.11,0.13,2)
bond3print("The bond price when interest rate is 14% is ")
## [1] "The bond price when interest rate is 14% is "
sprintf("$ %3.2f", bond3 )
## [1] "$ 2575634.19"
In this approach I use the annuity formula and the present value formula to calculate the bond price. I also use a function since I will be calculating bond price three times for 3 interest rates.
<-function(principal,ttm,couponrate,interestrate,periods) {
bondprice2# periods is the # of periods in the year for the compounding of interests
# I calculate the coupon amount per period:
=(couponrate/periods)*principal
coupon# I first calculate the present value of the coupons using the annuity formula:
<- coupon/(interestrate/periods) * (1 - 1/(1+interestrate/periods)^(ttm*periods))
PVcoupons # Now I calculate the present value of the principal
<- principal/(1+interestrate/periods)^(ttm*periods)
PVprincipal # Now I sum both present values to get the price of the bond:
return(PVcoupons + PVprincipal)
}
# Once I have my function, I just call my function with the parameters specified
# in the problem.
# I run my function 3 times for the 3 interest rates:
<-bondprice2(3000000,20,0.11,0.08,2)
bond1print("The bond price when interest rate is 7% is ")
## [1] "The bond price when interest rate is 7% is "
sprintf("$ %3.2f", bond1)
## [1] "$ 3890674.82"
<-bondprice2(3000000,20,0.11,0.11,2)
bond2# The sprintf function prints numbers on the screen with a specific format
print("The bond price when interest rate is 11% is ")
## [1] "The bond price when interest rate is 11% is "
sprintf("$ %3.2f", bond2)
## [1] "$ 3000000.00"
<-bondprice2(3000000,20,0.11,0.13,2)
bond3print("The bond price when interest rate is 14% is ")
## [1] "The bond price when interest rate is 14% is "
sprintf("$ %3.2f", bond3)
## [1] "$ 2575634.19"
I got the same results in both approaches!