Određivanje IRR projekta metodom regule falsi u pythonu

In [1]:
import platform
In [2]:
platform.platform()
Out[2]:
'Linux-4.19.6-1-MANJARO-x86_64-with-arch-Manjaro-Linux'
In [3]:
platform.python_version()
Out[3]:
'3.7.1'

Funkcija IRR_regula_falsi određuje IRR projekta metodom regule falsi. Funkcija ima sljedeće parametre:

  • novac - lista novčanih tokova $F_0,F_1,F_2,\dotsc$ tijekom godina.
  • a - donja granica za IRR. Unosi se kamatna stopa bez znaka postotka.
  • b - gornja granica za IRR. Unosi se kamatna stopa bez znaka postotka.
  • delta - preciznost na koju želimo izračunati IRR. Po defaultu je stavljeno delta=10e-5.
  • niter - Maksimalni dozvoljeni broj iteracija. Po defaultu je stavljeno niter=100. Nakon što vrijednosti susjednih dviju iteracija za IRR budu na udaljenosti manjoj od delta ili broj iteracija prijeđe vrijednost niter, tada se prekida izvođenje funkcije. Zadnju vrijednost možemo uzeti za aproksimacuiju IRR-a projekta.
  • decimale - Na koliko decimala želimo ispisati rezultate. Po defaultu je stavljeno decimale=5.
  • izlaz - u kojem obliku želimo ispisati korake algoritma. Ako je izlaz='rjecnik', tada se rezultati ispisuju u obliku rječnika. Ako je izlaz='html', tada se rezultati ispisuju u obliku html tablice. Dakle, funkcija na izlazu vraća svaki korak provedene iteracije.
In [4]:
import numpy as np
from ipy_table import *
In [5]:
def fun(p,novac):
    return np.npv(p/100,novac)
In [6]:
def IRR_regula_falsi(novac,a,b,delta=10e-5,niter=100,decimale=5,izlaz='rjecnik'):
    if fun(a,novac)*fun(b,novac) > 0:
        return "Error: f(a)*f(b)>0"
    broj_iteracija = 0
    A = []
    B = []
    C = [a,b]
    F = [fun(a,novac),fun(b,novac)]
    while ((abs(C[-1]-C[-2]) > delta)) and (broj_iteracija <= niter):
        broj_iteracija += 1
        A.append(a)
        B.append(b)
        C.append((a*fun(b,novac)-b*fun(a,novac))/(fun(b,novac)-fun(a,novac)))
        F.append(fun(C[-1],novac))
        if fun(a,novac) * fun(C[-1],novac) < 0:
                  b = C[-1]
        else:
                  a = C[-1]
    if izlaz == 'rjecnik':
        np.set_printoptions(suppress=True,precision=decimale)
        return {'a':np.around(A,decimale), 'b':np.around(B,decimale), 'c':np.around(C,decimale), 'NPV':np.around(F,decimale)}
    elif izlaz == 'html':
        tablica = list(zip(range(-1,broj_iteracija+1),[' ',' '] + A,[' ',' '] + B,C,F))
        tablica = [[' ','a','b','c<sub>i</sub','NPV']] + tablica
        tablica=make_table(tablica)
        apply_theme('basic_both')
        set_global_style(align='center')
        set_global_style(float_format='%0.{}f'.format(decimale))
        return tablica

Zadatak

Banka mora odlučiti između dviju investicija u iznosu od 200 000 € čiji novčani tokovi su procijenjeni u sljedećoj tablici.

projekt 0 1 2 3 4 5
A -200 000 80 000 60 000 70 000 100 000 100 000
B -200 000 30 000 85 000 95 000 90 000 85 000

Odredite IRR oba projekta metodom regule falsi i prikažite sve korake algoritma.

Rješenje

In [7]:
projektA=[-200000,80000,60000,70000,100000,100000]
projektB=[-200000,30000,85000,95000,90000,85000]

projekt A

