El 1 de octubre de 2016 una compañia productora de productos alimenticios, requiere una estrategia de cobertura a través de opciones europeas, para cubrir el riesgo de mercado causado por las variaciones de los precios del café, dado que es una materia prima fundamental para para muchos de los productos que oferta la compañia.

Las proyecciones de los volumenes de compra son las siguientes:

Fecha volumen en cargas (125 kg)
1-11-2016 700
1-12-2016 1200
1-01-2017 1000

El equipo de analistas de riesgo de la compañia, debe de proponer una estrategia de cobertura para estos flujos.
Un banco le ofrece opciones europeas para la cobertura con un valor de la prima un 5% por encima del precio teórico dado por el modelo de Black Scholes.

A la compañia le ofrecen opciones europeas, con un strike de 789258 COP por carga (una carga es 125 Kg). La prima que se debe de pagar por las opciones, corresponden al valor teórico obtenido por simulación de montecarlo mas el 10% de dicho valor.

El costo de mantener almacenado el café es del 6% anual con capitalización continua, sobre el valor de la carga.

El precio a diciembre de 2013 de la carga (125Kg), es de 789258 COP

En Colombia, la tasa libre de riesgo se representa a través de la rentabilidad ofrecida por los TES para los diferentes plazos. Se deben de utilizar las tasas de descuento apropiadas, según el plazo del descuento.

Plantee una estrategia de cobertura con opciones europeas sobre el precio de interno de la carga café, bajo el supuesto de que el café no tiene restricciones de almacenamiento.

Responda las siguientes preguntas:

1 Análisis de los precios internos del café.

De la pagina de la federacion de cafeteros de Colombia se puede obtener la serie histórica mensual del precio interno de Colombia.

https://www.federaciondecafeteros.org/static/files/Precio_interno_base_mensual.xls

1.1 Cargar datos del precio del Café

Precio_mensual_cafe <- read.csv(file="~/Downloads/Precio_interno_base_mensual_cafe.csv", header = TRUE, sep = ";")

Precio_mensual_cafe[,"Mes"]<-as.Date(Precio_mensual_cafe[,"Mes"], format = "%d/%m/%Y" )

1.2 Selección de la muestra

Se selecciona una muestra desde enero del 2000, hasta octubre de 2016

Inicio_muestra=which(Precio_mensual_cafe[,1]=="2000-01-01")
Fin_muestra=which(Precio_mensual_cafe [,1]=="2016-10-01")


Precio_cafe_2000_2016=Precio_mensual_cafe[Inicio_muestra :Fin_muestra,]

library(plotly)

plot_ly(Precio_cafe_2000_2016, x = ~Mes, y=~Precio.interno, type = "scatter" ,mode="line" )

1.2.1 Rendimientos del café

Rtos_Cafe=diff(log(Precio_cafe_2000_2016[,"Precio.interno"]))

plot_ly(Precio_cafe_2000_2016, x=~Precio_cafe_2000_2016[-1,"Mes"],y=~diff(log(Precio_cafe_2000_2016[,"Precio.interno"])), type = "scatter", mode="line")
## A line object has been specified, but lines is not in the mode
## Adding lines to the mode...
summary(Rtos_Cafe)
##      Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
## -0.225700 -0.045680  0.000000  0.004484  0.049710  0.337800
mean(Rtos_Cafe)
## [1] 0.004484023
sd(Rtos_Cafe)
## [1] 0.07271762
hist(Rtos_Cafe, breaks = 10, col = "gray", main = "histograma de rendimientos", freq = FALSE)
curve(dnorm(x,mean=mean(Rtos_Cafe),sd=sd(Rtos_Cafe)),add = T,col="blue")

2 Simulación del precio del café

Para la proyección del precio del café se utiliza un proceso estocástico browniano geometrico, bajo el supuesto de que el café no tiene restricciones de almacenamiento.

\[Precio_t=Precio_{t-1}*e^{(\mu-\frac{\sigma^2}{2})\Delta t+\sigma*\epsilon_t*\sqrt{\Delta t}}\]

mu=mean(Rtos_Cafe)*12
sigma=sd(Rtos_Cafe)*sqrt(12)
dt=1/12
So=Precio_cafe_2000_2016[which(Precio_cafe_2000_2016[,1]=="2016-10-01"),2]
Periodos=4
Iteraciones=1000
Spot=matrix(,Periodos,Iteraciones)
Spot[1,]=So
drift=vector()
drift[1]=So

