Beispiel #1
0
        private void SetWD(Model m, double[] withdrawals)
        {
            double essentialWD = Globals.Singleton().EssentialsPercent / 100.0 * Globals.Singleton().StartSum * Market.NormativeStepWD(m);
            int nSmallishWD = 0;
            foreach (var w in withdrawals)
            {
                if (w < essentialWD)
                    nSmallishWD++;
            }
            this.InsufficientWdRrate = (double)nSmallishWD * 100.0 / (double)withdrawals.Length;

            double[] binCounts = new double[Globals.Singleton().WDBins];
            for (int i = 0; i < binCounts.Length; i++)
                binCounts[i] = 0.0;

            this.WithdrawalAver = withdrawals.Average();
            this.WithdrawalMax = withdrawals.Max();
            this.WithdrawalMin = withdrawals.Min();
            double count = 0;
            double norm = Globals.Singleton().StartSum * Market.NormativeStepWD(m);
            foreach (double wd in withdrawals)
            {
                int ind = Globals.Singleton().Quantile(wd / norm);
                binCounts[ind] = binCounts[ind] + 1.0;
                count = count + 1.0;
            }

            this.WDistrib = new double[Globals.Singleton().WDBins];
            for (int i = 0; i < Globals.Singleton().WDBins; i++)
                WDistrib[i] = binCounts[i] / count;
        }
Beispiel #2
0
 public SingleRunResult(string country, Model m,
     double trailingAmount, double[] withdrawals)
 {
     this.Country = country;
     this.TrailingAmount = trailingAmount;
     SetWD(m, withdrawals);
 }
Beispiel #3
0
        public SingleRunResult(string country, Model m,
            double trailingAmount, double[] withdrawals1, double[] withdrawals2)
        {
            this.Country = country;
            this.TrailingAmount = trailingAmount;

            int len = withdrawals1.Length;
            if (len != withdrawals2.Length)
                throw new Exception("Wrong lens");
            double[] withdrawals = new double[len];
            for (int i = 0; i < len; i++)
                withdrawals[i] = withdrawals1[i] + withdrawals2[i];

            SetWD(m, withdrawals);
        }
Beispiel #4
0
        public static Model SweepModel(Model mp, SweepParameters sw, Country c)
        {
            Model m = new Model(mp.Strategy, mp.StartEq, mp.StartBo, mp.YearlyWithdrawal, mp.RebalanceEvery, c.Filename);
            if (sw.Strategy >= 0)
                m.Strategy = sw.Strategy;
            if (sw.Equity >= 0)
                m.StartEq = sw.Equity;
            if (sw.Bonds >= 0)
                m.StartBo = sw.Bonds;
            if (sw.WithdrawalRate >= 0)
                m.YearlyWithdrawal = sw.WithdrawalRate;
            if (sw.WorldShare >= 0)
                m.WorldShare = sw.WorldShare;

            return m;
        }
Beispiel #5
0
 public static void WriteResult(StreamWriter sw, Model mm, ModelResult mr, object printlock)
 {
     lock (printlock)
     {
         Utils.WriteResult(sw,
             mm.CountryName, 
             mm.Strategy,
             mm.StartEq,      mm.StartBo,
             mm.YearlyWithdrawal, 
             mm.RebalanceEvery,
             mm.WorldShare,
             mr.trailAverage, mr.trailMax, mr.trailMin,
             mr.withdrawalAverage, mr.withdrawalMax, mr.withdrawalMin,
             mr.WDistrib,
             mr.productivity,
             mr.trailSuccessRate, mr.withdrawalSuccessRate, mr.overallSuccessRate);
     }
 }
