public SimulationSetupViewModel(SimulationSetup model)
        {
            ResetToDefaultsCommand = new DelegateCommand(DoResetToDefaults);

            if (model != null)
            {
                Start       = model.Start;
                End         = model.End;
                UseSnowball = model.UseSnowball;
            }
            else
            {
                DoResetToDefaults();
            }
        }
예제 #2
0
        public SimulationState(Profile profile, SimulationSetup setup)
        {
            IsSnowball = setup.UseSnowball;

            Accounts     = profile.Accounts.Select(a => new SimulationBankAccount(a)).ToDictionary(a => a.Id);
            Bills        = profile.Bills.Select(b => new SimulationBill(setup.Start, b)).ToDictionary(b => b.Id);
            Debts        = profile.Debts.Select(d => new SimulationDebtAccount(setup.Start, d)).ToDictionary(d => d.Id);
            Paychecks    = profile.Paychecks.Select(p => new SimulationPaycheck(setup.Start, p)).ToDictionary(p => p.Id);
            Transactions = profile.Transactions.Select(t => new SimulationTransaction(setup.Start, t)).ToDictionary(t => t.Id);
            Events       = profile.Events.All().ToLookup(e => e.Date);

            SnowballPool = new Queue <SimulationDebtAccount>(Debts.Values
                                                             .Select((d, i) => (debt: d, order: GetDebtOrder(d, profile.Snowball, i)))
                                                             .OrderBy(t => t.order)
                                                             .Select(t => t.debt));
            SnowballTarget = SnowballPool.SafeDequeue();
            SnowballAmount = profile.Snowball.InitialAmount;

            Results = new Dictionary <IAccount, List <SimulationResultItem> >();

            AddToSnowball(setup.Start, 0);
        }
예제 #3
0
        public static async Task <Dictionary <IAccount, List <SimulationResultItem> > > Run(SimulationSetup setup, Profile profile)
        {
            var cloned = await Task.Run(() => profile.Clone());

            return(await Task.Run(() => RunInternal(setup, cloned)));
        }
예제 #4
0
        private static Dictionary <IAccount, List <SimulationResultItem> > RunInternal(SimulationSetup setup, Profile profile)
        {
            var state = new SimulationState(profile, setup);
            var start = setup.Start.Date;
            var end   = setup.End.Date;

            for (DateTime date = start; date <= end; date = date.AddDays(1))
            {
                // before anything else, make sure we do the events
                var events = state.Events[date];
                foreach (var item in events)
                {
                    ProcessEvent(state, date, item);
                }

                // if it is the end of the month, then interest hits
                if (date.IsEndOfMonth())
                {
                    foreach (var account in state.GetAccounts())
                    {
                        account.ProcessInterest(state, date);
                    }
                }

                // deposit any paychecks
                var paychecks = state.Paychecks.Values.Where(p => p.Due.Current == date);
                foreach (var paycheck in paychecks)
                {
                    paycheck.Process(state, date);
                    paycheck.Due.Next();
                }

                // pay the bills
                var bills = state.Bills.Values.Where(b => b.Due.Current == date);
                foreach (var bill in bills)
                {
                    bill.Process(state, date);
                    bill.Due.Next();
                }

                // pay the debts
                var debts = state.Debts.Values.Where(d => d.Due.Current == date);
                foreach (var debt in debts)
                {
                    debt.Process(state, date);
                    debt.Due.Next();
                }

                // process the transactions
                var transactions = state.Transactions.Values.Where(t => t.Due.Current == date);
                foreach (var transaction in transactions)
                {
                    transaction.Process(state, date);
                    transaction.Due.Next();
                }

                // if we get here and a debt has a zero balance, then it is paid off
                foreach (var debt in state.Debts.Values)
                {
                    if (debt.Balance <= 0)
                    {
                        state.PayOff(date, debt);
                    }
                }

                // if needed, update the snowball
                state.UpdateSnowball(date);

                // quit if we need to
                if (!state.ShouldKeepGoing())
                {
                    break;
                }
            }

            return(state.Results);
        }