Spis treści:

Kategoria:HTMLJavaScript


Obliczanie harmonogramu spłat kredytu - Javascript

Liczba osób, które mają, mieli lub będą mieć zaciągnięty kredyt hipoteczny idzie w setki tysięcy. Skłoniło mnie to do tego, aby pokazać, w jaki sposób samemu przygotować sobie takie wyliczenia przy pomocy HTML i Javascript. Aplikację można zoabaczyć tutaj: Harmonogram spłat kredytu hipotecznego - raty annuitetowe (równe).

Podstawy teoretyczne obliczania kredytu

Aby zrozumieć kod, należy najpierw przyjrzeć się sposobowi wyliczania rat. Wbrew pozorom nie jest to takie oczywiste. Po pierwsze, harmonogram to tylko plan. Jednym z głównych czynników wpływających na wysokość odsetek są stopy procentowe. Potrafią się one zmienić kilka razy w ciągu jednego roku, nie mówiąc już o wahaniach tego wskaźnika na przestrzeni 30 lat, bo na taki okres udzielana jest większość kredytów, o których słyszałem. Stopy procentowe podaję się najczęściej w stosunku rocznym, natomiast odsetki nalicza się w odstępach miesięcznych. Oznacza to, że do obliczeń należy przyjąć miesięczną stopę procentową, która jest równa pierwiastkowi dwunastego stopnia ze znormalizowanej stawki procentowej pomniejszonej o jeden. Brzmi to groźnie, ale popatrzmy na przykład i wszystko się wyjaśni.

Przypuśćmy, że stopa roczna wynosi 6%. Procent to setna część czegoś, więc 6% to 0.06. Znormalizowana postać (tak ją tutaj będę nazywał) polega na dodaniu do stopy wartości 1. Mamy zatem:
6% = 0.06
Postać znormalizowana
P1 = 0.06 + 1 = 1.06

Aby wyliczyć miesięczną stopę, wyciągamy pierwiastek dwunastego stopnia z rocznej wartości znormalizowanej. Pierwiastek dwunastego stopnia z A jest równe A do potęgi 1/12. Mamy wobec tego:

PM = 0.06 + 1 = 1.061/12 = 1.00486755

Jak to działa dalej? Od pożyczonej kwoty odejmowana jest miesięczna wpłata (rata kredytu), a do pozostałej kwoty doliczane są odsetki. I tak przez, powiedzmy, 30 lat. W rzeczywistości wygląda to trochę inaczej. Rzadko zdarza się, żeby instytucje finansowe oferowały produkt prosty i przejrzysty. Często doliczają opłaty za kontrolę nieruchomości, za uruchomienie kredytu, za obowiązkowe ubezpieczenia. Nie będę się tym zajmował, bo nie jest to zagrywka wykonywana tylko przez banki. Nie szukając daleko - wystarczy się przyjrzeć ofertom telefoniii komórkowej. Co istotne, obliczanie najczęściej nie rozpoczyna się też od pożyczonej kwoty. Zanim dojdzie do pierwszej raty, zostaniemy hojnie obdarowani odsetkami.

Przyjmijmy, że pożyczamy kwotę W0. Co się dzieje po miesiącu? Wartość pozostałą do spłaty obliczamy ze wzoru:

W1 = (W0 - W)P

W1 oznacza saldo rachunku, W oznacza wpłatę (czyli ratę), a P znormalizowaną miesięczną stopę procentową. Proste. Po dwóch miesiącach mamy:

W2 = (W1 - W)P
Podstawiamy W1
W2 = ((W0 - W)P - W)P
W2 = (W0P - WP - W)P
W2 = W0P2 - WP2 - WP

Przedstawię jeszcze wyliczenia na trzeci miesiąc, po których większość dostrzeże pewną prawidłowość.

W3 = (W2 - W)P
Podstawiamy W2
W3 = (W0P2 - WP2 - WP - W)P
W3 = W0P3 - WP3 - WP2 - WP

