diff --git a/simulation-investigation.ipynb b/simulation-investigation.ipynb new file mode 100644 index 0000000..117a399 --- /dev/null +++ b/simulation-investigation.ipynb @@ -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])