コード例 #1
0
ファイル: Distro.cs プロジェクト: alexdad/MarketModel
        public static void Prepare(
            List <int> equityChanges, List <int> bondChanges, List <int> billChanges,
            Distro distroEquities, Distro distroBonds, Distro distroBills,
            Object printlock)
        {
            int[] cases = { 1, 2, 3 };
            var   res1  = Parallel.ForEach(
                cases,
                (t) =>
            {
                List <int> testValues = new List <int>();
                Distro distroTest     = new Distro(Globals.Singleton().Bins);
                switch (t)
                {
                case 1:
                    Distro.PrepareDistribution(
                        equityChanges, distroEquities,
                        Globals.Singleton().Bins, "DistroEquities.csv", printlock);
                    break;

                case 2:
                    Distro.PrepareDistribution(
                        bondChanges, distroBonds,
                        Globals.Singleton().Bins, "DistroBonds.csv", printlock);
                    break;

                case 3:
                    Distro.PrepareDistribution(
                        billChanges, distroBills,
                        Globals.Singleton().Bins, "DistroBills.csv", printlock);
                    break;
                }
            });
        }
コード例 #2
0
ファイル: Experiments.cs プロジェクト: alexdad/MarketModel
        // Sweep run for a single portfolio
        public static void ExecuteSweepSingle(
            List <Country> countries,
            List <Model> models,
            SweepParameters[] sweeps,
            ConcurrentBag <ModelResult> modelResults,
            StreamWriter swr,
            Object printlock)
        {
            Country c = new Country("", 0, 0, 0.0, 0.0, 0.0, 0.0, 0);

            List <int> equityChanges = new List <int>();
            List <int> bondChanges   = new List <int>();
            List <int> billChanges   = new List <int>();

            GraphAcquierer.Acquire(countries, equityChanges, bondChanges, billChanges, printlock);

            Distro distroEquities = new Distro(Globals.Singleton().Bins);
            Distro distroBonds    = new Distro(Globals.Singleton().Bins);
            Distro distroBills    = new Distro(Globals.Singleton().Bins);

            Distro.Prepare(
                equityChanges, bondChanges, billChanges,
                distroEquities, distroBonds, distroBills,
                printlock);

            Distro.Test(
                distroEquities, distroBonds, distroBills,
                printlock);

            lock (printlock)
            {
                Console.WriteLine(Utils.ResultHeader);
            }

            var res2 = Parallel.ForEach(
                models,
                (m) =>
            {
                var res1 = Parallel.ForEach(
                    sweeps,
                    (sw) =>
                {
                    Model mm = Model.SweepModel(m, sw, c);
                    if (mm.Validate())
                    {
                        List <SingleRunResult> result = Market.RunSinglePortfolioExperiment(
                            mm,
                            distroEquities, distroBonds, distroBills);

                        ModelResult mr = new ModelResult(mm, result);
                        modelResults.Add(mr);
                        Utils.WriteResult(null, mm, mr, printlock);
                        Utils.WriteResult(swr, mm, mr, printlock);
                    }
                });
            });
        }
コード例 #3
0
ファイル: Distro.cs プロジェクト: alexdad/MarketModel
        public static void PrepareDistribution(
            List <int> changes, Distro distro, int bins, string resultPath, Object printLock)
        {
            int minChange = changes.Min();
            int maxChange = changes.Max();
            int span      = maxChange - minChange;

            if (span == 0)
            {
                lock (printLock)
                {
                    Console.WriteLine("CANNOT CREATE {0} - no changes: {1} , { 2}", resultPath, minChange, maxChange);
                }
                return;
            }

            int[] counts = new int[bins];
            for (int i = 0; i < bins; i++)
            {
                counts[i] = 0;
            }
            int binSize = span / bins + 1;

            foreach (int c in changes)
            {
                int binNo = (c - minChange) / binSize;
                counts[binNo]++;
            }

            using (StreamWriter sw = new StreamWriter(resultPath))
            {
                for (int j = 0; j < bins; j++)
                {
                    double mid     = minChange + binSize / 2 + binSize * j;
                    double binProb = (double)counts[j] / (double)changes.Count;
                    sw.WriteLine("{0:F2},{1:F2},", mid, binProb * 100.0);

                    distro.AddBin(mid, binProb);
                }
            }

            lock (printLock)
            {
                Console.WriteLine("Accumulated: {0}", distro.GetAccumulation());
            }
        }