Podejrzewam, że już wszystko jasne. Po N miesiącach będziemy mieli

W3 = W0PN - WPN - WPN-1 - ... - WP2 - WP

Wystarczy teraz z tego śmiesznego równania wyliczyć W, czyli naszą stałą miesięczną wpłatę. P i W0 są znane. Czeka nass jeszcze jedna podmiana. Po N miesiącach mamy mieć na koncie 0 długu, więc WN musi być równ 0. Popatrzmy na przekształcenia:

WN = W0PN - WPN - WPN-1 - ... - WP2 - WP
0 = W0PN - WPN - WPN-1 - ... - WP2 - WP
Przenosimy szukane wartości na lewo
WPN + WPN-1 + ... + WP2 + WP = W0PN
W(PN + PN-1 + ... + P2 + P) = W0PN
Dzielimy stronami przez ten wielki nawias po lewej
W = W0PN/(PN + PN-1 + ... + P2 + P)

Taki właśnie sposób wyliczania raty annuitetowej (równej) przyjęty został w algorytmie zaimplementowanym w języku Javascript.

Implemetacja algorytmu w Javascript

Poniżej zamieściłem kod pełnej strony, która może posłużyć za wzorzec innych, podobnych rozwiązań. Kod można skopiować i bez wprowadzania zmian uruchomić w przelglądarce. Dodałem też prosty styl i jakiś miły obrazek, aby strona nie wyglądała zbyt ubogo (zobacz: Harmonogram spłat kredytu hipotecznego - raty annuitetowe (równe)). Oto kod:

<html>
<head>
<title>Harmonogram spłat kredytu</title>
<script type="text/javascript">
 //Kolejne parametry to
 //P - roczna stopa procentowa w postaci dziesiętnej, np 0.06 (czyli 6%)
 //R - liczba miesięcznych rat
 //W - wartość kredytu, np. 280000
 function ObliczRate(P,R,W)
 {
  P = P/100.0;
  //P1 - znormalizowana wartość procentowa
  //Jeżeli stopa procentowa jest równa 0.06, postać znormalizowana wynosi 1.06
  //Licząc odsetki mnożmymy znormalizowaną wartość przez wartość początkową
  var P1 = P+1.0;
  //PN - znormalizowana wartość do potęgi N, N - liczba miesięcy
  var PN = 1.0;
  //PM - miesięczne odsetki, wyliczane ze stopy rocznej jako pierwiastek
  //dwunastego stopnia
  var PM = Math.pow(P1,1.0/12.0);
  //PS - Suma ciągu PM+PM^2+...+PM^(N-1)+PM^N
  var PS = 0.0;
  for (i=0; i<R; i++)
  {
   PN *= PM;
   PS += PN;
  }
  //RT - miesięczna rata annuitetowa z dokładnością do dwóch miejsc po przecinku
  //Powiększona o odsetki z pierwszego miesiąca, bo zanim zapłacimy pierwszą ratę,
  //bank już zdąży naliczyć co trzeba
  var RT = Math.round(100*PM*W*PN/PS)/100.0;
  
  //Dynamiczne tworzenie tabeli wynikowej
  var res=document.getElementById("ResultTable");
  while (res.hasChildNodes())
  {
   res.removeChild(res.lastChild);
  }
  
  var naglowki=["Miesiąc","Rata","Saldo przed spłatą","Kapitał","Odsetki","Saldo po spłacie"];
  var tab=document.createElement("table");
  var row=document.createElement("tr");
  for (i=0;i<naglowki.length;i++)
  {
   var th=document.createElement("th");
   th.innerHTML=naglowki[i];
   row.appendChild(th);
  }
  tab.appendChild(row);
  var sumaRat=0.0;
  var doSplaty=Math.round(100*W)/100.0;
  for (i=0;i<R;i++)
  {
   //Wartość do spłaty, zaczynamy od wartości początkowej powiększonej o odsetki
   //z pierwszego miesiąca
   doSplaty=Math.round(100*doSplaty*PM)/100.0;
   //Wyrównanie ostatniej raty spowodowane zaokrągleniami
   if (i==R-1)
    RT=doSplaty;
   sumaRat+=RT;
   row=document.createElement("tr");
   var td=document.createElement("td");
   td.innerHTML=(i+1);
   row.appendChild(td);
   
   td=document.createElement("td");
   td.innerHTML=RT.toFixed(2);
   row.appendChild(td);
   
   
   td=document.createElement("td");
   td.innerHTML=doSplaty.toFixed(2);
   row.appendChild(td);

   //Wartość odsetek w ramach wpłacanej raty
   var odsetki=Math.round(100*doSplaty*(PM-1)/PM)/100.0;
   td=document.createElement("td");
   //Wartość spłacanego kapitału w ramach raty
   td.innerHTML=(RT-odsetki).toFixed(2);
   row.appendChild(td);
   
   td=document.createElement("td");
   td.innerHTML=odsetki.toFixed(2);
   row.appendChild(td);
   
   doSplaty=doSplaty-RT;
   td=document.createElement("td");
   td.innerHTML=doSplaty.toFixed(2);
   row.appendChild(td);
   
   tab.appendChild(row);
  }
  res.appendChild(tab);
 }
 function ObliczRateClick()
 {
  var P = parseFloat(document.getElementById("P").value.replace(",", "."));
  var R = parseInt(document.getElementById("P").value);
  var W = parseInt(document.getElementById("W").value);
  ObliczRate(P,R,W);
 }

