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; }