In [8]:
IRR_regula_falsi(projektA,25,30,niter=10,izlaz='html')
Out[8]:
 abciNPV
-1  2511968.00000
0  30-9151.26329
1253027.83343-451.33866
22527.8334327.73046-21.38813
32527.7304627.72559-1.01159
42527.7255927.72536-0.04784
52527.7253627.72535-0.00226
In [9]:
IRR_regula_falsi(projektA,25,30,niter=10)
Out[9]:
{'a': array([25, 25, 25, 25, 25]),
 'b': array([30.     , 27.83343, 27.73046, 27.72559, 27.72536]),
 'c': array([25.     , 30.     , 27.83343, 27.73046, 27.72559, 27.72536,
        27.72535]),
 'NPV': array([11968.     , -9151.26329,  -451.33866,   -21.38813,    -1.01159,
           -0.04784,    -0.00226])}
In [10]:
IRR_regula_falsi(projektA,25,30,niter=10,izlaz='html',decimale=12)
Out[10]:
 abciNPV
-1  2511968.000000000000
0  30-9151.263288023227
1253027.833432169669-451.338660489568
22527.83343216966927.730460705970-21.388134332963
32527.73046070597027.725589776802-1.011591464910
42527.72558977680227.725359416648-0.047840722807
52527.72535941664827.725348522376-0.002262499183
In [11]:
IRR_regula_falsi(projektA,25,30,niter=10,decimale=12)
Out[11]:
{'a': array([25, 25, 25, 25, 25]),
 'b': array([30.            , 27.833432169669, 27.73046070597 , 27.725589776802,
        27.725359416648]),
 'c': array([25.            , 30.            , 27.833432169669, 27.73046070597 ,
        27.725589776802, 27.725359416648, 27.725348522376]),
 'NPV': array([11968.            , -9151.263288023227,  -451.338660489568,
          -21.388134332963,    -1.01159146491 ,    -0.047840722807,
           -0.002262499183])}

projekt B

In [12]:
IRR_regula_falsi(projektB,20,25,niter=10,izlaz='html')
Out[12]:
 abciNPV
-1  2016567.00103
0  25-8243.20000
1202523.33875-499.11538
22023.3387523.24110-29.26322
32023.2411023.23539-1.71242
42023.2353923.23505-0.10020
52023.2350523.23503-0.00586
In [13]:
IRR_regula_falsi(projektB,20,25,niter=10)
Out[13]:
{'a': array([20, 20, 20, 20, 20]),
 'b': array([25.     , 23.33875, 23.2411 , 23.23539, 23.23505]),
 'c': array([20.     , 25.     , 23.33875, 23.2411 , 23.23539, 23.23505,
        23.23503]),
 'NPV': array([16567.00103, -8243.2    ,  -499.11538,   -29.26322,    -1.71242,
           -0.1002 ,    -0.00586])}
In [14]:
IRR_regula_falsi(projektB,20,25,niter=10,izlaz='html',decimale=12)
Out[14]:
 abciNPV
-1  2016567.001028806611
0  25-8243.200000000001
1202523.338747841981-499.115377396891
22023.33874784198123.241102874050-29.263224564089
32023.24110287405023.235388026432-1.712422953122
42023.23538802643223.235053640015-0.100196176365
52023.23505364001523.235034074733-0.005862574897
In [15]:
IRR_regula_falsi(projektB,20,25,niter=10,decimale=12)
Out[15]:
{'a': array([20, 20, 20, 20, 20]),
 'b': array([25.            , 23.338747841981, 23.24110287405 , 23.235388026432,
        23.235053640015]),
 'c': array([20.            , 25.            , 23.338747841981, 23.24110287405 ,
        23.235388026432, 23.235053640015, 23.235034074733]),
 'NPV': array([16567.00102880661 , -8243.2           ,  -499.115377396891,
          -29.263224564089,    -1.712422953122,    -0.100196176365,
           -0.005862574897])}
In [ ]: