Пример #1
0
        // Method used to calculate the financial goal.
        public static string CalculateGoal(double withdrawlRate, double taxRate, decimal currentInvestments, decimal retirementSpeding, decimal initialSavings, double returns, double savings, bool pegToInflation, double inflation)
        {
            double  time = 0;
            decimal goal = currentInvestments;
            decimal fix  = (decimal)((1 + taxRate) / withdrawlRate);
            decimal adjustedRetirementSpeding = retirementSpeding;

            if (!pegToInflation)
            {
                goal = retirementSpeding * fix;
                return(goal.ToString("C0"));
            }


            while (goal / fix < adjustedRetirementSpeding)
            {
                goal = currentInvestments;

                if (savings > 0)
                {
                    goal += FinanceCalculations.FutureVariableAnnuityValue(initialSavings, time, returns, savings, 365, 0, recurringInvestingFrequency);
                }
                else
                {
                    goal += FinanceCalculations.FutureFixedAnnuityValue(initialSavings, time, returns, 365, 0, recurringInvestingFrequency);
                }

                adjustedRetirementSpeding = FinanceCalculations.FutureValue(retirementSpeding, time, inflation);
                time++;
            }

            return(goal.ToString("C0"));
        }
Пример #2
0
        // Method used to find the future value of the repeated payments.
        private decimal CalculateAnnuity(double length, double rate)
        {
            int     frequency        = int.Parse(txtCompoundingFrequency.Text);
            decimal payment          = decimal.Parse(txtAnnuityPayment.Text, NumberStyles.Currency);
            int     immediately      = chkPaymentAt.Checked ? 1 : 0;
            int     paymentFrequency = int.Parse(txtPaymentFrequency.Text);
            double  growth           = double.Parse(txtPaymentGrowth.Text) / 100;

            if (growth == 0)
            {
                return(FinanceCalculations.FutureFixedAnnuityValue(payment, length, rate, frequency, immediately, paymentFrequency));
            }
            else
            {
                return(FinanceCalculations.FutureVariableAnnuityValue(payment, length, rate, growth, frequency, immediately, paymentFrequency));
            }
        }
Пример #3
0
        // An interative function that finds the rate to meet the goal within a given time.
        public static double GetRateOfGrowth(decimal goal, decimal startingBal, decimal initialSavings, double growth, double time)
        {
            decimal bal  = startingBal;
            double  rate = 0;

            while (bal < goal)
            {
                bal = FinanceCalculations.FutureValue(startingBal, time, rate, 365);
                if (growth > 0)
                {
                    bal += FinanceCalculations.FutureVariableAnnuityValue(initialSavings, time, rate, growth, 365, 0, recurringInvestingFrequency);
                }
                else
                {
                    bal += FinanceCalculations.FutureFixedAnnuityValue(initialSavings, time, rate, 365, 0, recurringInvestingFrequency);
                }
                rate += RATE_STEP;
            }

            return(rate);
        }
Пример #4
0
        // An interative function that finds the time to meet the goal.
        public static double GetTimeToGoal(decimal goal, decimal principal, decimal payment, double growth, double savingsGrowth)
        {
            double  time = 0;
            decimal bal  = 0;

            while (bal < goal)
            {
                bal  = 0;
                bal += FinanceCalculations.FutureValue(principal, time, growth);

                if (savingsGrowth > 0)
                {
                    bal += FinanceCalculations.FutureVariableAnnuityValue(payment, time, growth, savingsGrowth, 365, 0, recurringInvestingFrequency);
                }
                else
                {
                    bal += FinanceCalculations.FutureFixedAnnuityValue(payment, time, growth, 365, 0, recurringInvestingFrequency);
                }

                time += TIME_STEP;
            }

            return(time);
        }
