shippy / ratadata-savings

A website utilizing Czech open data to provide personal savings recommendation.
0 stars 1 forks source link

Vytvořit vzorec pro doporučené měsíční důchodové spoření #2

Closed shippy closed 11 years ago

shippy commented 11 years ago

To take into current income, current savings, average expected income raise, account inflation, interest rate, target age (whether user-supplied or calculated) - and any number of other factors we can come up with.

shippy commented 11 years ago

V rámci prvního implementačního nástřelu jsem si řekl, že první draft vzorce spíchnu sám.

Tady je v TeXu rovnice value at retirement = discounted dividend payment (obrázek):

\big(\frac{1+s}{1+i}\big)^{12(R-a)}S
+ \sum_{j={12a}}^{12R} x\big(\frac{1+s}{1+i}\big)^{j-12a}
= \sum_{j=R}^{T} D(1+i)^{j}

image

kde

Vyjádřením x získám následující rovnici (obrázek):

x = \frac{\sum_{j={12R}}^{12T} D(1+i)^\frac{j}{12}
- \big(\frac{1+s}{1+i}\big)^{12(R-a)}S}
{12(R-a) \sum_{j={12a}}^{12R} \big(\frac{1+s}{1+i}\big)^{\frac{j}{12}-a}}

image

Rovnici jsem ještě netestoval, ale mám k ní sepsaný PHP kód v commitu 1c0d3ec4d5e509af14dd0fb80144afb515f8c3aa, který je možná přehlednější než LaTeX:

function getMonthlySavings($age_current, $age_retirement, $age_terminal,
          $rate_inflation, $rate_interest, // yearly
          $monthly_current, $monthly_desired, // income
          $savings_current) {

    $real_rate = (1+$rate_interest) / (1+$rate_inflation); // yearly

    $desired_total = 0;
    for ($i = $age_retirement; $i <= $age_terminal; $i++) {
        // counting monthly inflation for simplification // += operator adds to current value
        $desired_total += (12 * $monthly_desired * pow(1 + $rate_inflation, $i - $age_retirement));
    }

    $savings_value_at_retirement = $savings_current * pow($real_rate, $age_retirement - $age_current);

    $discounting = 0;
    for ($i = 12 * $age_current; $i < 12 * $age_retirement; $i++) {
        $discounting += pow($real_rate, $i - 12 * $age_current);
    }
    $discounting *= 12*($age_retirement - $age_current);

    return (($desired_total - $savings_value_at_retirement) / $discounting);
}

Chybí a dá se zlepšit:

shippy commented 11 years ago

Testování odhalilo, že vzorec je špatně; není mi úplně jasné, kde se stala chyba, ale někde je. Takže hlavní zlepšení je najít chybu.

shippy commented 11 years ago

Verze převedená na roční počítání, která dává rozumné výsledky, je následující:

image

S*R^{t_{work}} + \sum_{j=1}^{t_{work}} ({xR^j})
= \sum_{j=1}^{t_{retirement}} ({D(1+i)^j})

kde všechny proměnné fungují na roční bázi. Písmenka jsou stejná jako minule, jen:

Vyjádření pro požadovanou roční důchodovou dividendu je potom

image

x = \frac{\sum_{j=1}^{t_{retirement}} ({D(1+i)^j}) - S*R^{t_{work}}}
{t_{work}*\sum_{j=1}^{t_{work}} {R^j}}

To pořád není optimální. Issues:

Roční důchodová dividenda ale není špatná proměnná, takže si ji asi má smysl nechat.

shippy commented 11 years ago

Vytvoření odlišných rozhraní pro měsíční a roční vstupy / výpočty je jiná issue; zavírám.