In [1]:
from ipy_table import *
In [2]:
import math
from datetime import datetime
In [3]:
from scipy.optimize import bisect
In [4]:
class EKS_kredit:
    def __init__(self,K,p,n,m,datum,interval,druge_uplate={},druge_isplate={},isplata_kredita={},TSP={}):
        self.K = K
        self.p = p
        self.n = n
        self.m = m
        self.dan = datum[0]
        self.mjesec = datum[1]
        self.godina = datum[2]
        self.delta = 12 // m
        self.anuitet = self._odredi_anuitet()
        self.druge_uplate = self._kreiraj_druge_uplate(druge_uplate)
        self.druge_isplate = self._kreiraj_druge_uplate(druge_isplate)
        self.isplata_kredita = self._kreiraj_isplate_kredita(isplata_kredita)
        self.datumi = self._generiraj_datume()
        self.broj_dana = self._generiraj_broj_dana()
        self.NNT = self._generiraj_NNT()
        self.PGS = bisect(self.PGS_funkcija,interval[0],interval[1])
        self.DNNT = self._generiraj_DNNT()
        self.DIK = self._generiraj_DIK()
        self.UDIK = sum(self.DIK)
        self.TSP = self._kreiraj_TSP(TSP)
        self.DTSP = self._generiraj_DTSP()
        self.UDTSP = sum(self.DTSP)
        self.EKS = self.PGS * self.UDIK / (self.UDIK - self.UDTSP)
        
    def _odredi_anuitet(self):
        p1 = self.p / self.m;
        r = 1 + p1 / 100
        a = self.round_up(self.K * r**self.n * (r-1) / (r**self.n - 1))
        return a
        
    def _kreiraj_isplate_kredita(self,isplata_kredita):
        if isplata_kredita == {}:
            rezultat = [self.K] + [0.0]*self.n
            return rezultat
        rezultat = []
        for k in range(self.n+1):   
            try:
                rezultat.append(isplata_kredita[k])
            except:
                rezultat.append(0.0)
        return rezultat
    
    def _kreiraj_druge_uplate(self,uplate):
        if uplate == {}: return [0.0]*(self.n + 1)
        rezultat = []
        for k in range(self.n+1):   
            try:
                rezultat.append(uplate[k])
            except:
                rezultat.append(0.0)
        return rezultat
    
    def _kreiraj_TSP(self,tsp):
        if tsp == {}: return [0.0]*(self.n + 1)
        rezultat = []
        for k in range(self.n+1):   
            try:
                rezultat.append(tsp[k])
            except:
                rezultat.append(0.0)
        return rezultat
    
    def round_up(self,x):
        y = math.ceil(x * 100) / 100
        return round(y,2)
    
    def _is_leap_year(self,godina):
        if godina % 4 != 0: return False
        if godina % 100 != 0: return True
        if godina % 400 != 0: return False
        return True
    
    def _generiraj_datume(self):
        all_dates = ['{}/{}/{}'.format(self.dan, self.mjesec, self.godina)]
        mjesec = self.mjesec
        godina = self.godina
        for k in range(1,self.n+1):
            dan = self.dan
            mjesec = mjesec + self.delta
            if mjesec > 12:
                mjesec = mjesec % 12
                godina += 1
            if (mjesec == 2) and (self.dan >= 29):
                if self._is_leap_year(godina):
                    dan = 29
                else:
                    dan = 28
            elif (self.dan == 31) and (mjesec in [4,6,9,11]):
                dan = 30
            all_dates.append('{}/{}/{}'.format(dan, mjesec, godina))
        return all_dates
    
    def _generiraj_broj_dana(self):
        date_format = "%d/%m/%Y"
        razmak = list(map(lambda y: 
                    (datetime.strptime(y, date_format) - datetime.strptime(self.datumi[0], date_format)).days,
                    self.datumi))
        return razmak        
    
    def _generiraj_NNT(self):
        NNT = []
        NNT.append(-self.isplata_kredita[0] - self.druge_isplate[0] + self.druge_uplate[0])
        for k in range(1,self.n+1):
            NNT.append(self.anuitet + self.druge_uplate[k] - self.druge_isplate[k] - self.isplata_kredita[k])
        return NNT
    
    def _generiraj_DNNT(self):
        DNNT = []
        DNNT.append(self.NNT[0])
        for k in range(1,self.n+1):
            rez = self.NNT[k] / ((1 + self.PGS/100.0) ** (self.broj_dana[k] / 365.0))
            DNNT.append(rez)
        return DNNT
    
    def _generiraj_DIK(self):
        DIK = []
        DIK.append(self.isplata_kredita[0])
        for k in range(1,self.n+1):
            rez = self.isplata_kredita[k] / ((1 + self.PGS/100.0) ** (self.broj_dana[k] / 365.0))
            DIK.append(rez)
        return DIK
    
    def _generiraj_DTSP(self):
        DTSP = []
        DTSP.append(self.TSP[0])
        for k in range(1,self.n+1):
            rez = self.TSP[k] / ((1 + self.PGS/100.0) ** (self.broj_dana[k] / 365.0))
            DTSP.append(rez)
        return DTSP
        
    def PGS_funkcija(self,x):
        suma = 0
        for k in range(len(self.NNT)):
            suma += self.NNT[k] / ((1+x/100.0) ** (self.broj_dana[k] / 365.0))
        return suma
    
    def otplatna_tablica(self):
        lista = [['k','datum', 'anuitet', 'kamate', 'otplatna\n kvota', 'ostatak\n duga',
                  'druge\n uplate','druge\n isplate','isplata\n kredita','NNT','DNNT','DIK','TSP','DTSP']]
        lista.append([0,self.datumi[0],'','','',self.K,self.druge_uplate[0],self.druge_isplate[0],
                      self.isplata_kredita[0],self.NNT[0],self.DNNT[0],self.DIK[0],self.TSP[0],self.DTSP[0]])
        p1 = self.p / self.m;
        r = 1 + p1 / 100
        for k in range(1,self.n+1):
            Ik = lista[-1][5] * (r - 1)
            Rk = self.anuitet - Ik
            Ok = lista[-1][5] - Rk
            lista.append([k,self.datumi[k],self.anuitet,Ik,Rk,Ok,self.druge_uplate[k],self.druge_isplate[k],
                          self.isplata_kredita[k],self.NNT[k],self.DNNT[k],self.DIK[k],self.TSP[k],self.DTSP[k]])
        razlika = lista[-1][4] - lista[-2][5]
        lista[-1][2] = lista[-1][2] - razlika
        lista[-1][4] = lista[-2][5]
        lista[-1][5] = 0.0
        lista[-1][9] = lista[-1][9] - razlika
        lista[-1][10] = lista[-1][9] / ((1 + self.PGS/100.0) ** (self.broj_dana[-1] / 365.0))
        lista = make_table(lista)
        apply_theme('basic')
        set_global_style(float_format='%.2f',align='right')
        set_column_style(1, thick_border='right')
        set_column_style(5, thick_border='right')
        return lista
In [ ]: