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