I am trying to determine the parameters for the Nelson Siegel Svensson model and am solving a Non- Linear Optimization problem to do this. Some of the code I have written is below and this is where my problem lies as I find that some of my discount factors are of the order 10^-30 and I don't know where I am going wrong. I am using the procedure presented in Pg. 5 of this paper. df is a dataframe which consists of observed bond data. All coupon payments will take place in 6 month intervals.

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)
                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)))))                                

Edit: Please let me know if I need to provide more information. I realize in the paper I have cited they just consider the Nelson Siegel model, however in the code above I have accounted for the extra parameters associated with the Nelson Siegel Svensson model.

Thank You


1 Answer 1


if I read it correctly the paper you mention is about Nelson-Siegel and not Nelson-Siegel Svensson. The easier way to cross check it is to simply start by fixing theta and estimate the remaining parameters by OLS. If that works, then the optimization algorithm should work similarly. Below I attach a simple matlab code that does it and that you can adapt for your purposes:

    % Define yield structure used in the estimation
maturity = [ 1/12; 2/12; 3/12; 4/12; 5/12; 6/12; 9/12; 12/12; 18/12; 24/12;];

%************************    PARAMETERS     *****************************

yn = size(maturity,1);  % number of yields
lamda=0.3;         % as in Diebold, Rudebusch and Aruoba(2003)
Roll=1;              % Rolling estimation (1) or recursive estimation (0).
length = size(xdata,1); % data length

%% Ex 2-1).Calculate and plot Nelson-Siegel factor loadings, given lamda.
mat = 1:1:120; 
pNS1 = ones(1,120); 
pNS2 = zeros(1,120); 
pNS3 = zeros(1,120);
for imat = 1:120;
    pNS2(imat) = exp(-(imat/12)/lamda);
    pNS3(imat) = ((imat/12)/lamda)*exp(-(imat/12)/lamda);

CCw = [pNS1; pNS2; pNS3]'; %Coefficient matrix for all maturity 1:120
CC = CCw((maturity')*12,:);

% Extract (Estimate) Nelson-Siegel factors for yields by OLS.
yield= xdata(1:length,1:10);  
NS = ((CC'*CC)\eye(size(CC,2)))*CC'*yield';

   % Plot the NS factors and their empirical proxies
   tm = dates;
   tm = tm';
     ymin = min(NS(1,:))-0.05; ymax = max(NS(1,:))+0.05;
     plot(tm,NS(1,:),'r-', tm, yield(:,10), 'b:');
     h = legend('NS 1st factor','2year yield',1);

     plot(tm,NS(2,:),'r-', tm, -(yield(:,10)-yield(:,1)), 'b:');
     h = legend('NS 2nd factor',' -(2year - 1month)',1);

     plot(tm,NS(3,:),'r-', tm, 2*yield(:,3)-(yield(:,1)+yield(:,10)), 'b:');
     h = legend('NS 3rd factor','2*3month - (1month + 24month)',1);
  • $\begingroup$ Thank You. However, I would like to continue with solving the Non-Linear Optimization problem and hence just want to understand where I'm going wrong with my code. $\endgroup$
    – Jojo
    Jul 22, 2015 at 15:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.