Deployn

Kapitalwertrechner

Zwei mithilfe von JavaScript erstellte Kapitalwertrechner. Einer davon bietet die Möglichkeit, den Cashflow taggenau einzutragen.

Kapitalwertrechner-heroimage

Für eine Aufgabe wollte ich gerne den Barwert (NPV) einer Investition berechnen und als nächsten Schritt auch den internen Zinsfuß. Statt die Zahlen in meinen Taschenrechner einzutippen, hatte ich eher Lust darauf einen Rechner mit JavaScript zu erstellen, insbesondere da ich schon länger nichts mehr mit reinem JavaScript gemacht habe. Mich interessierte auch die Frage, wie ich eine Investition berechnen könnte, wenn nicht immer in einem regulären Intervall Ein- und Auszahlungen getätigt werden.

Zunächst zeige ich einen eher gewöhnlichen Kapitalwertrechner, der jedoch auch versucht den internen Zinsfuß zu berechnen. Anschließend folgt weiter unten ein Kapitalwertrechner mit letiablen Zahlungsflüssen.

Im Übrigen übernehme ich natürlich keine Gewähr für die Berechnung.

Update: Inzwischen sind die beiden Rechner umgezogen und basieren auf React.

Zum Kapitalwertrechner

Dennoch befindet sich hier die Erläuterung und der Javascript-Code.

1. Rechner Normalinvestition

Sobald man die Zahlen eingegeben hat und auf die “Berechnen”-Schaltfläche drückt, wird einem angezeigt, wie hoch der Kapitalwert der Investition im Zeitpunkt 0 ist. Des Weiteren wird der interne Zinsfuß auf eine Genauigkeit von 0,1 % berechnet. Der Rechner geht davon, dass es eine Investition im Zeitpunkt 0 gibt, anschließend gleichbleibende Investitionen in einer beliebigen Anzahl an Zeitpunkten. Letztlich bleibt noch ein positiver oder negativer Restwert am Ende der Laufzeit.

Auswertung

Was kann man damit berechnen? Beispiel: Nehmen wir an, es gibt eine Möglichkeit zu einer dreijährigen Investition, die anfänglich 10.000 € bedarf und anschließend jährlich 1.000 € weitere Kosten verursacht. Jedes Jahr erbringt die Investition einen Rückfluss in Höhe von 5.000 €. Das Geld könnte man jedoch auch woanders für 8 % Zinsen anlegen.

Beispiel Normalinvestition

Der Rechner sagt, dass der Barwert bei 308 € liegt. Der positive Kapitalwert zeigt, dass sich die Investition bei einem Kalkulationszins von 8 % lohnt. Der interne Zinssatz liegt zwischen 9,7 % und 9,8 %. Das heißt, bei einem Kalkulationszinssatz von ca. 9,7 %, würde der Barwert eine Höhe von ca. 0 € betragen. Also bringt die Investition eine Rendite von ca. 9,7 %.

Code

Vielleicht interessiert ja jemanden der ursprüngliche JavaScript-Code, obwohl er bisher noch nicht aufgeräumt ist:

function initInvest() {
	return document.getElementById("inputInitInvest").value;
}

function deposit() {
	return document.getElementById("inputDeposit").value;
}

function payout() {
	return document.getElementById("inputPayout").value;
}

function interest() {
	return document.getElementById("inputInterest").value;
}

function termVal() {
	return document.getElementById("inputTermVal").value;
}
function discount(value, interest, time) {
	return value * (1 / (1 + interest / 100) ** time);
}

function annuity() {
	let yearCount = 0;
	let annuity = 0;
	while (yearCount < duration()) {
		yearCount++;
		annuity += discount(payout() - deposit(), interest(), yearCount);
	}
	return annuity;
}

function annuityTest(newInterest) {
	let yearCount = 0;
	let annuity = 0;
	while (yearCount < duration()) {
		yearCount++;
		annuity += discount(payout() - deposit(), newInterest, yearCount);
	}
	return annuity;
}

function duration() {
	return document.getElementById("inputDuration").value;
}

function calc() {
	document.getElementById("solution").innerHTML =
		"Der Kapitalwert der Investition beträgt insgesamt " +
		(-initInvest() + annuity() + discount(termVal(), interest(), duration())).toLocaleString("de-DE") +
		".";
	return -initInvest() + annuity() + discount(termVal(), interest(), duration());
}

function calcTest(newInterest) {
	return -initInvest() + annuityTest(newInterest) + discount(termVal(), newInterest, duration());
}

function calcInt() {
	calc();
	let int = Number(interest());
	if (calcTest(int) == 0) {
		return calcIntHtml(int, "ok");
	} else if (calcTest(int) > 0) {
		while (calcTest(int) > 0) {
			int += 0.1;
			if (int > 100) {
				return calcIntHtml("error", "error");
			}
		}
		return calcIntHtml(int, "up");
	} else if (calcTest(int) < 0) {
		while (calcTest(int) < 0) {
			int -= 0.1;
			if (int < -100) {
				return calcIntHtml("error", "error");
			}
		}
		return calcIntHtml(int, "down");
	}
}

