Effective Interest Rate
Annualize Rates¶
Not all rates are paid on an annual basis. For example, many times there are semi-annual payments. If there is an 8% rate paid annually then 10% is paid at the end of the year but if it is semi-annual 5% is paid halfway through the year then the next 5% is paid at the end of the year. Let’s see how it might look if we compounded based on the half years.
years = [x/2 for x in range(61)]
#Annual is paid only every other half year
annual_r = [0, .1] * 30
#Semi-annual would be paid every period but with half the rate is
semiannual_r = [0.05, 0.05] * 30
#Convert the rates to numpy arrays
annual_r = np.array(annual_r)
semiannual_r = np.array(semiannual_r)
#Add 1 to the rates and find the cummulative product
cummulative_product1 = np.cumprod(annual_r + 1)
cummulative_product2 = np.cumprod(semiannual_r + 1)
#Insert the value of 1 in both of the arrays
cummulative_product1 = np.insert(cummulative_product1, 0, 1)
cummulative_product2 = np.insert(cummulative_product2, 0, 1)
#Find the account values
A_list1 = cummulative_product1 * 100
A_list2 = cummulative_product2 * 100
plt.plot(years, A_list1)
plt.plot(years, A_list2)
plt.xlabel("Year")
plt.ylabel("Account Value")
plt.title("Account Value with Withdrawals")
plt.legend(["Annual", "Semi-Annual"])
plt.show()
Obviously there is a benefit to more frequent compounding. The formula to find the equivalent or annualized formula is:
$ r_{effective} = (1 + \frac{r_{nominal}}{n}) ^ n -1 $
where
$ r_{nominal} = \text{Nominal rate of return} $
$ r_{effective} = \text{Effective rate of return} $
$ n = \text{Frequency of compounding} $
There is also the possibility of continuously compounded return (one in which every second there is compounding applied). This type of compounding given the same nominal rate will yield the highest effective rate. The formula for this case is:
$ r_{effective} = e^{r_{nominal}t}-1 $
where
$ r_{nominal} = \text{The nominal rate of return} $
$ r_{effective} = \text{The effective rate of return} $
#Let's compare returns that are compounded annually, semi-annually, quarterly, monthly, and continuously.
annual = .08
semiannual = (1 + .08/2) ** 2 - 1
quarterly = (1 + .08/4) ** 4 - 1
monthly = (1 + .08/12) ** 12 - 1
continuous = np.exp(.08 * 1) - 1
print("Annual: {}".format(annual))
print("Semi-annual: {}".format(semiannual))
print("Quarterly: {}".format(quarterly))
print("Monthly: {}".format(monthly))
print("Continuous: {}".format(continuous))
#And what about the effect over 30 years
years = list(range(31))
rates = [np.array([r]*30) + 1 for r in [annual, semiannual, quarterly, monthly, continuous]]
A_list = [np.cumprod(r) * 100 for r in rates]
A_list = [np.insert(A, 0, 100) for A in A_list]
for A in A_list:
plt.plot(years, A)
plt.xlabel("Year")
plt.ylabel("Account Value")
plt.title("Account Value vs. Compounding for r=8%")
plt.legend(["Annual", "Semi-annual", "Quarterly", "Monthly", "Continuous"])
plt.show()
#Look at the difference at the end of the 30 years between the value of a continuously compounded rate and annual one
print(A_list[-1][-1] - A_list[0][-1])
Solving Other Parts of the Equation¶
Besides finding the future value, we could find other variables. What about finding the number of years it would take for a principal amount to become a certain value. If the equation is:
$ A = P * (1+r)^t $
where
$ A = \text{The account value}$
$ r = \text{The effective annual rate}$
$ t = \text{The number of years}$
It can be re-arranged to find t by taking the log of both sides first, then dividing over.
$ log(\frac{A}{P}) = log((1+r)^t) $
$ log(\frac{A}{P}) = t * log(1+r) $
$ \frac{log(\frac{A}{P})}{log(1+r)} = t $
#With a 5% rate, a future account value of $200, and a starting value of 100, how many years would it take
A = 200
P = 100
r = .05
#Find the number of years
t = np.log(A/P) / np.log(1+r)
print(t)
print()
#Check it is correct
print(P * (1+r) ** t)
What if we want to know the rate that would be needed. We can re-arrange to get:
$ \frac{A}{P} =(1+r)^t $
$ (\frac{A}{P})^{\frac{1}{t}} =1+r $
$ (\frac{A}{P})^{\frac{1}{t}} - 1 =r $
#What if the account value is 200 after starting at 100 just 10 years older
A = 200
P = 100
t = 10
r = (A / P) ** (1/t) - 1
print(r)
print()
#Check if it is correct
print(P * (1+r) ** t)
Finally what about the starting value which would get us to a final account value given a number of years, a rate and that ending value.
$ \frac{A}{(1+r)^t} = P $
#What about $200 in the future, with 10 years of compounding at a 5% rate
A = 200
t = 10
r = .05
P = A / (1+r) ** t
print(P)
print()
#Check if it is correct
print(P * (1+r) ** t)