Пример #5
0
        private void GenerateReturns()
        {
            // Set parameters
            bool incomeGrowthExcessOfInflation = chkInflationIncomeGrowthPeg.Checked;

            int projectionType   = cboProjection.SelectedIndex;
            int paymentFrequency = Investing.recurringInvestingFrequency;

            double bondAllocation            = double.Parse(txtBondFraction.Text) / 100;
            double stockAllocation           = double.Parse(txtStockFraction.Text) / 100;
            double inflationMean             = double.Parse(txtInflation.Text) / 100;
            double incomeGrowthRate          = double.Parse(txtIncomeGrowth.Text) / 100 + (incomeGrowthExcessOfInflation ? inflationMean : 0);
            double savingsGrowthRateFraction = double.Parse(txtSavingFractionGrowth.Text) / 100;
            double bReturns          = double.Parse(txtBondReturns.Text) / 100;
            double sReturns          = double.Parse(txtStockReturns.Text) / 100;
            double savingsGrowthRate = savingsGrowthRateFraction * incomeGrowthRate;
            double time = 0;

            decimal currentInvestments = decimal.Parse(txtPrincipal.Text, NumberStyles.Currency);
            decimal initialSavings     = decimal.Parse(txtIncome.Text, NumberStyles.Currency) - decimal.Parse(txtSpending.Text, NumberStyles.Currency);
            decimal goal = decimal.Parse(txtSavingsGoal.Text, NumberStyles.Currency);

            carcInvestment.Series.Clear();

            // 0 = fixed returns, 1 = monte-carlo; TODO: 2 = historical cycles
            if (projectionType == 0)
            {
                // Fixed Returns

                double averageReturn = Investing.PortfolioWeightedAverageReturn(bondAllocation, stockAllocation, bReturns, sReturns);
                double timeToRetire  = Investing.GetTimeToGoal(goal, currentInvestments, initialSavings, averageReturn, savingsGrowthRate);

                decimal[] total     = new decimal[(int)timeToRetire + 5];
                decimal[] returns   = new decimal[(int)timeToRetire + 5];
                decimal[] principal = new decimal[(int)timeToRetire + 5];

                // Generate return arrays
                for (int i = 0; i < (int)timeToRetire + 5; i++)
                {
                    principal[i] += currentInvestments;
                    total[i]     += FinanceCalculations.FutureValue(currentInvestments, i, averageReturn, 365);

                    if (savingsGrowthRate > 0)
                    {
                        total[i]     += FinanceCalculations.FutureVariableAnnuityValue(initialSavings, i, averageReturn, savingsGrowthRate, 365, 0, paymentFrequency);
                        principal[i] += FinanceCalculations.FutureVariableAnnuityValue(initialSavings, i, 0, savingsGrowthRate, 365, 0, paymentFrequency);
                    }
                    else
                    {
                        total[i]     += FinanceCalculations.FutureFixedAnnuityValue(initialSavings, i, averageReturn, 365, 0, paymentFrequency);
                        principal[i] += initialSavings * i;
                    }
                    returns[i] = total[i] - principal[i];
                }

                GenerateChart(total, "Total");
                GenerateChart(returns, "Return");
                GenerateChart(principal, "Principal", goal, timeToRetire);
                time = timeToRetire;
            }
            else if (projectionType == 1)
            {
                // Monte-Carlo

                int simulations = 50000;
                //double inflationVolatility = 0.0119;
                double stockVolatility = 0.5;
                double bondVolatility  = 0.03;

                double[] percentileList       = { 0.9, 0.75, 0.5, 0.25, 0.1 };
                double[] lengths              = new double[simulations];
                double[] percentileLengths    = new double[percentileList.Length];
                double[] averageRatesOfGrowth = new double[percentileList.Length];

                decimal[][] percentileReturns = new decimal[percentileList.Length][];

                //Run the simulations to find lengths
                for (int i = 0; i < simulations; i++)
                {
                    decimal x = currentInvestments;
                    Random  r = new Random(DateTime.Now.Ticks.GetHashCode());
                    lengths[i] = 0;
                    while (x < goal)
                    {
                        // Randomly generated return of the portfolio
                        double pReturn = Investing.CalculateRandomPortfolioReturn(bReturns, bondVolatility, bondAllocation, sReturns, stockVolatility, stockAllocation, r);

                        // Caluculate portfolio value at the end of the year
                        x *= 1 + (decimal)pReturn;

                        // Add savings to portfolio
                        if (savingsGrowthRate > 0)
                        {
                            x += FinanceCalculations.FutureValue(initialSavings, lengths[i], savingsGrowthRate, 1);
                        }
                        else
                        {
                            x += initialSavings * i;
                        }

                        lengths[i]++;
                    }
                }

                for (int i = 0; i < percentileList.Length; i++)
                {
                    // Get length percentiles
                    percentileLengths[i] = FinanceCalculations.Percentile(lengths, percentileList[i]);

                    // Find equivelant growth rate
                    averageRatesOfGrowth[i] = Investing.GetRateOfGrowth(goal, currentInvestments, initialSavings, savingsGrowthRate, percentileLengths[i]);

                    // Initialize the array with the 90th percentile in length + 2
                    percentileReturns[i] = new decimal[(int)percentileLengths[0] + 2];

                    //Calculate return array
                    for (int j = 0; j < (int)percentileLengths[0] + 2; j++)
                    {
                        percentileReturns[i][j] += FinanceCalculations.FutureValue(currentInvestments, j, averageRatesOfGrowth[i], 365);

                        if (savingsGrowthRate > 0)
                        {
                            percentileReturns[i][j] += FinanceCalculations.FutureVariableAnnuityValue(initialSavings, j, averageRatesOfGrowth[i], savingsGrowthRate, 365, 0, paymentFrequency);
                        }
                        else
                        {
                            percentileReturns[i][j] += FinanceCalculations.FutureFixedAnnuityValue(initialSavings, j, averageRatesOfGrowth[i], 365, 0, paymentFrequency);
                        }
                    }
                }

                for (int i = 0; i < percentileLengths.Length; i++)
                {
                    int k = percentileList.Length - i - 1;
                    GenerateChart(percentileReturns[k], (100 * percentileList[i]).ToString("0") + "th Percentile Returns", goal, percentileLengths[2]);
                }

                time = percentileLengths[2];
            }

            PrintResults(time);
        }