function calcIntHtml(number, direction) {
	if (direction == "error") {
		document.getElementById("solutionInt").innerHTML = "Der interne Zinsfuß kann nicht berechnet werden.";
	}
	if (direction == "ok") {
		document.getElementById("solutionInt").innerHTML = "Der interne Zinsfuß beträgt vielleicht " + number + "&nbsp;%";
	}
	if (direction == "up") {
		document.getElementById("solutionInt").innerHTML =
			"Der interne Zinsfuß beträgt zwischen " + (number - 0.1).toFixed(1) + "&nbsp;% und " + number.toFixed(1) + "&nbsp;%";
	}
	if (direction == "down") {
		document.getElementById("solutionInt").innerHTML =
			"Der interne Zinsfuß beträgt zwischen " + number.toFixed(1) + "&nbsp;% und " + (number + 0.1).toFixed(1) + "&nbsp;%";
	}
}

2. Erweiterter Rechner

Bei diesem Rechner ist es möglich den Cashflow Taggenau einzugeben (ob es sinnvoll ist, kann ich nicht wirklich sagen). Der Rechner geht jedoch von einem gleichbleibenden Kalkulationszins aus. Der interne Zinsfuß wird nicht berechnet. Des Weiteren kann dieser Rechner auch als Zinsrechner genutzt werden.

Code

Der JavaScript-Code zum erweiterten Rechner:

let cnt = 0;

function addCashflow() {
  let div = document.createElement("DIV");
  div.innerHTML =
    '<input id="cfdate' +
    cnt +
    '" name="cashflow' +
    "" +
    '" type="date" />' +
    '<input id="cfvalue' +
    cnt +
    '" name="cashflow' +
    "" +
    '" type="number" />' +
    '<input id="Button' +
    cnt +
    '" type="button" ' +
    'value="X" onclick="deleteFile(this)" />';
  document.getElementById("cfControls").appendChild(div);
  cnt++;
  buttonText();
}

function deleteFile(div) {
  document.getElementById("cfControls").removeChild(div.parentNode);
  cnt--;
  buttonText();
}

function buttonText() {
  if (cnt > 0) {
    document.getElementById("add_button").value = "Weitere Zahlung hinzufügen";
  } else {
    document.getElementById("add_button").value = "Zahlung hinzufügen";
  }
}

function calc() {
  let solutionText = document.getElementById("solution2");
  solutionText.innerText = "";
  let int = document.getElementById("inputInterest2").value;
  let npv = 0;
  if (cnt == 0) {
    return (solutionText.innerText = "Es liegt keine Investition vor.");
  } else {
    npv += Number(document.getElementById("cfvalue0").value);
    let cfdateStart = new Date(document.getElementById("cfdate0").value);
    for (i = 1; i < cnt; i++) {
      let cfdate = new Date(document.getElementById("cfdate" + i).value);
      let cfvalue = document.getElementById("cfvalue" + i).value;
      npv += discount(cfvalue, int, cfdateStart, cfdate);
    }
    return (solutionText.innerText =
      "Der Kapitalwert der Investition betägt am " +
      cfdateStart.toLocaleDateString() +
      " eine Höhe von " +
      npv.toLocaleString() +
      (cnt > 1
        ? ".\nAm " +
          new Date(
            document.getElementById("cfdate" + (cnt - 1)).value
          ).toLocaleDateString() +
          " liegt der Kapitalwert bei " +
          discount(
            npv,
            int,
            new Date(document.getElementById("cfdate" + (cnt - 1)).value),
            cfdateStart
          ).toLocaleString()
        : ""));
  }
}

function discount(cash, interest, dateStart, dateEnd) {
  let yearStart = dateStart.getFullYear();
  let yearStartLastDay = new Date(yearStart, 11, 31);
  let yearEnd = dateEnd.getFullYear();
  let yearEndFirstDay = new Date(yearEnd, 0, 1);

  if (yearStart == yearEnd) {
    return (
      cash /
      (1 + interest / 100) **
        (dayCount(dateStart, dateEnd) / (365 + (leapYear(yearStart) ? 1 : 0)))
    );
  } else {
    let fullYears = yearEnd - yearStart - 1;
    return (
      cash /
      (1 + interest / 100) **
        ((dayCount(dateStart, yearStartLastDay) + 1) /
          (365 + (leapYear(yearStart) ? 1 : 0)) +
          dayCount(yearEndFirstDay, dateEnd) /
            (365 + (leapYear(yearEnd) ? 1 : 0)) +
          fullYears)
    );
  }
}

function leapYear(year) {
  return (year&nbsp;% 4 == 0 && year&nbsp;% 100 != 0) || year&nbsp;% 400 == 0;
}

function dayCount(start, end) {
  return Number(((end - start) / (1000 * 3600 * 24)).toFixed());
}

Diese Website verwendet Cookies. Diese sind notwendig, um die Funktionalität der Website zu gewährleisten. Weitere Informationen finden Sie in der Datenschutzerklärung