title: Calibrate parameters of Yield Curve Nelson Siegel Svensson
body: <p>[Edited]
  Dear Team</p>
  <p>I work with Nelson Siegel Svensson Yield Curve and I need to calibrate parameters b0, b1, b2, b3 and tau0, tau1 by least squares, related to real X,Y data and Y estimated with Yield Curve, I have this code to search calibration, but I'm not sure its a best strategy to reach the goal:</p>
  <pre><code>from scipy.optimize import least_squares
  import numpy as np
  from math import exp as EXP, trunc
  from nelson_siegel_svensson import NelsonSiegelSvenssonCurve
  import pandas as pd
  import matplotlib.pyplot as plt
  
  def model(x, const):
      arr = np.array([])
      for val in const:
          arr = np.append(arr,(x[0])+(x[1]*((1-EXP(-val/x[4]))/(val/x[4])))+(x[2]*((((1-EXP(-val/x[4]))/(val/x[4])))-(EXP(-val/x[4]))))+x[3]*((((1-EXP(-val/x[5]))/(val/x[5])))-(EXP(-val/x[5]))))
      return arr
   
  def fun(x, const, y_real):
      return y_real - model(x,const)
   
   
  # days
  const = np.array([30,90,270,548,913,1278,1643,2008,2373,2738,3103,3468,3833,4198,4563,4928,5293,5658,6023,6388,6935,7300,7665,8030])/365
  
  # empty values represented with 0
  y_real = np.array([3.33156,3.44928,3.62778,3.74313,3.96015,4.384,4.4705,4.55701,4.63817,4.69949,4.76081,4.82213,4.87285,4.8681,4.86336,4.85861,4.85387,4.84912,4.87039,4.89833,4.94286,4.98739,5.03192,5.07645])
  
  # initial coefficients of Nelson Siegel Svensson
  x0 = np.array([0.0001, 0.0001, 0.0001, 0.0001, 1.0, 1.0])
  
  res = least_squares(fun, x0, bounds=(0,5000), args=(const, y_real), verbose=1)
   
  print(res.x)
  
  X_fix = np.linspace(start=const[0], stop=const[-1], num=(const.size*20))
  
  NSS = NelsonSiegelSvenssonCurve(beta0=res.x[0], beta1=res.x[1], beta2=res.x[2], beta3=res.x[3], tau1=res.x[4], tau2=res.x[5])
  
  pd_interpolation = pd.DataFrame(columns=['Period','Value'])
  
  font = {'family': 'serif',
      'color':  '#1F618D',
      'weight': 'bold',
      'size': 14,
      }
  
  font_x_y = {'family': 'serif',
      'color':  '#C70039',
      'weight': 'bold',
      'size': 13,
      'style': 'oblique' 
      }
  
  fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(10, 6))
  
  minx = -const[1]*3
  
  config_manager = plt.get_current_fig_manager()
  config_manager.set_window_title(&quot;Visualización &quot; )
  
  screen_x, screen_y = config_manager.window.wm_maxsize()
  
  anchura = str(trunc(screen_x/12))
  altura = str(trunc(screen_y/8))
  middle_window = &quot;+&quot; + anchura + &quot;+&quot; + altura
  
  config_manager.window.wm_geometry(middle_window)
  
  plt.title('Interpolación ', fontdict=font, loc='center')
  plt.xlabel('Periodo', fontdict=font_x_y)
  plt.ylabel('Aproximación', fontdict=font_x_y, rotation=90, labelpad=10)
  
  ax.set_ylim(ymin=0, ymax=(np.amax(y_real)*1.1))
  ax.set_xlim(xmin=minx, xmax=(np.amax(const)*1.03))
  
  ax.plot(const, y_real, 'ro', label='Dato real')
  ax.plot(X_fix, NSS(X_fix),'--', label='Dato interpolado')
  ax.legend(loc='lower right', frameon=False)
  
  plt.show()
  </code></pre>
  <p>and the result is:</p>
  <p><a href="https://i.stack.imgur.com/YZ4Wb.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/YZ4Wb.png" alt="enter image description here" /></a></p>
  <p>Can you have other best option to work this?</p>
  <p>Thanks in advance.</p>