for(j in 1:Iteraciones){
  for(i in 2:Periodos){
Spot[i,j]=Spot[i-1,j]*exp((mu-sigma^2/2)*dt+sigma*rnorm(1)*sqrt(dt))
drift[i]=Spot[i-1,j]*exp((mu-sigma^2/2)*dt)
}
}
 
matplot(Spot, type = "l", col = "gray", main="Proyección del precio del cafe")
lines(drift, type = "l")

3 Estimación de la curva cero bajo la metodología de Nelson y Siegel

Para la valoración de las opciones, se requiere de las tasas de descuento apropiadas para cada vencimiento (tasas libres de riesgo). Para la estimación de la curva cero para el 1 de octubre de 2016, se utilizan los datos suministrados por el banco de la republica como aproximación.

fecha 1 año 5 años 10 años
30/09/16 6.85% 6.55% 7.06%

http://www.banrep.gov.co/sites/default/files/paginas/Tes%281-5-10%29%20Pesos.xls Se extraen los datos

\[y_t(\tau)=\beta_{ot}+\beta_{1t}*\frac{1-exp(-\lambda\tau)}{\lambda\tau}+\beta_{2t}(\frac{1-exp(-\lambda\tau)}{\lambda\tau}-exp(-\lambda\tau))\]

\(\beta_{ot}\): Termino de largo plazo.
\(\beta_{1t}\): Termino de corto plazo.
\(\beta_{2t}\): Termino de mediano plazo.
\(\lambda\): Velocidad de ajuste a la media.

library(YieldCurve)
## Loading required package: xts
## Loading required package: zoo
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
Yield=c(6.85,6.55,7.06)
maduracion=c(1,5,10) # en años

parametros_N_y_S=Nelson.Siegel(Yield,maduracion)



Estimacion_N_S=function(beta_0,beta_1,beta_2,lambda,tau){

y=beta_0+beta_1*(1-exp(-lambda*tau))/(lambda*tau)+beta_2*((1-exp(-lambda*tau))/(lambda*tau)-exp(-lambda*tau))

return(y)

}

beta_0=parametros_N_y_S[1,"beta_0"]
beta_1=parametros_N_y_S[1,"beta_1"]
beta_2=parametros_N_y_S[1,"beta_2"]
lambda=parametros_N_y_S[1,"lambda"]



maduracion_flujos=c(1/12,2/12,3/12)

Tasas_curva_financiacion=Estimacion_N_S(beta_0,beta_1,beta_2,lambda,maduracion_flujos )/100

4 Proyección sin cobertura.

4.1 Proyección de cada flujo

Cargas_por_periodo=c(700,1200,1000)

Costo_compra= Spot[2:Periodos,]*Cargas_por_periodo

par(mfrow=c(3,1))
hist(Costo_compra[1,],30, col = "gray", main = "1-11-2016")
hist(Costo_compra[2,],30, col = "gray", main = "1-12-2016")
hist(Costo_compra[3,],30, col = "gray", main = "1-01-2017")

rowMeans(Costo_compra)
## [1]  643172204 1109569917  932810143
sd(Costo_compra[1,])
## [1] 45689621
sd(Costo_compra[2,])
## [1] 114231374
sd(Costo_compra[3,])
## [1] 117940186

·# Estimación del valor presente de todos los flujos sin cobertura.

Para la estimación de la volatilidad y el valor esperado total del flujo de caja, se descuentan a valor presente dichos flujos. Se tomará como tasa de descuento la curva cero de los TES, bajo el supuesto de que la compañia se puede financiar a dicha tasa.

Costo_presente_sin_cobertura=(Costo_compra[1,])*exp(-Tasas_curva_financiacion[1]*maduracion_flujos[1])+(Costo_compra[2,])*exp(-Tasas_curva_financiacion[2]*maduracion_flujos[2])+(Costo_compra[3,])*exp(-Tasas_curva_financiacion[3]*maduracion_flujos[3])

mean(Costo_presente_sin_cobertura)
## [1] 2644597549
sd(Costo_presente_sin_cobertura)
## [1] 250042638

