pip install numpy-financial import numpy_financial as npf # DATOS DEL BONO nominal = 1000 cupon = 0.1 n = 5 # años r = 0.08 # FLUJOS DE CAJA flujos = [0] for i in range(1, n+1): if i < n: flujos.append(cupon * nominal) elif i == n: flujos.append(cupon * nominal + nominal) print("Flujos de caja: ", flujos) # PRECIO DEL BONO precio = 0 for i in range(1, n+1): precio += flujos[i] / (1+r)**i print("Precio del bono:", precio) bono = flujos[:] bono[0] = -precio # COMPROBACIÓN TIR = r tir = npf.irr(bono) print(f"La TIR del bono es: {tir:.5%}") # Internal rate of return import numpy_financial as npf # DATOS nominal = 1000 cupon = 0.1 n = 5 # años r01 = 0.02 r02 = 0.04 r03 = 0.06 r04 = 0.08 r05 = 0.10 etti = [r01,r02,r03,r04,r05] # FLUJOS DE CAJA flujos = [0] for i in range(1, n+1): if i < n: flujos.append(cupon * nominal) elif i == n: flujos.append(cupon * nominal + nominal) print("Flujos de caja: ", flujos) # PRECIO DEL BONO CON LA ETTI precio = 0 for i in range(1, n+1): precio += flujos[i] / (1+etti[i-1])**i print("Precio del bono:", precio) bono = flujos[:] bono[0] = -precio # CALCULAR LA TIR DEL BONO TIR = r tir = npf.irr(bono) print(f"La TIR del bono es: {tir:.6%}") # Internal rate of return import numpy_financial as npf # DATOS BONO A nominalA = 10_000 cuponA = 0.02 n = 5 # años, para A y B # DATOS BONO B nominalB = 4_000 cuponB = 0.25 # ETTI etti =[.02,.04,.06,.08,.10] # FLUJOS DE CAJA DE LOS BONOS def flujos(nominal, cupon, n): cf = [0] # array con el cash flow for i in range(1, n+1): if i < n: cf.append(cupon * nominal) elif i == n: cf.append(cupon * nominal + nominal) return cf # Flujos de caja de los Bonos A y B flujosA = flujos(nominalA, cuponA, n) flujosB = flujos(nominalB, cuponB, n) # PRECIO DE UN BONO CON LA ETTI def precio_etti(flujos, etti): precio = 0 for i in range(1, n+1): precio += flujos[i] * (1+etti[i-1])**-i return precio # Precios de los Bonos A y B precioA = precio_etti(flujosA, etti) precioB = precio_etti(flujosB, etti) print(f"El precio del bono A es {precioA}") print(f"El precio del bono B es {precioB}") # Flujos de caja de los bonos A y B bonoA = flujosA[:] bonoA[0] = -precioA bonoB = flujosB[:] bonoB[0] = -precioB # CREACIÓN DEL BONO SINTÉTICO C # m es el número de bonos que se han de comprar o vender de uno de los bonos m = max(cuponA*nominalA, cuponB*nominalB) / min(cuponB*nominalB, cuponA*nominalA) # con los datos de ejemplo m = 1000 / 200 = 5 # Flujos de caja del bono C bonoC = [0]*(n+1) for i in range(0, n+1): bonoC[i] = m * bonoA[i] - bonoB[i] print(f"Flujos de caja del bono C: {bonoC}") # Calcular la TIR de los bonos tirA = npf.irr(bonoA) tirB = npf.irr(bonoB) tirC = npf.irr(bonoC) print(f"La TIR del bono A es: {tirA:.6%}") print(f"La TIR del bono B es: {tirB:.6%}") print(f"La TIR del bono C es: {tirC:.6%}") import numpy_financial as npf # DATOS nominal = 10_000 cupon = .1 n = 10 # años precio = 10_000 # Flujos de caja del bono cf = [0]*(n+1) for i in range(1,n+1): cf[i] = cupon * nominal cf[n] += nominal cf[0] = -precio print(f"La TIR del bono es: {npf.irr(cf):.2%}") # Montante de la Reinversión def montante(cf,r): m = 0 # montante for i in range(1, n+1): m += cf[i]*(1+r)**(n-i) return m tasas_reinversion = [0,.1,.2] for t in tasas_reinversion: m = montante(cf,t) print() print(f"El montante reinvirtiendo al tanto del {t:.0%} es {m:,.2f} €") print(f"La rentabilidad del inversor reinvirtiendo al tanto {t:.0%} es {(m/precio)**(1/n)-1:.2%}") import numpy_financial as npf # DATOS c = 1_000_000 # capital inicial r = .1 # rentabilidad 10% anual ma = c*(1+r) # Montante A: el montante de la inversión A es 1.100.000 p = .01 # probabilidad de que suceda una de las ramas de la inverión B q = 1-p # probabilidad complementaria de la otra rama de B, se cumple que p+q=1 # Cálculo de mb2 # El montante de la inversión B es mb y tiene dos componentes mb1 + mb2 = mb def mb_2(ma,p,mb1): return (ma - p * mb1) / q # Resultados print("CASO 1") mb1 = 500_000 # primer caso que nos piden mb2 = mb_2(ma,p,mb1) print(f"Si el montante alcanzado con mb1 es {mb1:,} entonces el montante mb2 es {mb2:,.2f}") print(f"La TIR de la inversión B1 es: {npf.irr([-c,mb1]):.1%}") print(f"La TIR de la inversión B2 es: {npf.irr([-c,mb2]):.2%}") print(f"La TIR de la inversión A es: {npf.irr([-c, ma]):.1%}") # comprobar que ambas TIR son del 10% print(f"La TIR de la inversión B es: {npf.irr([-c, p*mb1+q*mb2]):.1%}") # comprobar que ambas TIR son del 10% print() print("CASO 2") mb1 = 0 # segundo caso que nos piden mb2 = mb_2(ma,p,mb1) print(f"Si el montante alcanzado con mb1 es {mb1} entonces el montante mb2 es {mb2:,.2f}") print(f"La TIR de la inversión B1 es: {npf.irr([-c,mb1]):.1%}") print(f"La TIR de la inversión B2 es: {npf.irr([-c,mb2]):.2%}") print(f"La TIR de la inversión A es: {npf.irr([-c, ma]):.1%}") # comprobar que ambas TIR son del 10% print(f"La TIR de la inversión B es: {npf.irr([-c, p*mb1+q*mb2]):.1%}") # comprobar que ambas TIR son del 10% import numpy_financial as npf from random import randint, seed seed() # DATOS tirA = .1 cuponB = 4_400 nominalB = 10_000 precioB = 14_000 nominalA = randint(1,10000) print(f"El nominal elegido para el bono A es {nominalA}") # FLUJOS DE CAJA bonos A y B bonoB = [-precioB, cuponB, cuponB+nominalB] bonoA = [-nominalA/(1+tirA), nominalA, 0] # añadimos un flujo 0 en t=2 por comodidad, para luego restar flujos m = bonoB[1]/bonoA[1] print(f"El multiplicador m es {m}") bonoC = [bonoB[0]-m*bonoA[0], bonoB[1]-m*bonoA[1], bonoB[2]-m*bonoA[2]] print("Bono C: ", bonoC) # TIR del bono C tirC = npf.irr(bonoC) print(f"La TIR del bono C es: {tirC:.6%}") # Creación de la ETTI etti = [tirA, tirC] # la tirC si pertenece a la ETTI por ser un bono cupón cero, pero la tirB no pertenece # COMPROBAR PRECIOS CON LA ETTI def precio_etti(flujos, etti): precio = 0 for i in range(1, len(flujos)): precio += flujos[i] * (1+etti[i-1])**-i return precio # Precios de los Bonos A, B y C precioA = precio_etti(bonoA, etti) precioB = precio_etti(bonoB, etti) precioC = precio_etti(bonoC, etti) print(f"La diferencia de precios en el bono A es {precioA+bonoA[0]}") print(f"La diferencia de precios en el bono B es {precioB+bonoB[0]}") print(f"La diferencia de precios en el bono C es {precioC+bonoC[0]}") import numpy_financial as npf ##### FASE 1 ##### # Flujos de caja de los bonos bonoA = [0,1000,0,0] # inicialmente el flujo de caja inicial es cero bonoB = [0,90,1090,0] bonoC = [0,500,500,1500] # Calcular el precio de los bonos dada la ETTI etti = [.1, .2, .3] def precio_etti(flujos, etti): precio = 0 for i in range(1, len(flujos)): precio += flujos[i] * (1+etti[i-1])**-i return precio precioA = precio_etti(bonoA, etti) precioB = precio_etti(bonoB, etti) precioC = precio_etti(bonoC, etti) print(f"El precio del bono A es {precioA:,.2f} €") print(f"El precio del bono B es {precioB:,.2f} €") print(f"El precio del bono C es {precioC:,.2f} €") print() # Calcular la TIR de los bonos bonoA[0] = -precioA bonoB[0] = -precioB bonoC[0] = -precioC tirA = npf.irr(bonoA) tirB = npf.irr(bonoB) tirC = npf.irr(bonoC) print(f"La TIR del bono A es: {tirA:.2%}") print(f"La TIR del bono B es: {tirB:.2%}") print(f"La TIR del bono C es: {tirC:.2%}") print() ##### FASE 2 ##### etti_calculada = [0,0,0] # inicializamos el array etti_calculada[0] = tirA # la ETTI del año 1 es la TIR del bono A por ser un bono cupón cero a un año def calcula_etti(bono, etti_calculada): n = [i for i, e in enumerate(bono) if e != 0][-1] ultimo_flujo = bono[n] precio = -bono[0] fcid = 0 # inicializamos los flujos de caja intermedios descontados for t in range(1,n): # recorre los flujos de caja intermedios fcid += bono[t] / (1+etti[t-1])**t return (ultimo_flujo / (precio - fcid))**(1/n)-1 r02 = calcula_etti(bonoB, etti_calculada) # calculamos r02 conocido el bono B y r01 etti_calculada[1] = r02 r03 = calcula_etti(bonoC, etti_calculada) # calculamos r03 conocido el bono C, r01 y r02 etti_calculada[2] = r03 # Imprime la etti_calculada for i in range(len(etti_calculada)): print(f"La ETTI del año {i+1} es {etti_calculada[i]:.2%}") # Para calcular n bonoA = [0,1000,0,0] # n = 1, vector = [1] bonoB = [0,90,1090,0] # n = 2, vector = [1, 2] bonoC = [0,500,500,1500] # n = 3, vector = [1, 2, 3] bono = bonoA vector = [i for i, e in enumerate(bono) if e != 0] # list comprhension print(vector[-1]) precioA = 100 precioB = 160 n = 1 # duración en años Co = precioA # Capital inicial prestado r = .1 # tipo de interés anual Cn = Co*(1+r)**n flujos_caja = [Co-precioA, round(precioB-Cn,8)] print(f"Los flujos de caja de la operación en los diferentes años son: {flujos_caja}") pip install numpy-financial import numpy_financial as npf import numpy as np # la librería numpy nos permitirá trabajar con ndarrays # DATOS bonoA = [0, 10, 1010] bonoB = [0, 200, 1200] etti = [.05, .2] # PRECIO DE UN BONO CON LA ETTI def precio_etti(flujos, etti): precio = 0 for i in range(1, len(bonoA)): precio += flujos[i] * (1+etti[i-1])**-i return precio # Precios de los Bonos A y B precioA = precio_etti(bonoA, etti) precioB = precio_etti(bonoB, etti) print(f"El precio del bono A es {precioA}") print(f"El precio del bono B es {precioB}") # Flujos de caja de los bonos A y B bonoA[0] = -precioA bonoB[0] = -precioB # Calcular la TIR de los bonos tirA = npf.irr(bonoA) tirB = npf.irr(bonoB) print(f"La TIR del bono A es: {tirA:.4%}") print(f"La TIR del bono B es: {tirB:.4%}") # Calcular la duración de Macaulay def duracion(bono): tir =npf.irr(bono) precio = 0 numerador = 0 for i in range(1, len(bonoA)): precio += bono[i] * (1+tir)**-i numerador += i * bono[i] * (1+tir)**-i return numerador / precio print(f"La duration del bono A es {duracion(bonoA)}") print(f"La duration del bono B es {duracion(bonoB)}") # Nuevo precio del bono A en el mercado desequilibrado precioAprima = npf.npv(tirB, bonoA) + precioA # sumamos el antiguo precio de A ya que va en la posición [0] del array con signo negativo print(f"El nuevo precio del bono A en el mercado desequilibrado es {precioAprima}") bonoAprima =[-precioAprima, bonoA[1], bonoA[2]] # Bono C = B - 20A' # bonoC = bonoB - 20 * bonoAprima # esto da error, necesitamos trabajar con ndarrays bonoB_arr = np.array(bonoB) bonoAprima_arr =np.array(bonoAprima) bonoC_arr = bonoB_arr - 20 * bonoAprima_arr print(f"El bono C es {bonoC_arr}") # Ajustamos con un préstamo prestamo = np.array([bonoC_arr[2] / (1+etti[1])**2, 0, -bonoC_arr[2]]) print(f"El préstamo es {prestamo}") # Cartera Total total = bonoC_arr + prestamo print(f"Cartera resultante del arbitraje {total}") import numpy_financial as npf import numpy as np ############## MÉTODO 1 ############## # DATOS bonoA = np.array([-933, 1000, 0]) bonoB = np.array([-98, 7, 107]) # ver los flujos de caja del archivo Excel # Bono C bonoC = np.array([0,0,0]) # inicializamos el ndarray bonoC = bonoA[0]*bonoB - bonoB[0]*bonoA print(f"Bono C: {bonoC}") # Forward r12 r12 = npf.irr(bonoC) print(f"MÉTODO 1: el forward r12 es {r12:.4%}") ############## MÉTODO 2 ############## # Bono D bonoD = np.array([0,0,0]) # inicializamos el ndarray bonoD = bonoA[1]*bonoB - bonoB[1]*bonoA print(f"Bono D: {bonoD}") # ETTI a dos años r02 r02 = npf.irr(bonoD) print(f"La ETTI a dos años es r02 = {r02:.4%}") # TIR del Bono A (r01) r01 = npf.irr(bonoA) print(f"La TIR del bono A es r01 = {r01:.4%}") ############## COMPROBACIÓN ############## # Comprobación r12 = r12_bis r12_bis = (1+r02)**2 / (1+r01) -1 print(f"MÉTODO 2: el forward r12 es {r12_bis:.4%}") print(f"La diferencia de r12 por ambos métodos es {abs(r12 - r12_bis)}") import numpy_financial as npf import numpy as np # DATOS bonoA = np.array([-100, 110, 0, 0]) bonoB = np.array([-500, 0, 500*1.09**2, 0]) # la TIR del bono B es del 9% bonoC = np.array([-1000/1.08**3, 0, 0, 1000]) print(f"Bono A: {bonoA}") print(f"Bono B: {bonoB}") print(f"Bono C: {bonoC}") ############## MÉTODO 1 ############## bonoD = np.ndarray([0,0,0,0]) bonoD = -bonoC[0] * bonoB + bonoB[0] * bonoC print(f"Bono D: {bonoD}") tirD = npf.irr(bonoD) print(f"Método 1: el forward r23 es {tirD:.5%}") ############## MÉTODO 2 ############## r23 = (1+0.08)**3 / (1+0.09)**2 -1 print(f"Método 2: el forward r23 es {r23:.5%}")