He estado trabajando en la obtención de los parámetros de entrada para la optimización no lineal que da los parámetros del modelo de Nelson Siegel Svensson y estoy llevando a cabo la regresión OLS como se describe en esta respuesta . Sin embargo, los parámetros de entrada obtenidos con el OLS están demasiado alejados de los parámetros reales, que he comprobado con algunos parámetros que sí tengo. Estoy utilizando las ecuaciones que aparecen en la "Figura 5" de la página 12 de este documento y obtener los datos de rendimiento, eligiendo bonos a la par y utilizando sus cupones como rendimientos a la par para obtener los tipos al contado, lo que parece ser un método correcto basado en la página 3 de este documento . El código que utilizo es el siguiente, donde acabo de implementar la fórmula del enlace anterior y he realizado la regresión en Python. Mi consulta es si hay algún problema con la forma en que configuro matrix_of_params
o si puede tener que ver con los datos en df
sí mismo .
Ejecuto la función anterior para diferentes valores de tau_1
y tau_2
. Luego tengo una función para obtener el params
asociado con el menor residuals
que estoy seguro de que es correcto.
#df is a Dataframe containing all the data about the Bonds
def obtainingparams(self, df, tau_1, tau_2, residuals):
values = []
face_values = df['FACE_VALUE'].values #Writing face values to an array
yields = (df['coupon'].values) #COUPON = YTM for Par Bonds
spot_rate = np.zeros((yields.shape[0]))
#Calculating Spot Rates
for x, value in np.ndenumerate(yields):
index = x[0]
if index == 0:
spot_rate[index] = (yields[index]/face_values[index]) * 100
else:
adding_negatives = 0
if index < spot_rate.shape[0]:
for i in range (0, index, 1):
adding_negatives = adding_negatives + (value*face_values[index]/200)/np.power((1+(spot_rate[i]/200)),i+1)
term_1 = face_values[index] - adding_negatives
spot_rate[index] = (2 * ((np.power(((((face_values[index] + ((value*face_values[index]/200)))/term_1))),1/(index+1)))-1))*100
matrix_of_params = np.empty(shape=[1, 4])
months_to_maturity_matrix = df.months_to_maturity.values #Writing months to maturity to an array
#Populating the Matrix of Parameter Coefficients
count = 0
for x, value in np.ndenumerate(months_to_maturity_matrix):
if count < months_to_maturity_matrix.shape[0]:
months_to_maturity = months_to_maturity_matrix[count]
years_to_maturity = months_to_maturity/12.0
#Applying the equation in the link
newrow = [1, ((1-np.exp(-years_to_maturity/tau_1))/(years_to_maturity/tau_1)), ((1-np.exp(-years_to_maturity/tau_1))/(years_to_maturity/tau_1))-(np.exp(-years_to_maturity/tau_1)), ((((1-np.exp(-years_to_maturity/tau_2))/(years_to_maturity/tau_2))))-(np.exp(-years_to_maturity/tau_2))]
count = count + 1
#Just adding the new row to the matrix of parameter coefficients
matrix_of_param_coefficients = np.vstack([matrix_of_params, newrow])
#Carrying out OLS Regression
params = np.linalg.lstsq(matrix_of_params,spot_rate)[0]
residuals = np.sqrt(((spot_rate - matrix_of_params.dot(params))**2).sum())
#To keep track of which params are associated with which residuals
values.append((tau_1, tau_2, residuals, params))
return values
Gracias