Exemplo n.º 1
0
        private void CreateInvestmentSamples(SampleData data, List <Account> brokerageAccounts)
        {
            if (brokerageAccounts.Count == 0)
            {
                return;
            }

            // now balance the accounts.
            foreach (Account a in money.Accounts.GetAccounts())
            {
                money.Rebalance(a);
            }

            // first figure out how much we can spend each year.
            int      year  = DateTime.Now.Year - 10;
            DateTime start = new DateTime(year, 1, 1); // start in January
            DateTime end   = start.AddYears(1);
            Dictionary <int, decimal> cash = new Dictionary <int, decimal>();
            Ownership ownership            = new Ownership();
            decimal   removed = 0;

            foreach (var t in money.Transactions.GetTransactionsFrom(this.checking))
            {
                if (t.Date > end)
                {
                    cash[year] = GetStockMoney(t.Balance);
                    end        = end.AddYears(1);
                    year++;
                }
            }

            money.BeginUpdate(this);

            Dictionary <Account, decimal> cashBalance = new Dictionary <Account, decimal>();

            foreach (var a in brokerageAccounts)
            {
                cashBalance[a] = 0;
            }

            Transactions transactions = money.Transactions;

            for (year = DateTime.Now.Year - 10; year <= DateTime.Now.Year; year++)
            {
                cash.TryGetValue(year, out decimal balance);
                balance -= removed;
                if (balance < 100)
                {
                    continue; // not enough.
                }
                decimal startBalance = balance;

                int numberOfTransactionForThatYear = rand.Next(5, 100); // up to 100 transactions max per year.

                // keep track of how much we own so we never go negative.
                IList <int> selectedDays = GetRandomDaysInTheYearForTransactions(numberOfTransactionForThatYear);

                foreach (var day in selectedDays)
                {
                    // select random security.
                    SampleSecurity ss = data.Securities[rand.Next(0, data.Securities.Count)];
                    // Get or Create the security
                    Security stock = money.Securities.FindSecurity(ss.Name, true);
                    stock.SecurityType = ss.SecurityType;
                    stock.Symbol       = ss.Symbol;

                    // select a random brokerage.
                    Account a = brokerageAccounts[rand.Next(brokerageAccounts.Count)];

                    var canSpend = balance + cashBalance[a];
                    if (canSpend < 100)
                    {
                        break;
                    }

                    // the date the purchase or sale was done
                    var date = new DateTime(year, 1, 1).AddDays(day);

                    // How many unit bought or sold
                    var quote = GetClosingPrice(ss.Symbol, date);

                    Transaction t     = null;
                    decimal     owned = ownership.GetUnits(a, ss.Symbol);
                    if (owned > 4 && rand.Next(3) == 1)
                    {
                        // make this a sell transaction.
                        // Create a new Transaction
                        t      = money.Transactions.NewTransaction(a);
                        t.Date = date;
                        //-----------------------------------------------------
                        // Create the matching Investment transaction
                        Investment i = t.GetOrCreateInvestment();
                        i.Transaction = t;
                        i.Security    = stock;
                        i.UnitPrice   = quote;
                        i.Price       = quote;
                        i.Type        = InvestmentType.Sell;
                        // Create the a SELL transaction
                        i.Units = rand.Next(1, (int)(owned / 2));
                        ownership.AddUnits(a, ss.Symbol, -i.Units);
                        // Calculate the Payment or Deposit amount
                        t.Amount = RoundCents(i.Units * i.UnitPrice);
                    }
                    else
                    {
                        int max = (int)(canSpend / quote);
                        if (max > 0)
                        {
                            // Create a new Transaction
                            t      = money.Transactions.NewTransaction(a);
                            t.Date = date;

                            //-----------------------------------------------------
                            // Create the matching Investment transaction
                            Investment i = t.GetOrCreateInvestment();
                            i.Transaction = t;
                            i.Security    = stock;
                            i.UnitPrice   = quote;
                            i.Price       = quote;
                            i.Type        = InvestmentType.Buy;
                            i.Units       = rand.Next(1, max);
                            ownership.AddUnits(a, ss.Symbol, i.Units);
                            // Calculate the Payment or Deposit amount
                            t.Amount = RoundCents(i.Units * i.UnitPrice * -1);
                        }
                    }

                    if (t != null)
                    {
                        t.Payee         = money.Payees.FindPayee(ss.Name, true);
                        t.Category      = money.Categories.InvestmentStocks;
                        balance        += t.Amount;
                        cashBalance[a] += t.Amount;
                        // Finally add the new transaction
                        money.Transactions.AddTransaction(t);
                    }
                }

                foreach (var acct in brokerageAccounts)
                {
                    var amount = cashBalance[acct];
                    if (amount < 0)
                    {
                        // then we need to transfer money to cover the cost of the stock purchases.
                        Transaction payment = transactions.NewTransaction(checking);
                        payment.Date   = new DateTime(year, 1, 1);
                        payment.Amount = RoundCents(amount);
                        transactions.AddTransaction(payment);
                        money.Transfer(payment, acct);
                        removed           += -amount;
                        cashBalance[acct] += -amount;
                    }
                }
            }
            money.EndUpdate();

            // now balance the accounts again!
            foreach (Account a in money.Accounts.GetAccounts())
            {
                money.Rebalance(a);
            }
        }