# nbi:hide_in
'''
Este Notebook tiene el código que se utilizo para generar la calculadora de Tasa fija y UVR's.
Las funciones desarrolladas estan implementadas en ingles,
mientras que cada calculadora en espanol debido a que no see hicieron al tiempo
'''
################################################################################################################
#Importamos las librerias necesarias para utilizar la calculadora.
import numpy as np #Tiene un tipo de dato muy importante para el analisis np.array
import pandas as pd #Libreria de analisis estadistico
import matplotlib.pylab as plt #Se utiliza para graficar
#Para manejar fechas,
from datetime import date
import datetime
#Estas librerias nos permiten utilizar los botones y exportarlos
import nbinteract as nbi
import ipywidgets as widgets
from ipywidgets import Layout
from IPython.display import display,HTML
'''
Para exportar, es importante que se haga desde una terminal con nbinteract instalado
ver https://www.nbinteract.com/
y se genera el html como,
nbinteract Calculadoras.ipynb
de forma tal que se debe subir a un repositorio en GitHub con los requerimientos para que Binder lo utilice.
'''
################################################################################################################
###################### A continuacion se definen las funciones utilizadas en la calculadora.####################
################################################################################################################
#Como se debe truncar en algunas ocasiones, definimos la funcion truncar.
def trunc(num,n=3):
return np.floor(10.**n * num) / 10.**n
#Calcula la fecha del anterior pago
def prev_pay(today,date_Ven):
date_Ant=date_Ven.replace(year=today.year)
if ((date_Ant-today)/np.timedelta64(1,'D')>0):
date_Ant=date_Ant.replace(year=today.year-1)
return date_Ant
#Calcula la fecha del Siguiente pago
def next_pay(today,date_Ven):
date_Next=date_Ven.replace(year=today.year+1)
if today.month < date_Ven.month:
date_Next=date_Next.replace(year=today.year)
elif today.month==date_Ven.month:
if today.day<=date_Ven.day:
date_Next=date_Next.replace(year=today.year)
return date_Next
#Se calcula la duracion del bono como
'''
$$
\text{Duracion}=\sum_n (n+\nu-1)\frac{cupon*100}{(1+tasa)**(n+\nu-1)}
$$
'''
def Duration(today,date_Ven,cupon,tasa,F='C'):
#Cuando es futuros, se debe corregir un día
if F=='D':
today+=datetime.timedelta(days=-1)
Dmac=0.
div=0.
date_Next=next_pay(today,date_Ven)
date_Ant=prev_pay(today,date_Ven)
pay_year=date_Next.year
pagos=date_Ven.year-date_Next.year+1
nu=((date_Next-today).days)/365.
for pago in range(pagos):
t=pago+nu
if(pay_year==date_Ven.year): cupon+=1.
peso=(cupon*100.)*((1./(1.+tasa)**(t)))
Dmac+=(t)*peso
div+=peso
pay_year+=1
if div==0: return '--'
return round(Dmac/div,3)
#Calcula la cantidad de 29's de febreros entre dos fechas
def bis(date1,date2):
if (date2-date1)/np.timedelta64(1,'D')<0:
date1,date2=date2,date1
year=date1.year
bisi=0.
for year in range(date1.year,date2.year+1):
if (year%4==0 and year%100!=0) or (year%4==0 and year%400==0):
if(year>date1.year and year< date2.year):
bisi+=1
elif(date1.year==date2.year and date1.month<3 and date2.month>2):
bisi+=1
elif(year==date1.year and date1.month<3):
bisi+=1
elif(year==date2.year and date2.month>2):
bisi+=1
return int(bisi)
#Calcula el Numero de dias SIN BISIESTOS entre dos fechas
def days(date1,date2):
if (date2-date1)/np.timedelta64(1,'D')<0:
date1,date2=date2,date1
return int((date2-date1)/np.timedelta64(1,'D')-bis(date1,date2))
#Calcula el precio Limpio MEC
def PLimpio(date_Ven,today,cupon,tasa):
date_prev=prev_pay(today,date_Ven)
Dias=days(today,date_prev)
Interes=round(cupon*Dias/365.,6)
days_prev=days(date_prev, today)
date_next=next_pay(today,date_Ven)
days_next=days(date_next,today)
cupon=cupon*100.
date_Cupon=date_next
if date_Ven.year==date_Cupon.year: cupon+=100
m=round(cupon/((1.+tasa)**((days_next)/365.)),6)
if days_prev==0: m=0
acum=0.
acum+=m
while (date_Ven.year-date_Cupon.year)>0:
date_Cupon=date_Cupon.replace(year=date_Cupon.year+1)
if date_Ven==date_Cupon: cupon+=100
days_next=days(date_Cupon,today)
n=days_next/365.
acum +=round((1./(1.+tasa)**(n))*cupon,6)
r=trunc(acum)
PL=trunc((r/100.-Interes)*100,3)
return PL
#Calcula los dias SIN BISIESTOS al vencimiento
def Dias_Vto(today,date_Ven):
date_Next=next_pay(today,date_Ven)
year=date_Next.year
Dias=days(today,date_Ven)
return int(Dias)
#Calcula los intereses del bono
def interests(cupon,today,date_Ven,column='C'):
fut=0.
if column=='D': fut=1.
date_Ant=prev_pay(today,date_Ven)
inte=(((cupon)*100.)/365.)*(int((today-date_Ant)/np.timedelta64(1,'D'))-fut)
return round(inte,6)
def Yield(Vencimiento,Hoy,Cupon,Limpio):
an=0.
bn=1.1
eps=1e-15
while (np.abs(an-bn)>eps):
pn=(an+bn)/2.
Test1=PLimpio(Vencimiento,Hoy,Cupon,an)-Limpio
Test2=PLimpio(Vencimiento,Hoy,Cupon,pn)-Limpio
if((Test1)*(Test2)>0):
an=pn
else:
bn=pn
if pn==0 or pn==1.1:
print('Tasa no encontrada')
return '--'
return round(pn,6)
'''Buttons y widgets
Cada uno de los botones o casillas para interaccion
deben ser definidos de forma independiente, y con un valor
inicial.
Si en dos casillas se utiliza el mismo objeto, cambian al tiempo.
'''
style = {'description_width': '75pt'}
Layout=Layout(width='100 pt')#, height='80px')
##### IPC widgets
Tasa_Compra_IPC=widgets.FloatText(
value=7.5,
style =style,
layout=Layout,
description='Tasa Compra:',
disabled=False
)
Tasa_Venta_IPC=widgets.FloatText(
value=7.5,
style =style,
layout=Layout,
description='Tasa Venta:',
disabled=False
)
Nominal_IPC=widgets.FloatText(
value=1000000000,
style = style,
layout=Layout,
description='Nominal:',
disabled=False
)
Tasa_Fondeo_IPC=widgets.FloatText(
value=4.5,
style =style,
layout=Layout,
description='Tasa de Fondeo:',
disabled=False
)
T_IPC=widgets.FloatText(
value=0,
style = style ,
layout=Layout,
description='T+:',
disabled=False
)
Futuros_IPC=widgets.IntText(
value=0,
style = style,
layout=Layout,
description='Futuros:',
disabled=False
)
Precio_Compra_IPC=widgets.FloatText(
value=100,
style = style,
layout=Layout,
description='Precio Compra:',
disabled=False
)
Precio_Venta_IPC=widgets.FloatText(
value=100,
style = style,
layout=Layout,
description='Precio Venta:',
disabled=False
)
Reinversion_IPC=widgets.FloatText(
value=4.5,
style = style,
layout=Layout,
description='Reinversión:',
disabled=False
)
##### UVR widgets
Tasa_Compra_UVR=widgets.FloatText(
value=2.5,
style =style,
layout=Layout,
description='Tasa Compra:',
disabled=False
)
Tasa_Venta_UVR=widgets.FloatText(
value=2.6,
style =style,
layout=Layout,
description='Tasa Venta:',
disabled=False
)
Nominal_UVR=widgets.FloatText(
value=10000000,
style = style,
layout=Layout,
description='Nominal:',
disabled=False
)
Tasa_Fondeo_UVR=widgets.FloatText(
value=4.5,
style =style,
layout=Layout,
description='Tasa de Fondeo:',
disabled=False
)
T_UVR=widgets.FloatText(
value=0,
style = style ,
layout=Layout,
description='T+:',
disabled=False
)
Futuros_UVR=widgets.IntText(
value=0,
style = style,
layout=Layout,
description='Futuros:',
disabled=False
)
Precio_Compra_UVR=widgets.FloatText(
value=100,
style = style,
layout=Layout,
description='Precio Compra:',
disabled=False
)
Precio_Venta_UVR=widgets.FloatText(
value=100,
style = style,
layout=Layout,
description='Precio Venta:',
disabled=False
)
UVR_Compra=widgets.FloatText(
value=0,
style = style,
layout=Layout,
description='UVR Compra:',
disabled=False
)
UVR_Venta=widgets.FloatText(
value=0,
style = style,
layout=Layout,
description='UVR Venta:',
disabled=False
)
Reinversion_UVR=widgets.FloatText(
value=4.5,
style = style,
layout=Layout,
description='Reinversión:',
disabled=False
)
# nbi:hide_in
import base64
# Convierte el dataframe y lo convierte a un link descargable en un .csv
# Utiliza ';' como separador
def create_download_link(df, filename = "data.csv",title = "Descargar datos"):
csv = df.to_csv(sep=';')
b64 = base64.b64encode(csv.encode(encoding='latin8'))
payload = b64.decode()
html = '<a download="{filename}" href="data:text/csv;base64,{payload}" target="_blank">{title}</a>'
html = html.format(payload=payload,title=title,filename=filename)
return HTML(html)
# nbi:hide_in
#Leemos los datos de la informacion de los bonos
df=pd.read_csv('https://raw.githubusercontent.com/jmsevillam/Calculadoras/master/ESPECIETF.csv',';',parse_dates=True)
df['Emision']=pd.to_datetime(df['Emision'], format='%d/%m/%Y')
df['Vencimiento']=pd.to_datetime(df['Vencimiento'], format='%d/%m/%Y')
Nombre_IPC=widgets.Dropdown(
options=list(df['Especie']),
style =style,
layout=Layout,
description='Bono:',
disabled=False,
)
# nbi:left
# nbi:hide_in
#Calcula para los futuros!
def Calcular2(Bono,Tasa,Futuro,Nominal,Hoy):
#Vuelve la tasa porcentajes de 0 a 1
Tasa=Tasa/100.
#Lee los datos del archivo csv, fechas y cupon
index=list(df['Especie']).index(Bono)
Emision=df['Emision'][index]
Vencimiento=df['Vencimiento'][index]
Cupon=trunc(float(df['Cupon'][index][:-1])/100.,5)
#Cambia la fecha a la futura
Hoy=Hoy+datetime.timedelta(days=Futuro)
#Calcula las cantidades en el futuro
Dias=Dias_Vto(Hoy,Vencimiento)
Duracion=Duration(Hoy,Vencimiento,Cupon,Tasa)
Precio_Limpio=PLimpio(Vencimiento,Hoy,Cupon,Tasa)
Pago_Anterior=prev_pay(Hoy,Vencimiento)
Pago_Siguiente=next_pay(Hoy,Vencimiento)
Intereses=interests(Cupon,Hoy,Vencimiento)
Precio_Sucio=round(Precio_Limpio+Intereses,4)
Valor_Giro=round((Precio_Sucio/100.)*Nominal,0)
#Devuelve las cantidades calculadas
ret=[Dias,Pago_Anterior,Pago_Siguiente,Precio_Sucio,Intereses,Precio_Limpio,Valor_Giro,Duracion,Hoy]
return ret
#Calcula para Hoy+(T+)
def Calcular_Precio_IPC(Bono,Tasa_Compra,Tasa_Venta,T,Futuro,Nominal,tasaFondeo,Reinversion):
#Lee los datos del bono, fechas y cupon
index=list(df['Especie']).index(Bono)
Emision=df['Emision'][index]
Vencimiento=df['Vencimiento'][index]
Cupon=trunc(float(df['Cupon'][index][:-1])/100.,5)
# Vuelve porcentajes de 0 a 1. i.e. 7% -> 0.07
Tasa=Tasa_Compra/100.
tasaFondeo=tasaFondeo/100
#Calcula la fecha de hoy, corrida con T+
Hoy=pd.to_datetime(date.today())
Hoy=Hoy+datetime.timedelta(days=T)
#Calcula los dias al vencimiento, duracion y precio limpio con las funciones definidas arriba
Dias=Dias_Vto(Hoy,Vencimiento)
Duracion=Duration(Hoy,Vencimiento,Cupon,Tasa)
Precio_Limpio=PLimpio(Vencimiento,Hoy,Cupon,Tasa)
#Calcula el pago anterior y siguiente
Pago_Anterior=prev_pay(Hoy,Vencimiento)
Pago_Siguiente=next_pay(Hoy,Vencimiento)
#Calcula los intereses y el precio Sucio
Intereses=interests(Cupon,Hoy,Vencimiento)
Precio_Sucio=round(Precio_Limpio+Intereses,4)
#Calcula el valor de giro
Valor_Giro=round((Precio_Sucio/100.)*Nominal,2)
#Calcula las mismas cantidades, pero para el futuro
Dias2,Pago_Anterior2,Pago_Siguiente2,Precio_Sucio2,Intereses2,Precio_Limpio2,Valor_Giro2,Duracion2,Hoy2=Calcular2(Bono,Tasa_Venta,Futuro,Nominal,Hoy)
#Organiza los datos para imprimirlos como un dataframe
index=["Fecha de Liquidación","Días al vencimiento","Vencimiento","Pago Anterior",
"Pago Siguiente","Cupon %","Precio Sucio","Intereses",
"Precio Limpio","Nominal","Valor Giro","Duración"]
test2=[[Hoy.strftime('%Y-%m-%d'),Hoy2.strftime('%Y-%m-%d')],[Dias,Dias2],
[Vencimiento.strftime('%Y-%m-%d'),Vencimiento.strftime('%Y-%m-%d')],
[Pago_Anterior.strftime('%Y-%m-%d'),Pago_Anterior2.strftime('%Y-%m-%d')],
[Pago_Siguiente.strftime('%Y-%m-%d'),Pago_Siguiente2.strftime('%Y-%m-%d')],
[trunc(Cupon*100,3),trunc(Cupon*100,3)],
[trunc(Precio_Sucio),trunc(Precio_Sucio2)],
[Intereses/100.,trunc(Intereses2/100.,6)],
[Precio_Limpio,Precio_Limpio2],
[Nominal,Nominal],
[Valor_Giro,Valor_Giro2],
[Duracion,Duracion2]]
#Imprime los datos
pd.options.display.float_format = '{:,}'.format
data2=pd.DataFrame(test2,columns=['Compra','Venta'],index=index)
display(data2)
#Crea el link para descargarlos
a=create_download_link(data2, filename = "Precio_IPC.csv",title = "Descargar datos")
display(a)
#Hace el analisis de la parte de "A plazo"
n=days(Hoy,Hoy2)/365.
#Se calculan la diferencia de giro y el costo dinero (Igual que en Excel)
Costo_dinero=round(Valor_Giro*((1.+tasaFondeo)**(n)-1.),2)
Diferencia_Giro=round(Valor_Giro2-Valor_Giro,2)
#Calcula el precio sucio con una tasa 0.01% más grande para el DVO1
Precio_Limpio3=PLimpio(Vencimiento,Hoy,Cupon,Tasa+0.0001)
Intereses3=round(interests(Cupon,Hoy,Vencimiento)/100.,6)
Precio_Sucio3=Precio_Limpio3+Intereses3*100
Valor_Giro3=(Precio_Sucio3/100.)*Nominal
DVO1=round(Valor_Giro-Valor_Giro3,2)
#Se calculan el precio y tasa equivalentes
PrecioFEq=0
TasaFEq=0
Ret_sin_Cost=0
ValorFuturo=0.
if((Hoy-Pago_Siguiente)/np.timedelta64(1,'D')<0 and (Hoy2-Pago_Siguiente)/np.timedelta64(1,'D')>0):
ValorFuturo=Cupon*Nominal*(1+Reinversion/100)**(days(Hoy2,Pago_Siguiente)/365.)
if Futuro>0:
Dias=days(Hoy,Hoy2)
Ret_sin_Cost=(((ValorFuturo+Valor_Giro2)/Valor_Giro)**(365/Dias)-1)*100
PrecioFEq=(Valor_Giro+Costo_dinero-ValorFuturo)*100/Nominal-trunc(interests(Cupon,Hoy2,Vencimiento,'C'),8)
TasaFEq=100*round(Yield(Vencimiento,Hoy2,Cupon,PrecioFEq),5)
Ret_sin_Cost=round(Ret_sin_Cost,2)
PrecioFEq=round(PrecioFEq,3)
#Se imprime el resumen
PyG=round(Diferencia_Giro-Costo_dinero+ValorFuturo,2)
index=['Costo Dinero','Diferencia de Giro','P&G','Retorno sin costos','DVO1','Precio F Eq.','Tasa F Eq.','Valor Futuro']
Values=[round(Costo_dinero,2),
round(Diferencia_Giro,2),
round(PyG,2),
round(Ret_sin_Cost,3),
round(DVO1,3),
round(PrecioFEq,3),
round(TasaFEq,3),
round(ValorFuturo,3)]
pd.options.display.float_format = '{:,}'.format
data2=pd.DataFrame(Values,columns=[''],index=index)
display(data2)
# Genera la parte interactiva
widgets.interact(Calcular_Precio_IPC,Bono=Nombre_IPC,
Tasa_Compra=Tasa_Compra_IPC,
Tasa_Venta=Tasa_Venta_IPC,
T=T_IPC,Futuro=Futuros_IPC,
Nominal=Nominal_IPC,
tasaFondeo=Tasa_Fondeo_IPC,
Reinversion=Reinversion_IPC);
# nbi:right
# nbi:hide_in
def In4(Bono,Limpio,Futuro,Nominal,Hoy):
index=list(df['Especie']).index(Bono)
Emision=df['Emision'][index]
Vencimiento=df['Vencimiento'][index]
Cupon=float(df['Cupon'][index][:-1])/100.
Valor_Nominal=100000
#pd.Timestamp('2019-03-08')#
Hoy=Hoy+datetime.timedelta(days=Futuro)
Tasa=round(Yield(Vencimiento,Hoy,Cupon,Limpio),5)
Duracion=Duration(Hoy,Vencimiento,Cupon,Tasa)
Pago_Anterior=prev_pay(Hoy,Vencimiento)
Pago_Siguiente=next_pay(Hoy,Vencimiento)
Intereses=interests(Cupon,Hoy,Vencimiento,'C')/100.
Precio_Sucio=round(Limpio+Intereses*100,4)
Valor_Giro=(Precio_Sucio/Valor_Nominal)*Nominal*1000
Dias=Dias_Vto(Hoy,Vencimiento)
ret=[Dias,Pago_Anterior,Pago_Siguiente,Precio_Sucio,Intereses,Tasa,Valor_Giro,Duracion,Hoy]
return ret
def Calcular_Tasa_IPC(Bono,Precio_Compra,Precio_Venta,T,Futuro,Nominal,tasaFondeo,Reinversion):
index=list(df['Especie']).index(Bono)
Emision=df['Emision'][index]
Vencimiento=df['Vencimiento'][index]
Cupon=trunc(float(df['Cupon'][index][:-1])/100.,5)
Hoy=pd.to_datetime(date.today())
Hoy=Hoy+datetime.timedelta(days=T)
Tasa=round(Yield(Vencimiento,Hoy,Cupon,Precio_Compra),5)
tasaFondeo=tasaFondeo/100
Dias=Dias_Vto(Hoy,Vencimiento)
Duracion=Duration(Hoy,Vencimiento,Cupon,Tasa)
Pago_Anterior=prev_pay(Hoy,Vencimiento)
Pago_Siguiente=next_pay(Hoy,Vencimiento)
Intereses=interests(Cupon,Hoy,Vencimiento)
Precio_Sucio=round(Precio_Compra+Intereses,4)
Valor_Giro=round((Precio_Sucio/100.)*Nominal,2)
Dias2,Pago_Anterior2,Pago_Siguiente2,Precio_Sucio2,Intereses2,Tasa2,Valor_Giro2,Duracion2,Hoy2=In4(Bono,Precio_Venta,Futuro,Nominal,Hoy)
index=["Fecha de Liquidación","Días al vencimiento","Vencimiento","Pago Anterior",
"Pago Siguiente","Cupon %","Precio Sucio","Intereses",
"Tasa","Nominal","Valor Giro","Duración"]
Data_Compra=[[Hoy.strftime('%Y-%m-%d'),Hoy2.strftime('%Y-%m-%d')],[Dias,Dias2],
[Vencimiento.strftime('%Y-%m-%d'),Vencimiento.strftime('%Y-%m-%d')],
[Pago_Anterior.strftime('%Y-%m-%d'),Pago_Anterior2.strftime('%Y-%m-%d')],
[Pago_Siguiente.strftime('%Y-%m-%d'),Pago_Siguiente2.strftime('%Y-%m-%d')],
[trunc(Cupon*100),trunc(Cupon*100)],
[Precio_Sucio,Precio_Sucio2],
[trunc(Intereses,8),trunc(Intereses2,8)],
[round(Tasa*100,4),round(Tasa2*100,4)],
[Nominal,Nominal],
[round(Valor_Giro,0),round(Valor_Giro2,0)],
[Duracion,Duracion2]]
pd.options.display.float_format = '{:,}'.format
DataF_Compra=pd.DataFrame(Data_Compra,columns=['Compra','Venta'],index=index)
display(DataF_Compra)
a=create_download_link(DataF_Compra, filename = "Tasa_IPC.csv",title = "Descargar datos")
display(a)
n=days(Hoy,Hoy2)/365.
Costo_dinero=round(Valor_Giro*((1.+tasaFondeo)**(n)-1.),2)
Diferencia_Giro=round(Valor_Giro2-Valor_Giro,2)
Precio_Limpio3=PLimpio(Vencimiento,Hoy,Cupon,Tasa+0.0001)
Intereses3=round(interests(Cupon,Hoy,Vencimiento)/100.,6)
Precio_Sucio3=Precio_Limpio3+Intereses3*100
Valor_Giro3=(Precio_Sucio3/100.)*Nominal
DVO1=round(Valor_Giro-Valor_Giro3,2)
PrecioFEq=0
TasaFEq=0
Ret_sin_Cost=0
ValorFuturo=0.
if((Hoy-Pago_Siguiente)/np.timedelta64(1,'D')<0 and (Hoy2-Pago_Siguiente)/np.timedelta64(1,'D')>0):
ValorFuturo=Cupon*Nominal*(1+Reinversion/100)**(days(Hoy2,Pago_Siguiente)/365.)
if Futuro>0:
Dias=days(Hoy,Hoy2)
Ret_sin_Cost=((Valor_Giro2/Valor_Giro)**(365/Dias)-1)*100
PrecioFEq=(Valor_Giro+Costo_dinero-ValorFuturo)*100/Nominal-trunc(interests(Cupon,Hoy2,Vencimiento,'C'),8)
TasaFEq=round(100*Yield(Vencimiento,Hoy2,Cupon,PrecioFEq),3)
Ret_sin_Cost=round(Ret_sin_Cost,2)
PrecioFEq=round(PrecioFEq,3)
PyG=round(Diferencia_Giro-Costo_dinero+ValorFuturo,2)
index=['Costo Dinero','Diferencia de Giro','P&G','Retorno sin costos','DVO1','Precio F Eq.','Tasa F Eq.','Valor Futuro']
Values=[round(Costo_dinero,2),
round(Diferencia_Giro,2),
round(PyG,2),
round(Ret_sin_Cost,3),
round(DVO1,3),
round(PrecioFEq,3),
round(TasaFEq,3),
round(ValorFuturo,3)]
pd.options.display.float_format = '{:,}'.format
Plazo=pd.DataFrame(Values,columns=[''],index=index)
display(Plazo)
widgets.interact(Calcular_Tasa_IPC,Bono=Nombre_IPC,
Precio_Compra=Precio_Compra_IPC,
Precio_Venta=Precio_Venta_IPC,
T=T_IPC,Futuro=Futuros_IPC,
Nominal=Nominal_IPC,
tasaFondeo=Tasa_Fondeo_IPC,
Reinversion=Reinversion_IPC);
# nbi:hide_in
df2=pd.read_csv('https://raw.githubusercontent.com/jmsevillam/Calculadoras/master/ESPECIEUVR.csv',';',parse_dates=True)
df3=pd.read_csv('https://raw.githubusercontent.com/jmsevillam/Calculadoras/master/UVR.csv',';',parse_dates=True)
df2['Emision']=pd.to_datetime(df2['Emision'], format='%d/%m/%Y')
df2['Vencimiento']=pd.to_datetime(df2['Vencimiento'], format='%d/%m/%Y')
df3['fecha']=pd.to_datetime(df3['fecha'], format='%d/%m/%Y')
Nombre_UVR=widgets.Dropdown(
options=list(df2['Especie']),
style =style,
layout=Layout,
description='Bono:',
disabled=False,
)
# nbi:left
# nbi:hide_in
def last_cup(Hoy,Vencimiento):
Vencimiento2=Vencimiento.replace(year=Hoy.year)
if (Vencimiento2-Vencimiento).days>0:
Vencimiento2=Vencimiento.replace(year=Vencimiento2.year-1)
return Vencimiento2
def Calcular6(Bono,Tasa,Futuro,Nominal,Hoy,UVR2):
Tasa=Tasa/100.
index=list(df2['Especie']).index(Bono)
#print(df.iloc[index])
Emision=df2['Emision'][index]
Vencimiento=df2['Vencimiento'][index]
Cupon=float(df2['Cupon'][index][:-1])/100.
Valor_Nominal=100000
#Hoy=pd.to_datetime(date.today())#pd.Timestamp('2019-03-08')#
Hoy=Hoy+datetime.timedelta(days=Futuro)
Dias=Dias_Vto(Hoy,Vencimiento)
Duracion=Duration(Hoy,Vencimiento,Cupon,Tasa)
Precio_Limpio=PLimpio(Vencimiento,Hoy,Cupon,Tasa)
Pago_Anterior=prev_pay(Hoy,Vencimiento)
Pago_Siguiente=next_pay(Hoy,Vencimiento)
Intereses=round(interests(Cupon,Hoy,Vencimiento)/100.,6)
Precio_Sucio=Precio_Limpio+Intereses*100
cc=round(days(last_cup(Hoy,Vencimiento),Hoy)*Cupon/365.,6)
UVR=UVR2
if UVR==0:
UVR=float(df3['valorUVR'][df3['fecha'][df3['fecha']==Hoy].index.tolist()[0]].replace(',','.'))
Valor_Giro=(Precio_Sucio/100.)*Nominal
Valor_Giro=UVR*Valor_Giro
ret=[Dias,Pago_Anterior,Pago_Siguiente,Precio_Sucio,Intereses,Precio_Limpio,Valor_Giro,Duracion,Hoy,UVR]
return ret
def Calcular_Precio_UVR(Bono,Tasa_Compra,Tasa_Venta,
T,Futuro,Nominal,tasaFondeo,
UVR_Compra,UVR_Venta,Reinversion):
#Lee los datos del bono, fechas y cupon
index=list(df2['Especie']).index(Bono)
Emision=df2['Emision'][index]
Vencimiento=df2['Vencimiento'][index]
Cupon=trunc(float(df2['Cupon'][index][:-1])/100.,5)
# Vuelve porcentajes de 0 a 1. i.e. 7% -> 0.07
Tasa=Tasa_Compra/100.
tasaFondeo=tasaFondeo/100
#Calcula la fecha de hoy, corrida con T+
Hoy=pd.to_datetime(date.today())
Hoy=Hoy+datetime.timedelta(days=T)
#Calcula los dias al vencimiento, duracion y precio limpio con las funciones definidas arriba
Dias=Dias_Vto(Hoy,Vencimiento)
Duracion=Duration(Hoy,Vencimiento,Cupon,Tasa)
Precio_Limpio=PLimpio(Vencimiento,Hoy,Cupon,Tasa)
#Calcula el pago anterior y siguiente
Pago_Anterior=prev_pay(Hoy,Vencimiento)
Pago_Siguiente=next_pay(Hoy,Vencimiento)
#Calcula los intereses y el precio Sucio
Intereses=interests(Cupon,Hoy,Vencimiento)
Precio_Sucio=round(Precio_Limpio+Intereses,4)
#Calcula el valor de giro en UVR
cc=round(days(last_cup(Hoy,Vencimiento),Hoy)*Cupon/365.,6)
UVR=UVR_Compra
if UVR==0:
UVR=float(df3['valorUVR'][df3['fecha'][df3['fecha']==Hoy].index.tolist()[0]].replace(',','.'))
Valor_Giro=(Precio_Sucio/100.)*Nominal
Valor_Giro=UVR*Valor_Giro
Dias2,Pago_Anterior2,Pago_Siguiente2,Precio_Sucio2,Intereses2,Precio_Limpio2,Valor_Giro2,Duracion2,Hoy2,UVR2=Calcular6(Bono,Tasa_Venta,Futuro,Nominal,Hoy,UVR_Venta)
index=["Fecha de Liquidación","Días al vencimiento","Vencimiento","Pago Anterior",
"Pago Siguiente","Cupon %","Precio Sucio","Intereses",
"Precio Limpio","Nominal","Valor Giro","UVR","Duración"]
test2=[[Hoy.strftime('%Y-%m-%d'),Hoy2.strftime('%Y-%m-%d')],[Dias,Dias2],
[Vencimiento.strftime('%Y-%m-%d'),Vencimiento.strftime('%Y-%m-%d')],
[Pago_Anterior.strftime('%Y-%m-%d'),Pago_Anterior2.strftime('%Y-%m-%d')],
[Pago_Siguiente.strftime('%Y-%m-%d'),Pago_Siguiente2.strftime('%Y-%m-%d')],
[trunc(Cupon*100,3),trunc(Cupon*100,3)],
[trunc(Precio_Sucio),trunc(Precio_Sucio2)],
[trunc(Intereses,8),trunc(Intereses2,8)],
[Precio_Limpio,Precio_Limpio2],
[Nominal,Nominal],
[round(Valor_Giro,0),round(Valor_Giro2,0)],
[UVR,UVR2],
[Duracion,Duracion2]]
pd.options.display.float_format = '{:,}'.format
data2=pd.DataFrame(test2,columns=['Compra','Venta'],index=index)
display(data2)
a=create_download_link(data2, filename = "Precio_UVR.csv",title = "Descargar datos")
display(a)
n=days(Hoy,Hoy2)/365.
Costo_dinero=round(Valor_Giro*((1.+tasaFondeo)**(n)-1.),2)
Diferencia_Giro=round(Valor_Giro2-Valor_Giro,2)
Precio_Limpio3=PLimpio(Vencimiento,Hoy,Cupon,Tasa+0.0001)
Precio_Sucio3=round(Precio_Limpio3+Intereses,4)
Valor_Giro3=UVR*(Precio_Sucio3/100.)*Nominal
DVO1=round(Valor_Giro3-Valor_Giro,2)
PrecioFEq=0
TasaFEq=0
Ret_sin_Cost=0
ValorFuturo=0.
if((Hoy-Pago_Siguiente)/np.timedelta64(1,'D')<0 and (Hoy2-Pago_Siguiente)/np.timedelta64(1,'D')>0):
ValorFuturo=Cupon*Nominal*(1+Reinversion/100)**(days(Hoy2,Pago_Siguiente)/365.)
if Futuro>0:
Dias=days(Hoy,Hoy2)
Ret_sin_Cost=((Valor_Giro2/Valor_Giro)**(365/Dias)-1)*100
PrecioFEq=(Valor_Giro+Costo_dinero-ValorFuturo)*100/Nominal-trunc(interests(Cupon,Hoy2,Vencimiento,'C'),8)
TasaFEq=round(100*Yield(Vencimiento,Hoy2,Cupon,PrecioFEq),3)
Ret_sin_Cost=round(Ret_sin_Cost,2)
PrecioFEq=round(PrecioFEq,3)
PyG=round(Diferencia_Giro-Costo_dinero+ValorFuturo,2)
index=['Costo Dinero','Diferencia de Giro','P&G','Retorno sin costos','DVO1','Precio F Eq.','Tasa F Eq.','Valor Futuro']
Values=[round(Costo_dinero,2),
round(Diferencia_Giro,2),
round(PyG,2),
round(Ret_sin_Cost,3),
round(DVO1,3),
round(PrecioFEq,3),
round(TasaFEq,3),
round(ValorFuturo,3)]
pd.options.display.float_format = '{:,}'.format
data2=pd.DataFrame(Values,columns=[''],index=index)
display(data2)
widgets.interact(Calcular_Precio_UVR,Bono=Nombre_UVR,
Tasa_Compra=Tasa_Compra_UVR,
Tasa_Venta=Tasa_Venta_UVR,
T=T_UVR,Futuro=Futuros_UVR,
Nominal=Nominal_UVR,
tasaFondeo=Tasa_Fondeo_UVR,UVR_Compra=UVR_Compra,UVR_Venta=UVR_Venta,Reinversion=Reinversion_UVR);
# nbi:right
# nbi:hide_in
def In6(Bono,Limpio,Futuro,Nominal,Hoy,UVR2):
index=list(df2['Especie']).index(Bono)
Emision=df2['Emision'][index]
Vencimiento=df2['Vencimiento'][index]
Cupon=float(df2['Cupon'][index][:-1])/100.
Valor_Nominal=100000
#pd.Timestamp('2019-03-08')#
Hoy=Hoy+datetime.timedelta(days=Futuro)
Tasa=round(Yield(Vencimiento,Hoy,Cupon,Limpio),6)
Duracion=Duration(Hoy,Vencimiento,Cupon,Tasa)
Pago_Anterior=prev_pay(Hoy,Vencimiento)
Pago_Siguiente=next_pay(Hoy,Vencimiento)
Intereses=interests(Cupon,Hoy,Vencimiento,'C')/100.
Precio_Sucio=round(Limpio+Intereses*100,4)
Dias=Dias_Vto(Hoy,Vencimiento)
cc=round(days(last_cup(Hoy,Vencimiento),Hoy)*Cupon/365.,6)
UVR=UVR2
if UVR==0:
UVR=float(df3['valorUVR'][df3['fecha'][df3['fecha']==Hoy].index.tolist()[0]].replace(',','.'))
Valor_Giro=(Precio_Sucio/Valor_Nominal)*Nominal*1000
Valor_Giro=UVR*Valor_Giro
ret=[Dias,Pago_Anterior,Pago_Siguiente,Precio_Sucio,Intereses,Tasa,Valor_Giro,Duracion,Hoy,UVR]
return ret
def Calcular_Tasa_UVR(Bono,Precio_Compra,Precio_Venta,T,Futuro,Nominal,tasaFondeo,UVR_Compra,UVR_Venta,Reinversion):
global res2,res
tasaFondeo/=100
index=list(df2['Especie']).index(Bono)
Emision=df2['Emision'][index]
Vencimiento=df2['Vencimiento'][index]
Cupon=round(float(df2['Cupon'][index][:-1])/100.,5)
Valor_Nominal=100000
Hoy=pd.to_datetime(date.today())
Hoy=Hoy+datetime.timedelta(days=T)
Tasa=round(Yield(Vencimiento,Hoy,Cupon,Precio_Compra),6)
Duracion=Duration(Hoy,Vencimiento,Cupon,Tasa)
Pago_Anterior=prev_pay(Hoy,Vencimiento)
Pago_Siguiente=next_pay(Hoy,Vencimiento)
Intereses=interests(Cupon,Hoy,Vencimiento,'C')/100.
Precio_Sucio=round(Precio_Compra+Intereses*100,4)
Dias=Dias_Vto(Hoy,Vencimiento)
cc=round(days(last_cup(Hoy,Vencimiento),Hoy)*Cupon/365.,6)
UVR=UVR_Compra
if UVR==0:
UVR=float(df3['valorUVR'][df3['fecha'][df3['fecha']==Hoy].index.tolist()[0]].replace(',','.'))
Valor_Giro=(Precio_Sucio/Valor_Nominal)*Nominal*1000
Valor_Giro=round(UVR*Valor_Giro,0)
Dias2,Pago_Anterior2,Pago_Siguiente2,Precio_Sucio2,Intereses2,Tasa2,Valor_Giro2,Duracion2,Hoy2,UVR2=In6(Bono,Precio_Venta,Futuro,Nominal,Hoy,UVR_Venta)
index=["Fecha de Liquidación","Días al vencimiento","Vencimiento","Pago Anterior",
"Pago Siguiente","Cupon %","Precio Sucio","Intereses","Tasa",
"Precio Limpio","Nominal","Valor Giro","UVR","Duración"]
test2=[[Hoy.strftime('%Y-%m-%d'),Hoy2.strftime('%Y-%m-%d')],[Dias,Dias2],
[Vencimiento.strftime('%Y-%m-%d'),Vencimiento.strftime('%Y-%m-%d')],
[Pago_Anterior.strftime('%Y-%m-%d'),Pago_Anterior2.strftime('%Y-%m-%d')],
[Pago_Siguiente.strftime('%Y-%m-%d'),Pago_Siguiente2.strftime('%Y-%m-%d')],
[trunc(Cupon*100,3),trunc(Cupon*100,3)],
[trunc(Precio_Sucio),trunc(Precio_Sucio2)],
[trunc(Intereses,8),trunc(Intereses2,8)],
[round(Tasa*100,3),round(Tasa2*100,3)],
[Precio_Compra,Precio_Venta],
[Nominal,Nominal],
[round(Valor_Giro,0),round(Valor_Giro2,0)],
[UVR,UVR2],
[Duracion,Duracion2]]
pd.options.display.float_format = '{:,}'.format
data2=pd.DataFrame(test2,columns=['Compra','Venta'],index=index)
#display(data)
display(data2)
a=create_download_link(data2, filename = "Tasa_UVR.csv",title = "Descargar datos")
display(a)
res=data2
n=days(Hoy,Hoy2)/365.
Costo_dinero=round(Valor_Giro*((1.+tasaFondeo)**(n)-1.),2)
Diferencia_Giro=round(Valor_Giro2-Valor_Giro,2)
Precio_Limpio3=PLimpio(Vencimiento,Hoy,Cupon,round(Tasa+0.0001,6))
Precio_Limpio3=PLimpio(Vencimiento,Hoy,Cupon,Tasa+0.0001)
Precio_Sucio3=round(Precio_Limpio3+Intereses,4)
Valor_Giro3=UVR*(Precio_Sucio3/100.)*Nominal
DVO1=round(Valor_Giro3-Valor_Giro,2)
Ret_sin_Cost=0
if Futuro>0:
Dias=days(Hoy,Hoy2)
Ret_sin_Cost=((Valor_Giro2/Valor_Giro)**(365/Dias)-1)*100
PrecioFEq=0
TasaFEq=0
Ret_sin_Cost=0
if Futuro>0:
Dias=days(Hoy,Hoy2)
Ret_sin_Cost=((Valor_Giro2/Valor_Giro)**(365/Dias)-1)*100
PrecioFEq=(Valor_Giro+Costo_dinero-ValorFuturo)*100/(Nominal*UVR2)-trunc(interests(Cupon,Hoy2,Vencimiento,'C'),8)
TasaFEq=round(100*Yield(Vencimiento,Hoy2,Cupon,PrecioFEq),5)
Ret_sin_Cost=round(Ret_sin_Cost,2)
PrecioFEq=round(PrecioFEq,3)
index=['Costo Dinero','Diferencia de Giro','P&G','Retorno sin costos','DVO1','Precio F Eq.','Tasa F Eq.']
Values=[Costo_dinero,Diferencia_Giro,Diferencia_Giro-Costo_dinero,Ret_sin_Cost,DVO1,PrecioFEq,TasaFEq]
pd.options.display.float_format = '{:,}'.format
data2=pd.DataFrame(Values,columns=[''],index=index)
display(data2)
widgets.interact(Calcular_Tasa_UVR,Bono=Nombre_UVR,
Precio_Compra=Precio_Compra_UVR,
Precio_Venta=Precio_Venta_UVR,
T=T_UVR,Futuro=Futuros_UVR,
Nominal=Nominal_UVR,
tasaFondeo=Tasa_Fondeo_UVR,
UVR_Compra=UVR_Compra,UVR_Venta=UVR_Venta,
Reinversion=Reinversion_UVR);
# nbi:hide_in
import ipywidgets as widgets
tab_contents = ['P0', 'P1']
a = widgets.IntSlider(description='a')
b = widgets.IntSlider(description='b')
c = widgets.IntSlider(description='c')
def f(a, b, c):
print('{}*{}*{}={}'.format(a, b, c, a*b*c))
out = widgets.interactive_output(f, {'a': a, 'b': b, 'c': c})
test1=widgets.HBox([widgets.VBox([a, b, c]), out])
test2=widgets.IntSlider(
value=2,
min=0,
max=10,
step=1,
description='Test:',
disabled=False,
continuous_update=False,
orientation='horizontal',
readout=True,
readout_format='d'
)
children = [test1,test2]
tab = widgets.Tab()
tab.children = children
for i in range(len(children)):
tab.set_title(i, 'Option '+str(i))
display(tab)