Representación de flujos de caja y tasas de interés

Notas de clase sobre ingeniería economica avanzada usando Python

Juan David Velásquez Henao
jdvelasq@unal.edu.co
Universidad Nacional de Colombia, Sede Medellín
Facultad de Minas
Medellín, Colombia

Software utilizado

Este es un documento interactivo escrito como un notebook de Jupyter , en el cual se presenta un tutorial sobre finanzas corporativas usando Python. Los notebooks de Jupyter permiten incoporar simultáneamente código, texto, gráficos y ecuaciones. El código presentado en este notebook puede ejecutarse en los sistemas operativos Linux y OS X.

Haga click aquí para obtener instrucciones detalladas sobre como instalar Jupyter en Windows y Mac OS X.

Descargue la última versión de este documento a su disco duro; luego, carguelo y ejecutelo en línea en Try Jupyter!

Contenido

>

Bibliografía

  • [1] SAS/ETS 14.1 User's Guide, 2015.
  • [2] hp 12c platinum financial calculator. User's guide.
  • [3] HP Business Consultant II Owner's manual.
  • [4] C.S. Park and G.P. Sharp-Bette. Advanced Engineering Economics. John Wiley & Sons, Inc., 1990.

In [1]:
import cashflows as cf

Conversión de tasas de interés

 Interés anticipado e interés vencido

Interés vencido: se paga al final del periodo.

$$F=P(1+r)$$

Interés anticipado: se paga al inicio del periodo (antes de su causación). En este caso surge una paradoja, que el interés se puede reinvertir a la misma tasa de interés (anticipadamente):

$$F = P + Pr_* + Pr_*^2 + ...$$

La suma infinita anterior puede reescribirse como:

$$F=P \frac{1}{1 - r_*}$$

Igualando las dos ecuaciones anteriores:

$$\frac{1}{1 - r_*}=1+r ~,~~ r=\frac{r_*}{1 - r_*} ~,~~ r_*=\frac{r}{1 + r}$$

Interés efectivo anual:

$$r_a=\left[1+\left (\frac{r_*}{1-r_*}\right)\right]^n-1$$

cashflow tiene las funciones nom2eff() y eff2nom() para realizar las conversiones entre nominal (anticipado y vencido) y efectivo respectivamente.

Ejemplo.-- Se solicita un prestamo a un año con un interés anticipado del 20%. ¿Determine el interés efectivo pagado por el dinero?


In [2]:
0.2 / (1 - 0.2)


Out[2]:
0.25

Ejemplo.-- Si se desea obtener una tasa efectiva anual del 36%, ¿cuánto se deberá cobrar en forma anticipada anual para obenerla?


In [3]:
0.36 / (1 + 0.36)


Out[3]:
0.2647058823529412

Interés nominal e interés efectivo

Interés nominal (r): expresado sobre una base anual para un número M de periodos de pago en el año.

Interés efectivo por periodo de pago ($i$): representa el interés real para cada periodo de pago en el año.

Interés efectivo anual ($i_a$): interés real para un periodo único de pago de un año.

$$ i= \frac{r}{M},$$


$$i_\alpha = \left( \displaystyle 1 + \frac{r}{M}\right)^M - 1 $$

Ejemplo.-- Se está considerando abrir una cuenta de ahorros en uno de tres bancos. Cuál banco tienen la tasa de interés más favorable?

  • Banco #1: 6.72% anual, compuesto semestralmente
  • Banco #1: 6.70% anual, compuesto trimestralmente.
  • Banco #2: 6.65% anual, compuesto mensualmente.

In [4]:
cf.iconv(nrate = 6.72, pyr =  2)  ## Banco 1


Out[4]:
(6.8328960000000105, 3.36)

In [5]:
cf.iconv(nrate = 6.70, pyr =  4)  ## Banco 2 -- mejor opción


Out[5]:
(6.8702251402816605, 1.675)

In [6]:
cf.iconv(nrate = 6.65, pyr = 12)  ## Banco 3


Out[6]:
(6.85647762811652, 0.5541666666666667)

