Skip to content

Commit

Permalink
Füge Link ein
Browse files Browse the repository at this point in the history
  • Loading branch information
Jacques-Mock-Schindler committed Nov 28, 2023
1 parent 095f197 commit 9681b01
Showing 1 changed file with 394 additions and 0 deletions.
394 changes: 394 additions & 0 deletions docs/npv/npv.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,394 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Berechnung des Net Present Value mit Python"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Im folgenden Notebook geht es darum, den Nettobarwert (Net Present\n",
"Value, NPV) einer Investition mit den Grundfunktionen von Python\n",
"zu berechnen. Allenfalls werden dafür eigene Funktionen\n",
"geschrieben."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Um die Berechnung des NPV zu programmieren, braucht es zuerst eine\n",
"Zusammenstellung der für die Berechnung erforderlichen Informationen\n",
"(Daten). Hilfreich ist es ausserdem, die Berechnung in Zwischenschritte\n",
"aufzuteilen und diese Zwischenschritte aufzulisten."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Zur Berechnung des NPV erforderliche Daten"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Listen Sie in der folgenden Zelle die für die Berechnung des NPV nötigen\n",
"Informationen auf."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- Anfangsinvestition\n",
"- Liquidationserlös\n",
"- kalkulatorischer Zinssatz\n",
"- Nutzungsdauer\n",
"- Liste der Cash Flows"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Zur Berechnung des NPV sinnvolle Zwischenschritte"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Zählen Sie in der folgenden Zelle sinnvolle Zwischenschritte für die\n",
"Berechnung des NPV auf."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- Berechnung der Abzinsungsfaktoren\n",
"- Summe der abgezinsten Cash Flows\n",
"- Berechnung des NPV aus den Zwischenresultaten"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Modellprojekt"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Das Modellprojekt ist eine Aufgabe, die aus dem Buch \n",
"Capaul, Roman, und Steingruber, Daniel; Betriebswirtschaft verstehen:\n",
"Das St.Galler Management-Modell. 4. Auflage. Berlin: Cornelsen, 2020,\n",
"Seite 425 übernommen wurde."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"| Stichwort | Variante A | Variante B |\n",
"| :--- | ---: | ---: |\n",
"| Anschaffungspreis | 8'000 | 10'000 |\n",
"| Nutzungsdauer | 4 Jahre | 4 Jahre |\n",
"| CF1 | 3'500 | 4'000 |\n",
"| CF2 | 3'800 | 4'100 |\n",
"| CF3 | 3'900 | 4'100 |\n",
"| CF4 | 4'000 | 4'200 |\n",
"| Kalkulatorischer Zinssatz | 12% | 12% |"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Um die Berechnung zu programmieren, wird vorerst nur mit der Variante A gerechnet."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Weisen Sie in der folgenden Zelle die Angaben der Ausgangslage Variabeln\n",
"zu. Verwenden Sie dazu sinnvolle Namen."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"investment = 8_000\n",
"cash_flows = [3_500, 3_800, 3_900, 4_000]\n",
"interest_rate = 0.12"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Berechnen Sie aus diesen Angaben als erstes eine Liste der diskontierten\n",
"Cash Flows. Arbeiten Sie dazu mit einer `for`-Schleife."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"test = []\n",
"for i in range(len(cash_flows)):\n",
" test.append(cash_flows[i] * (1+interest_rate)**-(i+1))\n",
"print(f\"Test: {test}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"test2 = []\n",
"i = 1\n",
"for cf in cash_flows:\n",
" test2.append(cf * (1+interest_rate)**-(i))\n",
" i += 1\n",
"print(f\"Test2: {test2}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Weil die Berechnung des Abzinsungsfaktors für jedes Jahr neu erfolgen\n",
"muss, braucht die `for`-Schlaufe eine laufende Variabel. \n",
"\n",
"In der ersten Variante ist das `i` aus `i in range()`. Allerdings wird\n",
"hier bei `0` zu zählen begonnen. Daher muss für die Potenz in der\n",
"Berechnung des Abzinsungsfaktors `(1+interest_rate)**-(i+1)` `i` um `1`\n",
"erhöht werden, damit mit der korrekten Anzahl Jahre gerechnet wird.\n",
"\n",
"In der zweiten Variante ist wiederum `i` die laufende Variabel.\n",
"Allerdings wird sie in dieser Variante ausserhalb des Schleifenkörpers\n",
"definiert (`i = 1`). Dies hat den Vorteil, dass für die Berechnung des\n",
"Abzinsungsfaktors direkt mit `i` gerechnet werden kann\n",
"(`(1+interest_rate)**-(i)`). Dafür muss `i` auf einer separaten Zeile\n",
"(`i += 1`) hochgezählt werden.\n",
"\n",
"Die beiden Varianten sind gleichwertig. Allenfalls ist die zweite\n",
"Variante, obwohl sie mehr Code-Zeilen braucht, besser lesbar."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Als Alternative kann die Liste der diskontierten Cash Flows auch mit Hilfe\n",
"einer\n",
"[list comprehension](https://realpython.com/list-comprehension-python/)\n",
"programmiert werden.\n",
"\n",
"Setzen Sie diese Alternative in der folgenden Zelle um."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Discounted cash flows: [3125.0, 3029.3367346938767, 2775.9429664723025, 2542.072313619324]\n"
]
}
],
"source": [
"discounted_cash_flows = [cf * (1+interest_rate)**-(i + 1) \n",
" for i, cf in enumerate(cash_flows)]\n",
"print(f\"Discounted cash flows: {discounted_cash_flows}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Um in der list comprehension eine laufende Variabel verwenden zu können,\n",
"braucht es die Funktion\n",
"[`enumerate()`](https://realpython.com/python-enumerate/). Diese gibt\n",
"sowohl den Index wie auch das entsprechende Element der Liste der Reihe\n",
"nach zurück.\n",
"Die entsprechenden Werte werden in `for i, cf in enumerate(cash_flows)`\n",
"den Variabeln `i` (Index) und `cf` (Element) zugewiesen."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Mit der Liste der diskontierten Cash Flows kann der NPV berechnet\n",
"werden, indem die Liste aufaddiert wird und der daraus resultierende\n",
"Barwert (Present Value, PV) der Anfangsinvestition gegenübergestellt wird."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Berechnen Sie in der folgenden Zelle den Nettobarwert und weisen diesen\n",
"der Variabel `npv` zu."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"NPV: 3472.3520147855033\n"
]
}
],
"source": [
"npv = sum(discounted_cash_flows) - investment\n",
"print(f\"NPV: {npv}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Die Berechnung des NPV in einer Funktion"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Um diese Vorgehensweise einem Nutzer zur wiederholten Verwendung zur\n",
"Verfügung zu stellen, kann sie als Funktion zur Verfügung gestellt werden."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Programmieren Sie in der nächsten Zelle eine Funktion `get_npv()` die\n",
"alle nötigen Informationen als Parameter entgegennimmt und den NPV zurückgibt."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"def get_npv(investment : int, \n",
" cash_flows : list[int], \n",
" interest_rate : float) -> float:\n",
" \n",
" discounted_cash_flows = [cf * (1+interest_rate)**-(i + 1) \n",
" for i, cf in enumerate(cash_flows)]\n",
" \n",
" npv = sum(discounted_cash_flows) - investment\n",
" \n",
" return npv"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Die Funktion könnte mit zwei Zeilen Code geschrieben werden: eine Zeile\n",
"Kopf der Funktion und eine Zeile `return` Statement. Allerdings wäre\n",
"dies weniger gut lesbar (*explicit is better then implicit*)."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"NPV A: 3472.3520147855033 \n",
"NPV B: 2427.3984147230294\n"
]
}
],
"source": [
"Variante_a = get_npv(investment, cash_flows, interest_rate)\n",
"Variante_b = get_npv(10_000, [4_000, 4_100, 4_100, 4_200], interest_rate)\n",
"print(f\"NPV A: {Variante_a} \\nNPV B: {Variante_b}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In der Anwendung der Funktion auf das Zahlenbeispiel kann man noch\n",
"Überlegungen zur Präzision des Resultates anstellen. Für die Darstellung\n",
"des Resultates kann auf die Nachkommastellen verzichtet werden."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"NPV A: 3472 \n",
"NPV B: 2427\n"
]
}
],
"source": [
"print(f'NPV A: {round(Variante_a)} \\nNPV B: {round(Variante_b)}')"
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".venv",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.6"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

0 comments on commit 9681b01

Please sign in to comment.