コード例 #4
0
ファイル: Distro.cs プロジェクト: alexdad/MarketModel
        public static void Test(
            Distro distroEquities, Distro distroBonds, Distro distroBills,
            Object printlock)
        {
            int[] tests = { 1, 2, 3 };
            var   res1  = Parallel.ForEach(
                tests,
                (t) =>
            {
                List <int> testValues = new List <int>();
                Distro distroTest     = new Distro(Globals.Singleton().Bins);
                switch (t)
                {
                case 1:
                    for (int i = 0; i < 10000000; i++)
                    {
                        testValues.Add((int)(distroEquities.Play() * Utils.PercentageScale));
                    }
                    Distro.PrepareDistribution(
                        testValues, distroTest,
                        Globals.Singleton().Bins, "testEq.csv", printlock);
                    break;

                case 2:
                    for (int i = 0; i < 10000000; i++)
                    {
                        testValues.Add((int)(distroBonds.Play() * Utils.PercentageScale));
                    }
                    Distro.PrepareDistribution(
                        testValues, distroTest,
                        Globals.Singleton().Bins, "testBo.csv", printlock);
                    break;

                case 3:
                    for (int i = 0; i < 10000000; i++)
                    {
                        testValues.Add((int)(distroBills.Play() * Utils.PercentageScale));
                    }
                    Distro.PrepareDistribution(
                        testValues, distroTest,
                        Globals.Singleton().Bins, "testBi.csv", printlock);
                    break;
                }
            });
        }
コード例 #5
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);
        }
コード例 #6
0
ファイル: Experiments.cs プロジェクト: alexdad/MarketModel
        // One run for a 2-part portfolio
        public static void ExecuteDouble(
            List <Country> countries,
            List <Model> models,
            ConcurrentBag <ModelResult> modelResults,
            StreamWriter swr,
            Object printlock)
        {
            // Separate countries into 2 groups: 2=WORLD, 1=all others
            double         weight1 = 0.0, weight2 = 0.0;
            List <Country> countries1 = new List <Country>();
            List <Country> countries2 = new List <Country>();

            foreach (Country c in countries)
            {
                if (Globals.IsWorld(c.Filename))
                {
                    countries2.Add(c);
                    weight2 += c.Weight;
                }
                else
                {
                    countries1.Add(c);
                    weight1 += c.Weight;
                }
            }
            if (weight1 <= 0 || weight2 <= 0)
            {
                throw new Exception("Cannot find the world or others");
            }

            // Group2 is just the World
            List <int> equityChanges2 = new List <int>();
            List <int> bondChanges2   = new List <int>();
            List <int> billChanges2   = new List <int>();

            GraphAcquierer.Acquire(countries2, equityChanges2, bondChanges2, billChanges2, printlock);

            Distro distroEquities2 = new Distro(Globals.Singleton().Bins);
            Distro distroBonds2    = new Distro(Globals.Singleton().Bins);
            Distro distroBills2    = new Distro(Globals.Singleton().Bins);

            Distro.Prepare(
                equityChanges2, bondChanges2, billChanges2,
                distroEquities2, distroBonds2, distroBills2,
                printlock);

            // Group1 is all except World
            List <int> equityChanges1 = new List <int>();
            List <int> bondChanges1   = new List <int>();
            List <int> billChanges1   = new List <int>();

            GraphAcquierer.Acquire(countries1, equityChanges1, bondChanges1, billChanges1, printlock);

            Distro distroEquities1 = new Distro(Globals.Singleton().Bins);
            Distro distroBonds1    = new Distro(Globals.Singleton().Bins);
            Distro distroBills1    = new Distro(Globals.Singleton().Bins);

            Distro.Prepare(
                equityChanges1, bondChanges1, billChanges1,
                distroEquities1, distroBonds1, distroBills1,
                printlock);

            lock (printlock)
            {
                Console.WriteLine(Utils.ResultHeader);
            }

            var res = Parallel.ForEach(
                models,
                (m) =>
            {
                if (m.Validate())
                {
                    List <SingleRunResult> result = Market.RunDoublePortfolioExperiment(
                        m,
                        weight2 / (weight1 + weight2),
                        distroEquities1, distroBonds1, distroBills1,
                        distroEquities2, distroBonds2, distroBills2);

                    ModelResult mr = new ModelResult(m, result);
                    modelResults.Add(mr);
                    Utils.WriteResult(null, m, mr, printlock);
                    Utils.WriteResult(swr, m, mr, printlock);
                }
            });
        }