In [7]:
## Otra forma
cf.iconv(nrate = [6.72, 6.79, 6.65], pyr = [2, 4, 12])


Out[7]:
([6.8328960000000105, 6.964855220821997, 6.85647762811652],
 [3.36, 1.6975, 0.5541666666666667])

Ejemplo.-- Convierta una tasa del 12% anual compuesto semestralmente a anual compuesto mensualmente.


In [8]:
erate, _ = cf.iconv(nrate = 12.0, pyr = 2) ## efectiva por año 
erate


Out[8]:
12.360000000000015

In [9]:
nrate, _ = cf.iconv(erate = erate, pyr = 12)       ## nominal compuesta mensualmente
nrate


Out[9]:
11.710553015030811

Ejemplo.-- Sea un interés nominal del 12% capitalizado mensualmente. Calcule:

  • Tasa efectiva mensual
  • Tasa efectiva trimestral
  • Tasa efectiva anual


In [10]:
## tasa efectiva mensual
0.12 / 12


Out[10]:
0.01

In [11]:
## tasa efectiva trimestral
erate, _ = cf.iconv(nrate = 3 * 0.12 / 12, pyr = 3)
erate


Out[11]:
0.030003000099987354

In [12]:
## tasa efectiva anual
erate, _ = cf.iconv(nrate = 12.0, pyr = 12)
erate


Out[12]:
12.682503013196978

Nomenclatura


Ejercicios

Ejercicio.-- Cuál es la tasa efectiva anual equivalente a 15% N.A.M.V. (nominal anual mes vencido)?


In [ ]:

Ejercicio.-- Cuál es la tasa efectiva anual equivalente a 23% N.A.T.A. (nominal anual trimestre anticipado)?


In [ ]:

Ejercicio.-- Sea un interés nominal del 39.29% capitalizado mensualmente a cuánto equivale en términos semestrales? (R/ 6.15%)


In [ ]:

Ejercicio.-- ¿Cuál es el valor futuro de \$ 609 dentro de 2 años a una tasa del 2% NATV?


In [ ]:

Ejercicio.-- ¿Cuál es el valor presente de un pago único de \$ 890 recibido dentro de 6 años a una tasa de 2.7% NATA?


In [ ]:

Ejercicio.-- ¿Qué cantidad de dinero se poseerá después de prestar \$ 2300 al 27% NAMA durante 3 años?


In [ ]:

Ejercicio.-- ¿Cuál es la tasa efectiva semestral equivalente al 14% NMTA?


In [ ]:

Ejercicio.-- ¿Cuánto dinero mensual se debe empezar a abonar hoy si se desea reunir \$ 28700 al final de 5 años y los ahorros rentan el 16%?


In [ ]:

Ejercicio.-- Se decide ahorrar mensualmente \$ 900 los cuales depositará al principio de cada mes en una entidad financiera que paga un interés del 30%. ¿Cuánto habrá acumulado al cabo de 2 años?


In [ ]:


Representación de tasas de interés usando cashflow

En la modelación financiera es común tener que representar tasas de interés que cambian en el tiempo. La librería cashflow permite realizar esta tarea. En la tabla que se presenta a continuación, la columna n indica para que periodos se aplica el valor correspondiente de la tasa (columna rate). Por definición, la tasa para el periodo 0 siempre es 0.


In [13]:
cf.nominal_rate(const_value=10, start=(2000, 0), nper=8, pyr=4)


Out[13]:
      Qtr0  Qtr1  Qtr2  Qtr3
2000 10.00 10.00 10.00 10.00
2001 10.00 10.00 10.00 10.00

In [14]:
cf.nominal_rate(const_value=10, start=(2000, 0), nper=8, pyr=6)


Out[14]:
Time Series:
Start = (2000, 0)
End = (2001, 1)
pyr = 6
Data = (2000, 0)-(2001, 1) [8] 10.00 

In [15]:
spec = ((2000, 3), 10)
cf.nominal_rate(const_value=1, start=(2000, 0), nper=8, pyr=4, spec=spec)


