""" Created on Sat Oct 25 21:59:15 2025 @author: boranozdemir """ import numpy as np import numpy_financial as npf from datetime import datetime def create_cash_flow(face_value,coupon_rate, bond_length, freq=1): coupon_payment = face_value * coupon_rate / freq cash_flows = [coupon_payment] * (bond_length - 1) + [coupon_payment + face_value] cash_flows.insert(0, 0) return cash_flows def calculate_macualy_duration(yield_, face_value, coupon_rate, bond_length, freq=1): # i should start from 1 dur = 0 cf = create_cash_flow(face_value, coupon_rate, bond_length) npv = npf.npv(yield_, cf) coupon_value = coupon_rate * face_value for i in range(1, bond_length+1): if i == bond_length: dur += ((coupon_value + face_value)*i)/((1+yield_)**i) continue dur += ((coupon_value*i)/((1+yield_)**i)) dur = (1/(1+yield_))*(dur/npv) return dur def calculate_modified_duration(macaulay_duration, yield_): mod_duration = macaulay_duration / (1 + yield_) return mod_duration def calculate_convexity(yield_, face_value, coupon_rate, bond_length, freq=1): conv = 0 cf = create_cash_flow(face_value, coupon_rate, bond_length) npv = npf.npv(yield_, cf) coupon_value = coupon_rate * face_value for i in range(1, bond_length+1): if i == bond_length: conv += ((coupon_value + face_value)*i*(i+1))/((1+yield_/freq)**i) continue conv += ((coupon_value*i*(i+1))/((1+yield_/freq)**i)) conv = (1/(1+yield_)**2)*(conv/npv) return conv def calculate_periodic_duration(macualy_duration, freq): periodic_duration = macualy_duration * freq return periodic_duration def calculate_time_to_maturity(settle_date_str, maturity_date_str, freq=1): settle = datetime.strptime(settle_date_str, '%d-%m-%Y') maturity = datetime.strptime(maturity_date_str, '%d-%m-%Y') time_delta = maturity - settle T = time_delta.days / 365.25 periods = int(np.ceil(T * freq)) return T, periods