Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions simulation-investigation.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import datetime as dt

def get_price_data(n_samples, risk_free_rate, volatility, time_deltas, total_collateral):
price_data = np.zeros((n_samples, len(time_deltas)+1))
initial_price = total_collateral
price_data[:,0] = initial_price
for j in range(n_samples):
for i in range(0,len(time_deltas)):
price_data[j,i+1] = price_data[j,i]*np.exp((risk_free_rate-np.power(volatility, 2)/2)*time_deltas[i]+volatility*np.sqrt(time_deltas[i])*np.random.normal(0,1))

return price_data

def lender_payoff(price_data_row, risk_free_rate, total_loan_amount, total_repayment_amount, convertible_coll_ratios, convertible_loan_ratios, time_deltas):
lender_total_payoff = 0
collateral_percent_left = 1
loan_percent_accounted_for = 0
time_left = np.sum(time_deltas)
is_repaid=False
for i in range(1,len(price_data_row)):
current_value = price_data_row[i]
if borrower_should_default(collateral_percent_left, loan_percent_accounted_for, current_value, total_repayment_amount, total_loan_amount):
lender_total_payoff += current_value*collateral_percent_left*np.exp(risk_free_rate*time_left)
break
else:
if lender_should_convert(current_value, convertible_coll_ratios[i-1], convertible_loan_ratios[i-1], total_loan_amount):
lender_total_payoff += current_value*convertible_coll_ratios[i-1]
collateral_percent_left -= convertible_coll_ratios[i-1]
loan_percent_accounted_for += convertible_loan_ratios[i-1]
time_left -= time_deltas[i-1]
if time_left <= 0:
is_repaid=True
break
else:
lender_total_payoff += total_loan_amount*convertible_loan_ratios[i-1]
collateral_percent_left -= convertible_coll_ratios[i-1]
loan_percent_accounted_for += convertible_loan_ratios[i-1]
time_left -= time_deltas[i-1]
if time_left <= 0:
is_repaid=True
break
if is_repaid:
lender_total_payoff += total_repayment_amount - total_loan_amount*loan_percent_accounted_for
return lender_total_payoff

def borrower_should_default(collateral_percent_left, loan_percent_accounted_for, current_value, total_repayment_amount, total_loan_amount):
total_amount_still_owed = total_repayment_amount - loan_percent_accounted_for*total_loan_amount
total_collateral_left_current_value = collateral_percent_left*current_value
return total_amount_still_owed > total_collateral_left_current_value

def lender_should_convert(current_value, convertible_collateral_percentage, convertible_loan_percentage, total_loan_amount):
return current_value*convertible_collateral_percentage > convertible_loan_percentage*total_loan_amount

def get_average_payoffs(n_samples, risk_free_rate, volatility, total_collateral, total_loan_amount, total_repayment_amount, convertible_coll_ratios, convertible_loan_ratios, time_deltas):
price_data = get_price_data(n_samples, risk_free_rate, volatility, time_deltas, total_collateral)
lender_payoffs = np.zeros(n_samples)
for i in range(n_samples):
lender_payoffs[i] = lender_payoff(price_data[i,:], risk_free_rate, total_loan_amount, total_repayment_amount, convertible_coll_ratios, convertible_loan_ratios, time_deltas)
return np.average(lender_payoffs)

def get_payoff_delta(n_samples, risk_free_rate, volatility, total_collateral, total_loan_amount, total_repayment_amount, convertible_coll_ratios, convertible_loan_ratios, time_deltas):
loan_payoff = get_average_payoffs(n_samples, risk_free_rate, volatility, total_collateral, total_loan_amount, total_repayment_amount, convertible_coll_ratios, convertible_loan_ratios, time_deltas)
risk_free_payoff = total_loan_amount*np.exp(risk_free_rate*np.sum(time_deltas))
return loan_payoff - risk_free_payoff

def get_payoff_histogram(n_samples, risk_free_rate, volatility, total_collateral, total_loan_amount, total_repayment_amount, convertible_coll_ratios, convertible_loan_ratios, time_deltas):
price_data = get_price_data(n_samples, risk_free_rate, volatility, time_deltas, total_collateral)
lender_payoffs = np.zeros(n_samples)
for i in range(n_samples):
lender_payoffs[i] = lender_payoff(price_data[i,:], risk_free_rate, total_loan_amount, total_repayment_amount, convertible_coll_ratios, convertible_loan_ratios, time_deltas)
plt.hist(lender_payoffs, bins=50)
plt.show()

# n_samples = 50000
# risk_free_rate = 0.03
# volatility = 0.75
# total_collateral = 1000000 #(in USD)
# total_loan_amount = 300000 #(in USD)
# total_repayment_amount = 310000 #(in USD)
# convertible_coll_ratio = [0.03,0.02,0.01,0.01]
# convertible_loan_ratio = [0.2,0.15,0.1,0.1]
# time_deltas = [0.25,0.25,0.25,0.25] # in years

print(get_payoff_delta(50000, 0.03, 0.75, 1000000, 300000, 310000, [0.03,0.02,0.01,0.01], [0.2,0.15,0.1,0.1], [0.25,0.25,0.25,0.25]))
get_payoff_histogram(10000, 0.03, 0.75, 1000000, 300000, 310000, [0.03,0.02,0.01,0.01], [0.2,0.15,0.1,0.1], [0.25,0.25,0.25,0.25])