Out[15]:
      Qtr0  Qtr1  Qtr2  Qtr3
2000  1.00  1.00  1.00 10.00
2001 10.00 10.00 10.00 10.00

In [16]:
spec = [(3, 10), (6, 20)]
cf.nominal_rate(const_value=1, start=(2000, 0), nper=8, pyr=4, spec=spec)


Out[16]:
      Qtr0  Qtr1  Qtr2  Qtr3
2000  1.00  1.00  1.00 10.00
2001 10.00 10.00 20.00 20.00

In [17]:
cf.nominal_rate(const_value=[10, 20]*10, pyr=4)


Out[17]:
   Qtr0  Qtr1  Qtr2  Qtr3
0 10.00 20.00 10.00 20.00
1 10.00 20.00 10.00 20.00
2 10.00 20.00 10.00 20.00
3 10.00 20.00 10.00 20.00
4 10.00 20.00 10.00 20.00

Ejemplo.-- Se va a tomar un crédito a 48 meses. La tasa inicial es del 3% y aumenta un punto cada año. Represente la tasa de interés.


In [18]:
cf.nominal_rate(const_value = 3, 
                start = (2000, 0),
                nper = 48,  
                pyr = 12, 
                spec= [(12, 4),      # tasa para el año 2
                       (24, 5),      # tasa para el año 3
                       (36, 6)])     # tasa para el año 4)


Out[18]:
      Jan  Feb  Mar  Apr  May  Jun  Jul  Aug  Sep  Oct  Nov  Dec
2000 3.00 3.00 3.00 3.00 3.00 3.00 3.00 3.00 3.00 3.00 3.00 3.00
2001 4.00 4.00 4.00 4.00 4.00 4.00 4.00 4.00 4.00 4.00 4.00 4.00
2002 5.00 5.00 5.00 5.00 5.00 5.00 5.00 5.00 5.00 5.00 5.00 5.00
2003 6.00 6.00 6.00 6.00 6.00 6.00 6.00 6.00 6.00 6.00 6.00 6.00

In [19]:
x = cf.nominal_rate(const_value = 3, 
                    start = (2000, 0),
                    nper = 48,  
                    pyr = 12, 
                    spec= [(12, 4),      # tasa para el año 2
                           (24, 5),      # tasa para el año 3
                           (36, 6)])     # tasa para el año 4) 
x[5] = 100
x


Out[19]:
        Jan    Feb    Mar    Apr    May    Jun    Jul    Aug    Sep    Oct    Nov    Dec
2000   3.00   3.00   3.00   3.00   3.00 100.00   3.00   3.00   3.00   3.00   3.00   3.00
2001   4.00   4.00   4.00   4.00   4.00   4.00   4.00   4.00   4.00   4.00   4.00   4.00
2002   5.00   5.00   5.00   5.00   5.00   5.00   5.00   5.00   5.00   5.00   5.00   5.00
2003   6.00   6.00   6.00   6.00   6.00   6.00   6.00   6.00   6.00   6.00   6.00   6.00

Representación de flujos genéricos de caja

cashflow también permite la representación de flujos de efectivo en forma similar (pero no igual) a las tasas de interés, pero en este caso las tuplas (time, value) representan valores puntuales en el tiempo.


In [20]:
cf.cashflow(const_value=1,   # valor constante
            start=(2000, 0), # (periodo mayor, periodo menor)
            nper=8,          # número total de periodos
            pyr=4)           # número de periodos por año


Out[20]:
     Qtr0 Qtr1 Qtr2 Qtr3
2000 1.00 1.00 1.00 1.00
2001 1.00 1.00 1.00 1.00

In [21]:
## un valor puntual puede ser introducido mediante una tupla
spec = ((2000, 3), 10)  # ((major, minor), value)
cf.cashflow(const_value=1, start=(2000, 0), nper=8, pyr=4, spec=spec)


Out[21]:
      Qtr0  Qtr1  Qtr2  Qtr3
2000  1.00  1.00  1.00 10.00
2001  1.00  1.00  1.00  1.00