5 proyección con cobertura

5.1 Calculadora de opciones.

Se crea una función para valorar opciones Call. Las funciones en R se definen con el comando function el cual recibe como argumento, los parámetros para cálculo de la opción.

EN este ejemplo la función se nombra como: “Prima_call_europea” y los argumentos se introducen son los siguientes:

Prima_call_europea(So,sigma,r,q,dt,k,Numero_periodos,Iteraciones)

Por ejemplo:

Prima_call_europea(So=100,sigma=0.2,r=0.1,q=0.03,dt=1/2,Numero_periodos = 2,Iteraciones = 1000,k=100)

Prima_call_europea=function(So,sigma,r,q,dt,k,Iteraciones) {

prima_call=vector()


for(j in 1:Iteraciones){
St=So*exp((r+q-sigma^2/2)*dt+ sigma*rnorm(1)*sqrt(dt))
prima_call[j]=max(St-k,0)*exp(-r*dt)
}



Call_Promedio=mean(prima_call)



return(Call_Promedio)

}

5.2 Valoración de las primas de las opciones call europeas

# Primas por carga de 125kg

Prima_Unitaria_Nov=Prima_call_europea(So=So,sigma=sigma,r=Tasas_curva_financiacion[1],q=0.06,dt=maduracion_flujos[1],k=So,Iteraciones = 1000)*1.1

print(Prima_Unitaria_Nov)
## [1] 36043.37
Prima_Unitaria_Dic=Prima_call_europea(So=So,sigma=sigma,r=Tasas_curva_financiacion[2],q=0.06,dt=maduracion_flujos[2],k=So,Iteraciones = 1000)

print(Prima_Unitaria_Dic)
## [1] 49296.14
Prima_Unitaria_Ene=Prima_call_europea(So=So,sigma=sigma,r=Tasas_curva_financiacion[3],q=0.06,dt=maduracion_flujos[3],k=So,Iteraciones = 1000)

print(Prima_Unitaria_Ene)
## [1] 63750.58

5.3 Beneficio unitario Prima Call

k=So
Ben_Esp_unit_Nov=vector() #Beneficio unitario esperado para la opción que madura en Noviembre
Ben_Esp_unit_Dic=vector() #Beneficio unitario esperado para la opción que madura en Diciembre
Ben_Esp_unit_Ene=vector() #Beneficio unitario esperado para la opción que madura en Enero


for(j in 1:Iteraciones){
Ben_Esp_unit_Nov[j]=max(Spot[2,j]-k,0)
Ben_Esp_unit_Dic[j]=max(Spot[3,j]-k,0)
Ben_Esp_unit_Ene[j]=max(Spot[4,j]-k,0)
}

par(mfrow=c(3,1))
hist(Ben_Esp_unit_Nov,20,col = "gray")
hist(Ben_Esp_unit_Dic,20,col = "gray")
hist(Ben_Esp_unit_Ene,20,col = "gray")

5.4 Flujo de caja con cobertura

5.5 Razón de cobertura delta.

La delta de una opción puede utilizarse como razón de cobertura, a lo cual se conoce como cobertura delta. La cobertura delta implica que mientras la delta de la opción no cambie, los rendimientos del portafolio de cobertura, serán iguales a la tasa libre de riesgo. Esto tambén se conoce como Posición neutral Delta.

La delta puede calcularse como la \(N(d_1)\) lo cual corresponde a la probabilidad acumulada de una distribución normal estándar, hasta el valor \(d_1\).

\[d_1=\frac{ln(So/K)+(r+q+\sigma^2/2)T}{\sigma \sqrt{T}}\]

q=0.06
d1_nov=(log(So/k)+(Tasas_curva_financiacion[1]/100+q+sigma^2/2)*maduracion_flujos[1])/(sigma*sqrt(maduracion_flujos[1]))

d1_dic=(log(So/k)+(Tasas_curva_financiacion[2]/100+q+sigma^2/2)*maduracion_flujos[2])/(sigma*sqrt(maduracion_flujos[2]))

d1_ene=(log(So/k)+(Tasas_curva_financiacion[3]/100+q+sigma^2/2)*maduracion_flujos[3])/(sigma*sqrt(maduracion_flujos[3]))


