This is an INDIVIDUAL workshop. In this workshop we learn about Algirithmic thinking and foundations of programming. We practice writing pseudo-code for simple finance-related problems
1 Introduction to Algorithmic thinking
What is an Algorithm? It is a set of logical, structured and sequential set of steps that takes input information, process it and creates a desired output.
How to design an algorithm?
Write the problem with your words and with clear and short sentences.
Identify what inputs are needed to solve the problem
Identify what is the output or the final expected result
What is the general approach to solve the problem? Here you specify general steps you will follow in a sequential order.
What is the specific steps for each general step specified above
Pseudo-code vs programming code
When we design
How can we use LLM’s (such as ChatGPT) to learn how think algorithmically ?
2 Introduction to programming code
What is a programming language? A programming language is a set of commands or instructions that are executed by the computer usually to automate repetitive tasks or functions that usually require intensive data processing. Programming languages are also used to develop computer applications. In Economics and Finance, we use programming languages mainly to do the following:
data input and/or data collection,
data cleaning,
data management including data transformation and data merging,
data storing,
data processing that includes descriptive analytics and predictive models, and finally
information delivery that includes reports or documents usually with summary tables and graphs.
You can effectively perform these programming processes in Python or R. Python is a free open source language. Nowadays, both Python and R are the two more popular programming languages for Data Science around the world.
2.1 Elements of a programming language
Any programming language has the following elements used to automate any pseudocode to solve any business or technical problem:
Variables and variable types
Conditionals using comparison operators
Loops to do repetitive tasks
Data structures - objects
Data frames
Objetcs
Functions
A function is a method that receives an input (1 or more parameters, which can be variables), do specific steps to process the input, and at the end, return an output which can be one number, one variable with numbers, a data frame, or a complete data structure such as an object.
3 What is an Objet-Programming Language?
Objects:
Classes: Specification of a data structure that contains both properties or variables, other objects, and methods
Object as an instance of a Class
Each object contains data as attributes or properties, and methods (functions) that operate into on the data. The methods are usually functions
4 CHALLENGE 1
You have to write pseudocode and corresponding Python code 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.
Once you wrote your Algorithm as a Text CHUHK, use it as a prompt (or series of prompts) for Gemini to generate Python code.
You have to run the Python code and check whether your results are correct.
Pay attention in class about the syntax and logic of Python computer language.
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 logical steps as pseudocode. # CHALLENGE 1 SOLUTION - Approach 1
My general approach was the following. The inputs of the problem are
Loan amount (LOAN)
Annual percentage rate (APR)
Fixed payment per month (PAYMENT)
The outputs are:
Number of months needed to fully pay the loan
Amount of the last payment
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:
BALANCE to be equal to the LOAN amount, and
A variable N to zero for the # of months.
For each iteration of this loop I will do the following:
Add 1 to N
Calculate the interests for the month using a monthly interest rate
Calculate the principal amount of the payment
Subtract the principal of the payment from the BALANCE
If BALANCE is zero or negative, then calculate the last payment amount and display N as the # of months needed to pay the loan
Here is my code and its documentation:
# Parámetros inicialesLOAN =3_000_000# Monto del préstamoBALANCE = LOANAPR =0.11# Tasa anual (12%)PAYMENT =40_000# Pago mensualN =0# Contador de meses# Bucle hasta que el saldo llegue a 0 o menoswhile BALANCE >0:# Incrementar contador de meses N +=1# Intereses mensuales INTERESTS = BALANCE * (APR /12)# Parte del pago que corresponde al principal PRINCIPAL = PAYMENT - INTERESTS# Actualizar saldo BALANCE -= PRINCIPAL# Verificar si el saldo llegó a cero o negativoif BALANCE <=0:# El último pago será menor que el pago regular LASTPAYMENT = PAYMENT + BALANCEprint(f"The last payment will be less than the rest, and will be {LASTPAYMENT:,.2f} in period {N}")# Resultado finalprint(f"The number of periods (months) to finish paying the loan is {N}")
The last payment will be less than the rest, and will be 18,840.27 in period 128
The number of periods (months) to finish paying the loan is 128
4.1 CHALLENGE 1 Solution - Approach 2
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:
Now I can easily implement this formula in Python as follows:
import math# Parámetros inicialesBALANCE =3_000_000PAYMENT =40_000APR =0.11# Fórmula: N = (-ln(1 - (PV * r / C))) / ln(1 + r)# Donde PV = saldo (principal), r = tasa por periodo, C = pago periódicor = APR /12# tasa mensualN2 = (-math.log(1- (BALANCE * r / PAYMENT))) / math.log(1+ r)print("The number of months (in decimal) I need to finish paying my mortgage is:")print(N2)# Obtener la parte entera del número de mesesNmonths = math.trunc(N2)# Si hay una parte decimal, implica un pago final parcialif Nmonths < N2: lastpayment = (N2 - Nmonths) * PAYMENT Nmonths +=1else: lastpayment =0print(f"In other words, I need {Nmonths} months to pay the mortgage.")print(f"The last payment must be = ${lastpayment:,.2f}")
The number of months (in decimal) I need to finish paying my mortgage is:
127.46987018733515
In other words, I need 128 months to pay the mortgage.
The last payment must be = $18,794.81
5 CHALLENGE 2
Write pseudo-code and corresponding Python code to calculate 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:
Principal: $3,000,000
Time to maturity: 20 years
Coupon rate: 11% (annual)
coupons are payed semi annually
Calculate the price of this bond if the stated annual interest rate is:
8%
11%
13%
As in the previous challenge, do the same to generate Python code.
5.1 CHALLENGE 2 Solution - Approach 1
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.
import numpy as npdef bondprice(principal, ttm, coupon_rate, interest_rate, periods):""" Calculates the price of a bond given its parameters. Parameters: principal (float): Face value of the bond ttm (int): Time to maturity (in years) coupon_rate (float): Annual coupon rate (e.g., 0.06 for 6%) interest_rate (float): Annual market interest rate (yield) periods (int): Number of compounding periods per year Returns: float: Present value (price) of the bond """# Coupon payment per period coupon = (coupon_rate / periods) * principal# Cash flow vector: all coupons, with the last payment including principal cf = np.repeat(coupon, ttm * periods) cf[-1] += principal # add principal to the last payment# Discount factors exponents = np.arange(1, ttm * periods +1) discount_factors =1/ (1+ interest_rate / periods) ** exponents# Present value (bond price) present_value = np.sum(cf * discount_factors)return present_value# 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: # Run the function for three different interest rates:# 8% annual interest rate:bond1 = bondprice(principal=3_000_000, ttm=20, coupon_rate=0.11, interest_rate=0.08, periods=2)print("The bond price when interest rate is 8% is")print(f"$ {bond1:,.2f}")# 11% annual interest rate:bond2 = bondprice(3_000_000, 20, 0.11, 0.11, 2)print("The bond price when interest rate is 11% is")print(f"$ {bond2:,.2f}")# 13% annual interest rate:bond3 = bondprice(3_000_000, 20, 0.11, 0.13, 2)print("The bond price when interest rate is 13% is")print(f"$ {bond3:,.2f}")
The bond price when interest rate is 8% is
$ 3,890,674.82
The bond price when interest rate is 11% is
$ 3,000,000.00
The bond price when interest rate is 13% is
$ 2,575,634.19
5.2 CHALLENGE 2 Solution - Approach 2
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.
def bondprice2(principal, ttm, coupon_rate, interest_rate, periods):""" Calculates the bond price using the annuity formula for coupon PV and the present value of the principal. Parameters: principal (float): Face value of the bond ttm (int): Time to maturity (years) coupon_rate (float): Annual coupon rate (e.g., 0.11 for 11%) interest_rate (float): Annual market interest rate (yield) periods (int): Number of compounding periods per year Returns: float: Present value (price) of the bond """# Coupon payment per period coupon = (coupon_rate / periods) * principal# Present value of coupons (ordinary annuity) PV_coupons = coupon / (interest_rate / periods) * (1-1/ (1+ interest_rate / periods) ** (ttm * periods) )# Present value of the principal PV_principal = principal / (1+ interest_rate / periods) ** (ttm * periods)# Bond pricereturn PV_coupons + PV_principal# Run the function for three different interest ratesbond1 = bondprice2(3_000_000, 20, 0.11, 0.08, 2)print("The bond price when interest rate is 8% is")print(f"$ {bond1:,.2f}")bond2 = bondprice2(3_000_000, 20, 0.11, 0.11, 2)print("The bond price when interest rate is 11% is")print(f"$ {bond2:,.2f}")bond3 = bondprice2(3_000_000, 20, 0.11, 0.13, 2)print("The bond price when interest rate is 13% is")print(f"$ {bond3:,.2f}")
The bond price when interest rate is 8% is
$ 3,890,674.82
The bond price when interest rate is 11% is
$ 3,000,000.00
The bond price when interest rate is 13% is
$ 2,575,634.19