In [22]:
cf.cashflow(const_value=1, start=(2000, 0), nper=8, pyr=4, spec=((2000, 3), 10))


Out[22]:
      Qtr0  Qtr1  Qtr2  Qtr3
2000  1.00  1.00  1.00 10.00
2001  1.00  1.00  1.00  1.00

In [23]:
spec = [((2000, 3), 10), ((2001, 3), 10)]
cf.cashflow(const_value=1, start=(2000, 0), nper=8, pyr=4, spec=spec)


Out[23]:
      Qtr0  Qtr1  Qtr2  Qtr3
2000  1.00  1.00  1.00 10.00
2001  1.00  1.00  1.00 10.00

In [24]:
spec = (3, 10)
cf.cashflow(const_value=1, start=(2000, 0), nper=8, pyr=4, spec=spec)


Out[24]:
      Qtr0  Qtr1  Qtr2  Qtr3
2000  1.00  1.00  1.00 10.00
2001  1.00  1.00  1.00  1.00

In [25]:
cf.cashflow(const_value=1, start=(2000, 0), nper=8, pyr=4, spec=(3, 10))


Out[25]:
      Qtr0  Qtr1  Qtr2  Qtr3
2000  1.00  1.00  1.00 10.00
2001  1.00  1.00  1.00  1.00

In [26]:
spec = [(3, 10), (7, 10)]
cf.cashflow(const_value=1, start=(2000, 0), nper=8, pyr=4, spec=spec)


Out[26]:
      Qtr0  Qtr1  Qtr2  Qtr3
2000  1.00  1.00  1.00 10.00
2001  1.00  1.00  1.00 10.00

In [27]:
cf.cashflow(const_value=[10]*10, pyr=4)


Out[27]:
   Qtr0  Qtr1  Qtr2  Qtr3
0 10.00 10.00 10.00 10.00
1 10.00 10.00 10.00 10.00
2 10.00 10.00

In [28]:
cf.cashflow(const_value=[-10]*4)


Out[28]:
Time Series:
Start = (0,)
End = (3,)
pyr = 1
Data = (0,)-(3,) [4] -10.00 

In [29]:
## un flujo de caja es un objeto que puede guardarse 
## en una variable para usarse después
x = cf.cashflow(const_value=[0, 1, 2, 3], pyr=4)
x[3] = 10
x


Out[29]:
   Qtr0  Qtr1  Qtr2  Qtr3
0  0.00  1.00  2.00 10.00

In [30]:
## es posible alterar y acceder a valores individuales 
## para cada periodo de tiempo usando []
x[3]


Out[30]:
10

In [31]:
x[(0, 3)] = 0

In [32]:
x


Out[32]:
  Qtr0 Qtr1 Qtr2 Qtr3
0 0.00 1.00 2.00 0.00

In [33]:
x[(0,2)]


Out[33]:
2

In [34]:
abs(cf.cashflow(const_value=[-10]*4, pyr=4))


Out[34]:
   Qtr0  Qtr1  Qtr2  Qtr3
0 10.00 10.00 10.00 10.00

In [35]:
cf.cashflow(const_value=[1]*4, pyr=4) + cf.cashflow(const_value=[2]*4, pyr=4)


Out[35]:
  Qtr0 Qtr1 Qtr2 Qtr3
0 3.00 3.00 3.00 3.00

In [36]:
cf.cashflow(const_value=[6]*4, pyr=4) // cf.cashflow(const_value=[4]*4, pyr=4)


Out[36]:
  Qtr0 Qtr1 Qtr2 Qtr3
0 1.00 1.00 1.00 1.00

In [37]:
x = cf.cashflow( const_value=[2]*4, pyr=4)
x += cf.cashflow( const_value=[3]*4, pyr=4)
x


Out[37]:
  Qtr0 Qtr1 Qtr2 Qtr3
0 5.00 5.00 5.00 5.00

In [38]:
x = cf.cashflow( const_value=[6]*4, pyr=4)
x //= cf.cashflow( const_value=[4]*4, pyr=4)
x


Out[38]:
  Qtr0 Qtr1 Qtr2 Qtr3