コード例 #7
0
ファイル: Experiments.cs プロジェクト: alexdad/MarketModel
        // Sweep run for a double-part portfolio  by country
        public static void ExecuteSweepDoubleByCountry(
            List <Country> countries,
            List <Model> models,
            SweepParameters[] sweeps,
            ConcurrentBag <ModelResult> modelResults,
            StreamWriter swr,
            Object printlock)
        {
            // Group2 is just the World
            List <Country> countries2 = new List <Country>();

            foreach (Country c in countries)
            {
                if (Globals.IsWorld(c.Filename))
                {
                    countries2.Add(c);
                    countries2.Last().Weight = 1;
                }
            }

            List <int> equityChanges2 = new List <int>();
            List <int> bondChanges2   = new List <int>();
            List <int> billChanges2   = new List <int>();

            GraphAcquierer.Acquire(countries2, equityChanges2, bondChanges2, billChanges2, printlock);

            Distro distroEquities2 = new Distro(Globals.Singleton().Bins);
            Distro distroBonds2    = new Distro(Globals.Singleton().Bins);
            Distro distroBills2    = new Distro(Globals.Singleton().Bins);

            Distro.Prepare(
                equityChanges2, bondChanges2, billChanges2,
                distroEquities2, distroBonds2, distroBills2,
                printlock);

            // Now enumerate countries; Group1 each time will carry just one
            foreach (var c in countries)
            {
                if (Globals.IsWorld(c.Filename))
                {
                    continue;
                }
                List <Country> countries1 = new List <Country>();
                countries1.Add(c);
                countries1.Last().Weight = 1;

                // Group1 is just one country
                List <int> equityChanges1 = new List <int>();
                List <int> bondChanges1   = new List <int>();
                List <int> billChanges1   = new List <int>();

                GraphAcquierer.Acquire(countries1, equityChanges1, bondChanges1, billChanges1, printlock);

                Distro distroEquities1 = new Distro(Globals.Singleton().Bins);
                Distro distroBonds1    = new Distro(Globals.Singleton().Bins);
                Distro distroBills1    = new Distro(Globals.Singleton().Bins);

                Distro.Prepare(
                    equityChanges1, bondChanges1, billChanges1,
                    distroEquities1, distroBonds1, distroBills1,
                    printlock);

                lock (printlock)
                {
                    Console.WriteLine(Utils.ResultHeader);
                }

                var res2 = Parallel.ForEach(
                    models,
                    (m) =>
                {
                    var res1 = Parallel.ForEach(
                        sweeps,
                        (sw) =>
                    {
                        Model mm = Model.SweepModel(m, sw, c);
                        if (mm.Validate())
                        {
                            if (mm.StartEq + mm.StartBo <= 100)
                            {
                                List <SingleRunResult> result = Market.RunDoublePortfolioExperiment(
                                    mm,
                                    sw.WorldShare,
                                    distroEquities1, distroBonds1, distroBills1,
                                    distroEquities2, distroBonds2, distroBills2);

                                ModelResult mr = new ModelResult(mm, result);
                                modelResults.Add(mr);
                                Utils.WriteResult(null, mm, mr, printlock);
                                Utils.WriteResult(swr, mm, mr, printlock);
                            }
                        }
                    });
                });

                c.Weight = 0;
            }
        }
コード例 #8
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;
        }
コード例 #9
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);
        }