I am trying to determine the parameters for the Nelson Siegel Svensson model and am solving a Non- Linear Optimization problem to do this. I am using the procedure presented in this paper.
The way I am currently thinking of the set-up is as follows:
Bond 1 is associated with vector $m_1$ which contains all the differences between times to maturity and times of each of the payments for Bond 1. For example, if Bond 1 has 24 months to maturity and has semi_annual coupons $m_1 = [18,12,6,0]$. However, the paper suggests that even the face value needs to be included in $c_{ij}$. But the equation $\sum\limits_{j=1}^{l_i}c_{ij}*d(m_{ij}, \theta)$ gives a very low value for the price of the bond as the $d(m_{ij}, \theta)$ values are turning out to be very small (of the order 10^-34 through to 10^-1, for each bond, as the differences between times to maturity and time of the payment decreases).
So, am I correct in thinking that each bond is associated with a different discount factor vector as $m_{ij}$ changes for each bond?
I guess my main issue is, am I interpreting $m_{ij}$ correctly and hence correctly calculating the discount factors the right way, as I find that they are very small and hence the prices are very small and only got a reasonable answer for the parameters when I take the discount factor to be 1 when $c_{ij} = Face value + Coupon$
Also, I realize in the paper I have cited they just consider the Nelson Siegel model, however in the code I have written below I account for the extra parameters associated with the Nelson Siegel Svensson model.
This is the code that I am using to determine the prices, where df contains all the observed market data:
def calculatingprices(df, beta_0, beta_1, beta_2, beta_3, tau_1, tau_2): #I am just creating a dict 'd' which will have the months to maturity for each bond as keys and #a list as its values. The lists will contain the months to maturity - payments associated #with the bond months_to_maturity_matrix = df['months_to_maturity'].values number_of_rows = df.shape[0] theoretical_price_for_bonds = np.zeros((number_of_rows, 1)) d = {} for months_to_maturity_bond in months_to_maturity_matrix: l = [] #Adding the difference in dates to the dict d. Differences, will just be multiples of 6 upto 360 (i.e. the 30 year bond) for i in range(6, 360, 6): if i <= months_to_maturity_bond: l.append(months_to_maturity_bond - i) else: l.append(0) d[months_to_maturity_bond] = l d_ordered = collections.OrderedDict(sorted(d.items())) #I then use the formula for the discount factor as follows for x, value in np.ndenumerate(months_to_maturity_matrix): diff_between_maturity_and_payments_array = np.array(d_ordered[value]) years_diff_between_maturity_and_payments_array = diff_between_maturity_and_payments_array/12 theoretical_discount_factor = np.exp(-years_diff_between_maturity_and_payments_array * (beta_0 + ((beta_1 + beta_2)*((1-np.exp(-years_diff_between_maturity_and_payments_array/tau_1))/years_diff_between_maturity_and_payments_array/tau_1))-(beta_2*np.exp(-years_diff_between_maturity_and_payments_array/tau_1)) + (beta_3*(((1-np.exp(-years_diff_between_maturity_and_payments_array/tau_2))/years_diff_between_maturity_and_payments_array/tau_2) -np.exp(-years_diff_between_maturity_and_payments_array/tau_2))))) Thank You