|
1 | 1 | # cashflows.R
|
2 |
| -Simple functions for visualizing and discounting cash flows (DCF) in R |
| 2 | + |
| 3 | +## Czym jest cashflows.R? |
| 4 | + |
| 5 | +cashflows.R to niewielki skrypt w R, który ułatwia pracę nad przepływami pieniężnymi (cash flows). Umożliwia między innymi łączenie różnych przepływów, zapisywanie w formie przepływu rent i obligacji, a także obliczanie wartości przepływu w danym czasie według podanego oprocentowania prostego lub złożonego. |
| 6 | + |
| 7 | +## Rozpoczynanie pracy |
| 8 | + |
| 9 | +Można dołączyć cashflows.R do swojego skryptu dopisując na początku |
| 10 | +komendę |
| 11 | + |
| 12 | +``` r |
| 13 | +source("https://github.com/pawelmajcher/cashflows.R/blob/main/cashflows.R?raw=true") |
| 14 | +``` |
| 15 | + |
| 16 | +która dodaje wszystkie funkcje do twojej przestrzeni roboczej. |
| 17 | + |
| 18 | +## Dostępne funkcje |
| 19 | + |
| 20 | +### cashflow(payments, periods) |
| 21 | + |
| 22 | +Funkcja `cashflow` przyjmuje wektor z wartościami poszczególnych transakcji oraz wektor z czasem ich wykonania, i porządkuje je tak, aby transakcje były zapisane w odpowiedniej kolejności i zwraca listę w R, która przez inne funkcje jest rozumiana jako przepływ pieniężny. |
| 23 | + |
| 24 | +#### Argumenty |
| 25 | + |
| 26 | +| Nazwa | Opis | Przyjmowana wartość | Wymagany | |
| 27 | +|:-----|:-------------------------|:-----------------------|:---------------| |
| 28 | +| `payments` | wektor z wartościami poszczególnych transakcji | wektor liczbowy o dowolnej długości | Tak | |
| 29 | +| `periods` | wektor z czasem przeprowadzenia poszczególnych transakcji | wektor liczbowy o takiej samej długości jak payments | Nie, domyślnie 1:length(payments) | |
| 30 | + |
| 31 | +#### Przykłady |
| 32 | + |
| 33 | +``` r |
| 34 | +cashflow_example_1 = cashflow(payments = c(10,30,40,10)) |
| 35 | +cashflow_example_1 |
| 36 | +``` |
| 37 | + |
| 38 | + ## $payments |
| 39 | + ## [1] 10 30 40 10 |
| 40 | + ## |
| 41 | + ## $periods |
| 42 | + ## [1] 1 2 3 4 |
| 43 | + |
| 44 | +``` r |
| 45 | +cashflow_example_2 = cashflow(payments = c(10,20,30), periods = c(0,2,5)) |
| 46 | +cashflow_example_2 |
| 47 | +``` |
| 48 | + |
| 49 | + ## $payments |
| 50 | + ## [1] 10 20 30 |
| 51 | + ## |
| 52 | + ## $periods |
| 53 | + ## [1] 0 2 5 |
| 54 | + |
| 55 | +### cfmerge(…) |
| 56 | + |
| 57 | +Funkcja `cfmerge` przyjmuje i łączy (scala) dowolną liczbę przepływów |
| 58 | +pieniężnych w jeden. |
| 59 | + |
| 60 | +#### Przykłady |
| 61 | + |
| 62 | +``` r |
| 63 | +cashflow_example_3 = cfmerge(cashflow_example_1, cashflow_example_2, cashflow(-100, periods=5)) |
| 64 | +cashflow_example_3 |
| 65 | +``` |
| 66 | + |
| 67 | + ## $payments |
| 68 | + ## [1] 10 10 50 40 10 -70 |
| 69 | + ## |
| 70 | + ## $periods |
| 71 | + ## [1] 0 1 2 3 4 5 |
| 72 | + |
| 73 | +### cfmatrix(cf, vertical) |
| 74 | + |
| 75 | +Funkcja `cfmatrix` zwraca dany przepływ pieniężny jako macierz. Jest |
| 76 | +przydatna, gdy chcemy wyświetlić przepływ i ręcznie go przeanalizować. |
| 77 | + |
| 78 | +#### Argumenty |
| 79 | + |
| 80 | +| Nazwa | Opis | Przyjmowana wartość | Wymagany | |
| 81 | +|:----|:--------------------------------|:----------------|:-----------------| |
| 82 | +| `cf` | przepływ, który chcemy zapisać jako macierz | przepływ pieniężny wygenerowany przez inną funkcję | Tak | |
| 83 | +| `vertical` | opcja zapisu kolejnych transakcji pod sobą zamiast obok siebie (warto wybrać dla dłuższych przepływów) | wartość logiczna | Nie, domyślnie `FALSE` (kolejne transakcje poziomo) | |
| 84 | + |
| 85 | +#### Przykłady |
| 86 | + |
| 87 | +``` r |
| 88 | +cfmatrix(cashflow_example_2) |
| 89 | +``` |
| 90 | + |
| 91 | + ## Payment 1 Payment 2 Payment 3 |
| 92 | + ## Period 0 2 5 |
| 93 | + ## Amount 10 20 30 |
| 94 | + |
| 95 | +``` r |
| 96 | +cfmatrix(cashflow_example_3, vertical=TRUE) |
| 97 | +``` |
| 98 | + |
| 99 | + ## Period Amount |
| 100 | + ## Payment 1 0 10 |
| 101 | + ## Payment 2 1 10 |
| 102 | + ## Payment 3 2 50 |
| 103 | + ## Payment 4 3 40 |
| 104 | + ## Payment 5 4 10 |
| 105 | + ## Payment 6 5 -70 |
| 106 | + |
| 107 | +### annuity(period, amount, due) |
| 108 | + |
| 109 | +Funkcja `annuity` przyjmuje parametry danej renty i zwraca odpowiadający |
| 110 | +jej przepływ pieniężny. |
| 111 | + |
| 112 | +#### Argumenty |
| 113 | + |
| 114 | +| Nazwa | Opis | Przyjmowana wartość | Wymagany | |
| 115 | +|:----|:----------------|:--------------------------------|:-----------------| |
| 116 | +| `period` | liczba okresów (długość) trwania renty | liczba naturalna lub `Inf` (przybliżenie renty wieczystej jako 10000 okresów) | Tak | |
| 117 | +| `amount` | wysokość renty | liczba | Nie, domyślnie `1` | |
| 118 | +| `due` | płatność renty z góry | wartość logiczna | Nie, domyślnie `FALSE` (płatność z dołu) | |
| 119 | + |
| 120 | +#### Przykłady |
| 121 | + |
| 122 | +``` r |
| 123 | +cashflow_example_4 = annuity(period = 6, amount = 150, due = TRUE) |
| 124 | +cfmatrix(cashflow_example_4) |
| 125 | +``` |
| 126 | + |
| 127 | + ## Payment 1 Payment 2 Payment 3 Payment 4 Payment 5 Payment 6 |
| 128 | + ## Period 0 1 2 3 4 5 |
| 129 | + ## Amount 150 150 150 150 150 150 |
| 130 | + |
| 131 | +### bond(principal, maturity, couponRate, boughtFor) |
| 132 | + |
| 133 | +Funkcja `bond` przyjmuje parametry danej obligacji i zwraca |
| 134 | +odpowiadający jej przepływ pieniężny. |
| 135 | + |
| 136 | +#### Argumenty |
| 137 | + |
| 138 | +| Nazwa | Opis | Przyjmowana wartość | Wymagany | |
| 139 | +|:------|:-------------------|:-----------------|:----------------------------| |
| 140 | +| `principal` | wartość nominalna obligacji | liczba | Tak | |
| 141 | +| `maturity` | termin zapadalności obligacji | liczba naturalna | Tak | |
| 142 | +| `couponRate` | stała lub zmienna stopa kuponowa obligacji | liczba lub wektor długości `maturity` | Nie, domyślnie 0 (obligacja zerokuponowa) | |
| 143 | +| `boughtFor` | cena, za jaką obligacja została zakupiona | liczba | Nie, domyślnie 0 (transakcja zakupu obligacji nie jest dopisana) | |
| 144 | + |
| 145 | +#### Przykłady |
| 146 | + |
| 147 | +``` r |
| 148 | +cashflow_example_5 = bond(principal = 5000, maturity = 5, couponRate = 0.03) |
| 149 | +cfmatrix(cashflow_example_5) |
| 150 | +``` |
| 151 | + |
| 152 | + ## Payment 1 Payment 2 Payment 3 Payment 4 Payment 5 |
| 153 | + ## Period 1 2 3 4 5 |
| 154 | + ## Amount 150 150 150 150 5150 |
| 155 | + |
| 156 | +``` r |
| 157 | +cashflow_example_6 = bond(principal = 20, maturity = 10, boughtFor = 10) |
| 158 | +cfmatrix(cashflow_example_6) |
| 159 | +``` |
| 160 | + |
| 161 | + ## Payment 1 Payment 2 |
| 162 | + ## Period 0 10 |
| 163 | + ## Amount -10 20 |
| 164 | + |
| 165 | +### timevalue(cf, v, i, t, as.cashflow) |
| 166 | + |
| 167 | +Funkcja `timevalue` oblicza wartość przepływu pieniężnego w danej chwili |
| 168 | +przy konkretnych rynkowych stopach procentowych i oprocentowaniu |
| 169 | +złożonym. |
| 170 | + |
| 171 | +#### Argumenty |
| 172 | + |
| 173 | +| Nazwa | Opis | Przyjmowana wartość | Wymagany | |
| 174 | +|:------|:-------------------------|:--------------------|:------------------| |
| 175 | +| `cf` | przepływ, którego wartość chcemy obliczyć | przepływ pieniężny wygenerowany przez inną funkcję | Tak | |
| 176 | +| `v` | wartość/wartości czynnika dyskontującego | liczba lub wektor długości równej liczbie transakcji | Tak, o ile nie zdefiniowano `i` | |
| 177 | +| `i` | wartość/wartości stopy procentowej | liczba lub wektor długości równej liczbie transakcji | Tak, o ile nie zdefiniowano `v` | |
| 178 | +| `t` | czas, dla którego liczymy wartość | liczba | Nie, domyślnie 0 (wartość obecna) | |
| 179 | +| `as.cashflow` | zwrócenie przepływu zdyskontowanego do danej chwili zamiast liczby | wartość logiczna | Nie, domyślnie `FALSE` (funkcja zwraca liczbę) | |
| 180 | + |
| 181 | +**UWAGA:** Jeśli wprowadzasz `v` lub `i` jako wektor, upewnij się, że |
| 182 | +nie wpisujesz wartości dla kolejnych okresów zamiast kolejnych |
| 183 | +transakcji. |
| 184 | +**UWAGA 2:** Wprowadź jedną z wartości `v` lub `i`, ale nie obie |
| 185 | +jednocześnie. |
| 186 | + |
| 187 | +#### Przykłady |
| 188 | + |
| 189 | +``` r |
| 190 | +# Ile warte są kolejne wypłaty renty z przykładu 4? (załóżmy od 1 roku malejącą stopę procentową z 5% do 1% w kolejnych wypłatach) (stopa w roku 0 nie ma znaczenia, więc przyjęliśmy 6% dla ułatwienia) |
| 191 | +cashflow_example_4_rates = seq(0.06, 0.01, by=-0.01) |
| 192 | +cashflow_example_4_present_values = timevalue(cashflow_example_4, i = cashflow_example_4_rates, as.cashflow = TRUE) |
| 193 | +cfmatrix(cashflow_example_4_present_values) |
| 194 | +``` |
| 195 | + |
| 196 | + ## Payment 1 Payment 2 Payment 3 Payment 4 Payment 5 Payment 6 |
| 197 | + ## Period 0 1.0000 2.0000 3.0000 4.0000 5.0000 |
| 198 | + ## Amount 150 142.8571 138.6834 137.2712 138.5768 142.7199 |
| 199 | + |
| 200 | +``` r |
| 201 | +# Ile będzie warta obligacja z przykładu 5 w chwili jej zapadalności? (załóżmy stały czynnik dyskontujący 0.98) |
| 202 | +cashflow_example_5_maturity_value = timevalue(cashflow_example_5, v = 0.98, t = 5) |
| 203 | +cashflow_example_5_maturity_value |
| 204 | +``` |
| 205 | + |
| 206 | + ## [1] 5781.243 |
| 207 | + |
| 208 | +``` r |
| 209 | +# Ile zarobiliśmy na obligacji z przykładu 6? (załóżmy stałą stopę procentową 5%) |
| 210 | +cashflow_example_6_present_value = timevalue(cashflow_example_6, i = 0.05) |
| 211 | +cashflow_example_6_present_value |
| 212 | +``` |
| 213 | + |
| 214 | + ## [1] 2.278265 |
| 215 | + |
| 216 | +**UWAGA:** Istnieje też druga funkcja do obliczania obecnej wartości |
| 217 | +przepływu przy oprocentowaniu złożonym, `presentvalue`. Występuje ona ze |
| 218 | +względu na zgodność z poprzednimi wersjami skryptu i nie ma potrzeby jej |
| 219 | +stosowania (domyślnie `timevalue` i tak oblicza wartość bieżącą). |
| 220 | + |
| 221 | +### simpletimevalue(cf, i, method, t, as.cashflow) |
| 222 | + |
| 223 | +Funkcja `simpletimevalue` oblicza wartość przepływu pieniężnego w danej |
| 224 | +chwili przy konkretnych rynkowych stopach procentowych i oprocentowaniu |
| 225 | +prostym. |
| 226 | + |
| 227 | +#### Argumenty |
| 228 | + |
| 229 | +| Nazwa | Opis | Przyjmowana wartość | Wymagany | |
| 230 | +|:----|:------------------------------------|:---------------|:--------------| |
| 231 | +| `cf` | przepływ, którego wartość chcemy obliczyć | przepływ pieniężny wygenerowany przez inną funkcję | Tak | |
| 232 | +| `i` | wartość/wartości stopy procentowej | liczba lub wektor długości równej liczbie transakcji | Tak | |
| 233 | +| `t` | czas, dla którego liczymy wartość | liczba | Nie, domyślnie 0 (wartość obecna) | |
| 234 | +| `method` | metoda obliczania wartości przepływu pieniężnego (przepływy równoważne/ekwiwalentne lub metoda retrospektywnie-prospektywna) | `e` lub `rp` | Tak, chyba że `t == 0` | |
| 235 | +| `as.cashflow` | zwrócenie przepływu zdyskontowanego do danej chwili zamiast liczby | wartość logiczna | Nie, domyślnie `FALSE` (funkcja zwraca liczbę) | |
| 236 | + |
| 237 | +#### Przykłady |
| 238 | + |
| 239 | +``` r |
| 240 | +# Ile będzie warta obligacja z przykładu 5 w chwili jej zapadalności? (załóżmy stałą stopę procentową 7% i oprocentowanie proste) |
| 241 | +cashflow_example_5_maturity_value_si_rp = simpletimevalue(cashflow_example_5, i = 0.07, t = 5, method = "rp") |
| 242 | +cashflow_example_5_maturity_value_si_e = simpletimevalue(cashflow_example_5, i = 0.07, t = 5, method = "e") |
| 243 | + |
| 244 | +# kolejno wynik metodą retrospektywnie-prospektywn i przepływów równoważnych: |
| 245 | +c(cashflow_example_5_maturity_value_si_rp, cashflow_example_5_maturity_value_si_e) |
| 246 | +``` |
| 247 | + |
| 248 | + ## [1] 5855.000 5842.442 |
| 249 | + |
| 250 | +``` r |
| 251 | +# Ile zarobiliśmy na obligacji z przykładu 6? (załóżmy stałą stopę procentową 5% i oprocentowanie proste) |
| 252 | +cashflow_example_6_present_value_si = simpletimevalue(cashflow_example_6, i = 0.05) |
| 253 | +cashflow_example_6_present_value_si |
| 254 | +``` |
| 255 | + |
| 256 | + ## [1] 3.333333 |
| 257 | + |
| 258 | +## Więcej przykładów |
| 259 | + |
| 260 | +### Zadanie 1 |
| 261 | + |
| 262 | +Wyznacz wartość obecną przepływu nieskończonego, który dla parzystych |
| 263 | +chwil n wypłaca wartość *1/n*, a dla nieparzystych wypłaca *1/n^2* dla |
| 264 | +*i = 0.02*. |
| 265 | + |
| 266 | +**Rozwiązanie:** |
| 267 | + |
| 268 | +``` r |
| 269 | +cashflow_task_1_1 = cashflow(periods = 2*(1:10000), payments = 1/(2*(1:10000))) |
| 270 | + |
| 271 | +cashflow_task_1_2 = cashflow(periods = 2*(1:10000) - 1, payments = (1/(2*(1:10000)) - 1)^2) |
| 272 | + |
| 273 | +cashflow_task_1 = cfmerge(cashflow_task_1_1, cashflow_task_1_2) |
| 274 | + |
| 275 | +timevalue(cashflow_task_1, i=0.02) |
| 276 | +``` |
| 277 | + |
| 278 | + ## [1] 23.93494 |
| 279 | + |
| 280 | +### Zadanie 2 |
| 281 | + |
| 282 | +Podaj różnicę między wartością renty dziesięcioletniej płatnej z góry o |
| 283 | +wysokości 400 zł w chwili ostatniej wypłaty a teraz. Załóż |
| 284 | +oprocentowanie proste w wysokości i=0.10 i metodę przepływów |
| 285 | +równoważnych. |
| 286 | + |
| 287 | +**Rozwiązanie:** |
| 288 | + |
| 289 | +``` r |
| 290 | +cashflow_task_2 = annuity(period = 10, amount = 400, due = TRUE) |
| 291 | +cfmatrix(cashflow_task_2) |
| 292 | +``` |
| 293 | + |
| 294 | + ## Payment 1 Payment 2 Payment 3 Payment 4 Payment 5 Payment 6 Payment 7 |
| 295 | + ## Period 0 1 2 3 4 5 6 |
| 296 | + ## Amount 400 400 400 400 400 400 400 |
| 297 | + ## Payment 8 Payment 9 Payment 10 |
| 298 | + ## Period 7 8 9 |
| 299 | + ## Amount 400 400 400 |
| 300 | + |
| 301 | +``` r |
| 302 | +simpletimevalue(cashflow_task_2, i = 0.1, t = 9, method="e") - simpletimevalue(cashflow_task_2, i = 0.1, method="e") |
| 303 | +``` |
| 304 | + |
| 305 | + ## [1] 2587.577 |
| 306 | + |
| 307 | +### Zadanie 3 |
| 308 | + |
| 309 | +Dla jakiej stopy przy oprocentowaniu prostym dziesięcioletnia obligacja |
| 310 | +zerokuponowa jest równoważna tej obligacji przy stopie 5% i |
| 311 | +oprocentowaniu złożonym? |
| 312 | + |
| 313 | +**Rozwiązanie:** |
| 314 | + |
| 315 | +``` r |
| 316 | +# bierzemy dowolny dodatni nominał obligacji |
| 317 | +cashflow_task_3 = bond(principal = 1, maturity = 10) |
| 318 | +for (i in (1:1000)/1000) { |
| 319 | + if (simpletimevalue(cashflow_task_3, i=i) < timevalue(cashflow_task_3, i=0.05)) { |
| 320 | + print(i) |
| 321 | + break() |
| 322 | + } |
| 323 | +} |
| 324 | +``` |
| 325 | + |
| 326 | + ## [1] 0.063 |
0 commit comments