</script>
<style type="text/css">
#ResultTable table{border:solid 1px;border-collapse: collapse;}
#ResultTable table tr th{border: 1px solid;text-align: center;font-weight: bold;background:Yellow;padding: 0 5px;}
#ResultTable table tr td:first-child{text-align: center;padding:0;font-weight: bold;}
#ResultTable table tr td{border: 1px solid;text-align: right;padding: 0 5px 0 10px;}
#ResultTable tr:nth-child(even) {background: #EEE;}
#ResultTable tr:nth-child(odd) {background: #FFF;}
.ClickSpan{background:Yellow;border: 1px solid;font-weight: bold;padding: 2px 5px;cursor:pointer;}
</style>
</head>
<body>
<h1>Harmonogram spłat kredytu</h1>
<p>Sprawdź przybliżony harmonogram spłat kredytu przy ratach annuitetowych (równych).</p>
<table>
<tr><td><b>Liczba miesięcy:</b></td><td><input id="Rtype="textvalue="360"/></td>
<td rowspan="4"><img src="Skarbonka_Harmonogram_splat.pngtitle="Harmonogram spłat kredytu"/></td></tr>
<tr><td><b>Oprocentowanie:</b></td><td><input id="Ptype="textvalue="6,8"/></td></tr>
<tr><td><b>Kwota:</b></td><td><input id="Wtype="textvalue="280000"/></td></tr>
<tr><td></td><td><span class="ClickSpanonclick="ObliczRateClick();">Oblicz</span></td></tr>
</table>
<hr/>
<div id="ResultTable"></div>
</body>
</html>

Przykład 1. Harmonogram spłat kredytu hipotecznego - raty annuitetowe (równe).

Kategoria:HTMLJavaScript

, 2013-12-20

Komentarze:

gość (2014-05-06 22:44:27)
Skrypt nie działa :-p
kd (2021-10-21 16:50:25)
działa :) tylko była literówka :)
Dodaj komentarz
Wyślij
Ostatnie komentarze
Dzieki za rozjasnienie zagadnienia upsert. wlasnie sie ucze programowania :).
Co się stanie gdy spróbuję wyszukać:
SELECT * FROM NV_Airport WHERE Code='SVO'
SELECT * FROM V_Airport WHERE Code=N'SVO'
(odwrotnie są te N-ki)
Będzie konwersja czy nie znajdzie żadnego rekordu?