Beispiel #6
0
        public ModelResult(Model m, List<SingleRunResult> results)
        {
            this.model = m;
            this.WDistrib = new double[Globals.Singleton().WDBins];
            for (int i = 0; i < Globals.Singleton().WDBins; i++)
            {
                this.WDistrib[i] = 0;
                foreach (var r in results)
                    this.WDistrib[i] = this.WDistrib[i] + r.WDistrib[i];
                this.WDistrib[i] /= results.Count;
            }

            int failures = 0, successes = 0;
            trailSuccessRate = Market.CheckTrailingAmount(results, ref failures, ref successes);

            withdrawalSuccessRate = Market.CheckWithdrawals(results, ref failures, ref successes);
            trailAverage = withdrawalAverage = 0;
            trailMin = withdrawalMin = double.MaxValue;
            trailMax = withdrawalMax = double.MinValue;

            overallSuccessRate = Market.CheckOverall(results, ref failures, ref successes);

            int count = 0;
            foreach (var sr in results)
            {
                trailAverage += sr.TrailingAmount;
                trailMax = Math.Max(trailMax, sr.TrailingAmount);
                trailMin = Math.Min(trailMin, sr.TrailingAmount);
                withdrawalAverage += sr.WithdrawalAver;
                withdrawalMax = Math.Max(withdrawalMax, sr.WithdrawalMax);
                withdrawalMin = Math.Min(withdrawalMin, sr.WithdrawalMin);
                count++;
            }

            this.trailAverage /= (count * 1000000.0);
            this.trailMax = trailMax / 1000000.0;
            this.trailMin = trailMin / 1000000.0;
            this.withdrawalAverage /= count;
            this.withdrawalAverage *= (Utils.StepsInYear / 1000.0);
            this.withdrawalMax *= (Utils.StepsInYear / 1000.0);
            this.withdrawalMin *= (Utils.StepsInYear / 1000.0);
            this.productivity = this.withdrawalAverage * 1000.0 / Globals.Singleton().StartSum * 100.0;
        }
Beispiel #7
0
        public static void RunSingleStep(
            int c, int r, Model m, double initialWithdrawal,
            ref double eq, ref double bo, ref double bi, 
            Distro distroEq, Distro distroBo, Distro distroBi,
            ref double[] prior, ref double curWithdrawal, 
            ref List<double> withdrawals)
        {
            // Market play
            eq *= (1.0 + distroEq.Play());
            bo *= (1.0 + distroBo.Play());
            bi *= (1.0 + distroBi.Play());

            // Calculate desired withdrawal on this step
            switch(m.Strategy)
            {
                case 1:
                    curWithdrawal = initialWithdrawal;
                    break;
                case 2:
                    curWithdrawal = (eq + bo + bi) * NormativeStepWD(m);
                    break;
                case 3:
                    if (c >= (int)(3 * Utils.StepsInYear) &&
                        c % ((int)Utils.StepsInYear) == 0)
                        curWithdrawal = prior.Average() * NormativeStepWD(m);
                    break;
                default:
                    throw new Exception("Unknown strategy");
            }

            // Calculate actual total step withdrawal
            double actualWithdrawal = Math.Min(eq + bo + bi, curWithdrawal);
            double allocated = 0;

            if (bi > 0)
            {
                double d = Math.Min(bi, actualWithdrawal * (bi / (eq + bo + bi)));
                allocated += d;
                bi -= d;
            }
            if (bo > 0)
            {
                double d = Math.Min(bo, actualWithdrawal * (bo / (eq + bo + bi)));
                allocated += d;
                bo -= d;
            }
            if (eq > 0)
            {
                double d = Math.Min(eq, actualWithdrawal * (eq / (eq + bo + bi)));
                allocated += d;
                eq -= d;
            }

            if (allocated < actualWithdrawal)
            {
                double d = Math.Min(bi, actualWithdrawal - allocated);
                bi -= d;
                allocated += d;

                d = Math.Min(bo, actualWithdrawal - allocated);
                bo -= d;
                allocated += d;

                d = Math.Min(eq, actualWithdrawal - allocated);
                eq -= d;
                allocated += d;
            }

            withdrawals.Add(actualWithdrawal);

            double total = eq + bo + bi;

            // Rebalance evert X steps, if requested
            if (m.RebalanceEvery > 0 && r % m.RebalanceEvery == 0)
            {
                eq = total * m.StartEq / 100.0;
                bo = total * m.StartBo / 100.0;
                bi = total - eq - bo;
            }

            // Remember priors
            for (int y = 1; y < prior.Length; y++)
            {
                prior[y - 1] = prior[y];
            }
            prior[prior.Length - 1] = total;
        }
