image

# 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)

Calculadoras (Beta)

Mauricio Sevilla.

email: jsevilla@credicorpcapital.com

17.04.2019-02


Tasa Fija

Para ver la documentación link,link2

# 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,
)

Cálculo Precio

Cálculo Tasa

# 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);

UVR

# 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,
) 

Cálculo Precio

Cálculo Tasa

# 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)