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:
¿cuál es el valor esperado y la volatilidad de los valores de las compras si no se reraliza cobertura? (Incluir graficas y análisis)
¿cuál es el valor esperado y la volatilidad de los valores de las compras si se reraliza cobertura? (Incluir graficas y análisis)
Compare las proyecciones con los precios observados por medio de una grafica y una tabla en donde se pueda visualizar el valor esperado y un intervalo de confianza del 95% para cada periodo.
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
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" )
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" )
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")
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")
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
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
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)
}
# 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
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")
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
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
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")
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
#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