Beispiel #8
0
        public static List<SingleRunResult> RunDoublePortfolioExperiment(
            Model m, 
            double share2,
            Distro distroEq1, Distro distroBo1, Distro distroBi1,
            Distro distroEq2, Distro distroBo2, Distro distroBi2)
        {
            int rebalanceEvery = m.RebalanceEvery;
            double initWD = Globals.Singleton().StartSum * NormativeStepWD(m);
            double initWD1 = initWD * (1.0 - share2);
            double initWD2 = initWD * (share2);
            double curWD1 = initWD1;
            double curWD2 = initWD2;
            double[] prior1 = new double[3 * (int)Utils.StepsInYear];
            double[] prior2 = new double[3 * (int)Utils.StepsInYear];

            List<SingleRunResult> results = new List<SingleRunResult>();

            for (int r = 0; r < Globals.Singleton().Repeats; r++)
            {
                double eq1 = (1.0 - share2) * Globals.Singleton().StartSum * m.StartEq / 100;
                double bo1 = (1.0 - share2) * Globals.Singleton().StartSum * m.StartBo / 100;
                double bi1 = (1.0 - share2) * Globals.Singleton().StartSum * (100 - m.StartEq - m.StartBo) / 100;
                if (eq1 < 0 || bo1 < 0 || bi1 < 0)
                    throw new Exception("Bad parameters");

                double eq2 = share2 * Globals.Singleton().StartSum * m.StartEq / 100;
                double bo2 = share2 * Globals.Singleton().StartSum * m.StartBo / 100;
                double bi2 = share2 * Globals.Singleton().StartSum * (100 - m.StartEq - m.StartBo) / 100;
                if (eq2 < 0 || bo2 < 0 || bi2 < 0)
                    throw new Exception("Bad parameters");

                //List<double> withdrawals = new List<double>();
                List<double> withdrawals1 = new List<double>();
                List<double> withdrawals2 = new List<double>();
                double curWd1 = initWD1;
                double curWd2 = initWD2;

                for (int c = 0; c < Globals.Singleton().Cycles; c++)
                {

                    RunSingleStep(c, r, m, initWD1,
                                  ref eq1, ref bo1, ref bi1,
                                  distroEq1, distroBo1, distroBi1,
                                  ref prior1, ref curWD1, ref withdrawals1);

                    RunSingleStep(c, r, m, initWD2,
                                  ref eq2, ref bo2, ref bi2,
                                  distroEq2, distroBo2, distroBi2,
                                  ref prior2, ref curWD2, ref withdrawals2);

                    //TODO: here comes portfolio parts re balancing
                }

                results.Add( 
                    new SingleRunResult(
                        m.CountryName, m, 
                        eq1 + bo1 + bi1 + eq2 + bo2 + bi2, 
                        withdrawals1.ToArray(), 
                        withdrawals2.ToArray()));

            }
            return results;
        }
Beispiel #9
0
 public static double NormativeStepWD(Model m)
 {
     return m.YearlyWithdrawal / 100.0 / Utils.StepsInYear;
 }
Beispiel #10
0
        public static List<SingleRunResult> RunSinglePortfolioExperiment(
            Model m, 
            Distro distroEq, Distro distroBo, Distro distroBi)
        {
            int rebalanceEvery = m.RebalanceEvery;
            double initWD = Globals.Singleton().StartSum * NormativeStepWD(m);
            double[] prior = new double[3 * (int)Utils.StepsInYear];

            List<SingleRunResult> singleRunResults = new List<SingleRunResult>();

            for (int r = 0; r < Globals.Singleton().Repeats; r++)
            {
                double eq = Globals.Singleton().StartSum * m.StartEq / 100;
                double bo = Globals.Singleton().StartSum * m.StartBo / 100;
                double bi = Globals.Singleton().StartSum * (100 - m.StartEq - m.StartBo) / 100;
                if (eq < 0 || bo < 0 || bi < 0)
                    throw new Exception("Bad parameters");

                List<double> withdrawals = new List<double>();
                double curWd = initWD;
                for (int c = 0; c < Globals.Singleton().Cycles; c++)
                {
                    // Market play
                    RunSingleStep(c, r, m, initWD, 
                                  ref eq, ref bo, ref bi, 
                                  distroEq, distroBo, distroBi, 
                                  ref prior, ref curWd, ref withdrawals);
                }

                singleRunResults.Add(new SingleRunResult("", m, eq + bo + bi, withdrawals.ToArray()));
            }
            return singleRunResults;
        }