0 1.00 1.00 1.00 1.00

In [39]:
x = cf.cashflow( const_value=[2]*4, pyr=4)
x *= cf.cashflow( const_value=[3]*4, pyr=4)
x


Out[39]:
  Qtr0 Qtr1 Qtr2 Qtr3
0 6.00 6.00 6.00 6.00

In [40]:
x = cf.cashflow( const_value=[6]*4, pyr=4)
x -= cf.cashflow( const_value=[4]*4, pyr=4)
x


Out[40]:
  Qtr0 Qtr1 Qtr2 Qtr3
0 2.00 2.00 2.00 2.00

In [41]:
cf.cashflow( const_value=[2]*4, pyr=4) * cf.cashflow( const_value=[3]*4, pyr=4)


Out[41]:
  Qtr0 Qtr1 Qtr2 Qtr3
0 6.00 6.00 6.00 6.00

In [42]:
cf.cashflow( const_value=[6]*4, pyr=4) - cf.cashflow( const_value=[4]*4, pyr=4)


Out[42]:
  Qtr0 Qtr1 Qtr2 Qtr3
0 2.00 2.00 2.00 2.00

In [43]:
cf.cashflow( const_value=[6]*4, pyr=4).tolist()


Out[43]:
[6, 6, 6, 6]

In [44]:
cflo = cf.cashflow(const_value=[-10, 5, 0, 20] * 3, pyr=4)
cf.cfloplot(cflo)


time    value +------------------+------------------+
(0, 0) -10.00           **********
(0, 1)   5.00                    *****
(0, 2)   0.00                    *
(0, 3)  20.00                    ********************
(1, 0) -10.00           **********
(1, 1)   5.00                    *****
(1, 2)   0.00                    *
(1, 3)  20.00                    ********************
(2, 0) -10.00           **********
(2, 1)   5.00                    *****
(2, 2)   0.00                    *
(2, 3)  20.00                    ********************

In [ ]:

En algunos casos es necesario introducir patrones de flujo más complejos.


In [45]:
cf.cashflow(const_value=[0, 1, 2, 2, 4, 5, 6, 7, 8])


Out[45]:
Time Series:
Start = (0,)
End = (8,)
pyr = 1
Data = (0,)          0.00 
       (1,)          1.00 
       (2,)-(3,) [2] 2.00 
       (3,)          5.00 
       (4,)          6.00 
       (5,)          7.00 
       (6,)          8.00 

In [46]:
## para  5 <= t < 10, el valor es $ 100, y 0 en el resto de los casos
cf.cashflow(const_value=0, nper=15, pyr=1, spec=[(t,100) for t in range(5,10)])


Out[46]:
Time Series:
Start = (0,)
End = (14,)
pyr = 1
Data = (0,)-(4,)  [5]   0.00 
       (4,)-(7,)  [4] 100.00 
       (7,)-(10,) [4]   0.00 

In [47]:
## un flujo escalonado
a = [(t, 100) for t in range( 1,  5)]
b = [(t, 150) for t in range( 6, 10)]
c = [(t, 200) for t in range(11, 13)]
cf.cashflow(const_value=0, nper=20, pyr=1, spec=a + b + c)


Out[47]:
Time Series:
Start = (0,)
End = (19,)
pyr = 1
Data = (0,)             0.00 
       (1,)-(4,)  [4] 100.00 
       (4,)-(7,)  [4] 150.00 
       (7,)-(8,)  [2] 200.00 
       (8,)-(13,) [6]   0.00 

In [48]:
## flujo con gradiente geométrico (aumento del 5% por periodo)
cf.cashflow(const_value=0, nper=20, pyr=1, spec=[(t, 100 * 1.05 ** (t-5)) for t in range(5,10)])


Out[48]:
Time Series:
Start = (0,)
End = (19,)
pyr = 1
Data = (0,)-(4,)  [5]    0.00 
       (4,)            105.00 
       (5,)            110.25 
       (6,)            115.76 
       (7,)            121.55 
       (8,)-(17,) [10]   0.00