def calc_cashflow(SMM_array, r, Pool1_bal, Pool2_bal, Pool1_mwac, Pool1_age, Pool1_term, Pool2_mwac, Pool2_age, Pool2_term, coupon_rate, Tranche_bal_arr): # Pool cash flows arrays # 5 columns: #0 PMT #1 Interest #2 Principal #3 pp CF #4 Balance ### Define Tranche CF arrays outside to pre-allocate # define Tranche CF array, Tranche x time x (Principal, Interest, Balance) # Tranche order: 'CG', 'VE', 'CM', 'GZ', 'TC', 'CZ', 'CA', 'CY' # Tranche order: 0, 1, 2, 3, 4, 5, 6, 7 Tranche_CF_arr = np.zeros((8, 241, 3)) for i in range(8): Tranche_CF_arr[i, 0, 2] = Tranche_bal_arr[i] #a=time.time() Pool1_data = np.zeros((241, 5)) Pool2_data = np.zeros((241, 5)) Pool1_data[0, 4] = Pool1_bal Pool2_data[0, 4] = Pool2_bal lib.pool_cf(Pool1_data, Pool1_mwac, Pool1_age, Pool1_term, SMM_array) lib.pool_cf(Pool2_data, Pool2_mwac, Pool2_age, Pool2_term, SMM_array) # Reproduce Principal CF Allocation (waterfall) Total_principal = Pool1_data[:, 2] + Pool2_data[:, 2] + Pool1_data[:, 3] + Pool2_data[:, 3] CA_CY_princ = 0.225181598 * Total_principal Rest_princ = 0.7748184 * Total_principal # Temporary arrays for calculating GZ/CZ interest accrual. The "interest" here # is not cash flow. 2 columns: #interest #accrued GZ_interest = np.zeros((241, 2)) CZ_interest = np.zeros((241, 2)) # Calculate Cash flows # redefine giant Tranche_DF lib.tranche_CF_calc(Tranche_CF_arr, CA_CY_princ, Rest_princ, GZ_interest, CZ_interest, coupon_rate) CF_arr = np.zeros((241, 8)) for i in range(8): CF_arr[:, i] = Tranche_CF_arr[i, :, 0] + Tranche_CF_arr[i, :, 1] #print(time.time()-a) # Calculate Bond price price = calc_bond_price(CF_arr[1:, :], r) return price
'CY': 13950000 } # small for loop, pre-allocate data for tranches for i in Tranche_list: Tranche_dict[i] = pd.DataFrame(np.zeros((241, 3)), columns=cols) Tranche_dict[i].loc[0, 'Balance'] = Tranche_bal_dict[i] # Temporary arrays for calculating GZ/CZ interest accrual. The "interest" here # is not cash flow. cols = ['interest', 'accrued'] GZ_interest = pd.DataFrame(np.zeros((241, 2)), columns=cols) CZ_interest = pd.DataFrame(np.zeros((241, 2)), columns=cols) # Calculate Cash flows lib.tranche_CF_calc(Tranche_dict, CA_CY_princ, Rest_princ, GZ_interest, CZ_interest, coupon_rate) CF_df = pd.DataFrame(np.zeros((240, 8)), columns=list(Tranche_bal_dict.keys())) for i in Tranche_bal_dict.keys(): CF_df[i] = Tranche_dict[i]['Principal'] + Tranche_dict[i]['Interest'] # %% Calculate Standard Errors, Duration, Convexity, and OAS cf_bond = CF_df.iloc[1:, :] m = 10000 r0 = np.log((zero_df.iloc[1, 1]/2+1)**(0.5))/0.25 price_df_MC = lib.mc_bond(m, cf_bond, theta_df, kappa, sigma, r0, antithetic=True) price_mean_MC = price_df_MC.mean() price_std_MC = price_df_MC.std()/np.sqrt(len(price_df_MC))