delta_nov=pnorm(d1_nov)
print(delta_nov)
## [1] 0.5422779
delta_dic=pnorm(d1_dic)
print(delta_dic)
## [1] 0.5596559
delta_ene=pnorm(d1_ene)
print(delta_ene)
## [1] 0.5729025

6 Flujo de caja con cobertura

Las opciones se liquidan financieramente (non delivery)

Costo_total_primas=Prima_Unitaria_Nov*Cargas_por_periodo[1]*delta_nov+Prima_Unitaria_Dic*Cargas_por_periodo[2]*delta_dic+Prima_Unitaria_Ene*Cargas_por_periodo[3]*delta_ene

#Valor presente del beneficio total
VP_Beneficio_total=Ben_Esp_unit_Nov*exp(-Tasas_curva_financiacion[1]*maduracion_flujos[1])*Cargas_por_periodo[1]*delta_nov+Ben_Esp_unit_Dic*exp(-Tasas_curva_financiacion[2]*maduracion_flujos[2])*Cargas_por_periodo[2]*delta_dic+Ben_Esp_unit_Ene*exp(-Tasas_curva_financiacion[3]*maduracion_flujos[3])*Cargas_por_periodo[3]*delta_ene

Costo_total_cobertura=Costo_total_primas-VP_Beneficio_total

Costo_presente_con_cobertura=Costo_presente_sin_cobertura+Costo_total_cobertura


sd(Costo_presente_sin_cobertura)/1000000
## [1] 250.0426
sd(Costo_presente_con_cobertura)/1000000
## [1] 171.6355
mean(Costo_presente_sin_cobertura)/1000000
## [1] 2644.598
mean(Costo_presente_con_cobertura)/1000000
## [1] 2658.205

7 desempeño real de la estrategia

7.1 Comparación del pronostico del precio con el precio observado.

Precio_obs_nov=Precio_mensual_cafe[which(Precio_mensual_cafe[,1]=="2016-11-01"),2]
Precio_obs_dic=Precio_mensual_cafe[which(Precio_mensual_cafe[,1]=="2016-12-01"),2]
Precio_obs_ene=Precio_mensual_cafe[which(Precio_mensual_cafe[,1]=="2017-01-01"),2]

plot(c(So,Precio_obs_nov,Precio_obs_dic,Precio_obs_ene),type="l", main = "evolción observada del precio del cafe entre octubre de 2016 y enero de 2017 ")

matplot(Spot, type = "l", col = "gray", main="Proyección del precio del cafe")
lines(drift, type = "l")
lines(c(So,Precio_obs_nov,Precio_obs_dic,Precio_obs_ene),type="l", lwd=2, col="blue")

7.2 Desempeño sin cobertura

Costo_presente_observado_sin_cobertura=Precio_obs_nov*Cargas_por_periodo[1]*exp(-Tasas_curva_financiacion[1]*maduracion_flujos[1])+Precio_obs_dic*Cargas_por_periodo[2]*exp(-Tasas_curva_financiacion[2]*maduracion_flujos[2])+Precio_obs_ene*Cargas_por_periodo[3]*exp(-Tasas_curva_financiacion[3]*maduracion_flujos[3])

print(Costo_presente_observado_sin_cobertura)
## [1] 2582211079

7.3 Desempeño con cobertura

#Valor presente de los beneficios

VP_Beneficio_obs_Nov=max(Precio_obs_nov-k,0)*Cargas_por_periodo[1]*delta_nov*exp(-Tasas_curva_financiacion[1]*maduracion_flujos[1])
VP_Beneficio_obs_Dic=max(Precio_obs_dic-k,0)*Cargas_por_periodo[2]*delta_dic*exp(-Tasas_curva_financiacion[2]*maduracion_flujos[2])
VP_Beneficio_obs_ene=max(Precio_obs_ene-k,0)*Cargas_por_periodo[3]*delta_ene*exp(-Tasas_curva_financiacion[3]*maduracion_flujos[3])

VP_beneficio_obs_total=VP_Beneficio_obs_Nov+VP_Beneficio_obs_Dic+VP_Beneficio_obs_ene
Costo_presente_observado_con_cobertura=Costo_presente_observado_sin_cobertura+Costo_total_primas-VP_beneficio_obs_total

print(Costo_presente_observado_con_cobertura)
## [1] 2630520243