Exemple #1
0
        public void CostBasisAcrossTransfers()
        {
            UiDispatcher.CurrentDispatcher = System.Windows.Threading.Dispatcher.CurrentDispatcher;
            MyMoney  m = new MyMoney();
            Security s = m.Securities.NewSecurity();

            s.Name = "MSFT";
            Account a  = m.Accounts.AddAccount("Ameritrade");
            Account a2 = m.Accounts.AddAccount("Fidelity");

            AddInvestment(m, s, a, DateTime.Parse("1/1/2000"), 10, 1, InvestmentType.Buy);
            m.StockSplits.AddStockSplit(new StockSplit()
            {
                Date        = DateTime.Parse("6/1/2000"),
                Numerator   = 2,
                Denominator = 1,
                Security    = s
            });
            AddInvestment(m, s, a, DateTime.Parse("1/1/2001"), 20, 2, InvestmentType.Buy);

            Transaction transfer = AddInvestment(m, s, a, DateTime.Parse("1/1/2002"), 30, 2, InvestmentType.Remove);

            m.Transfer(transfer, a2);

            // now should be able to sell 10 left in this account (after split)
            AddInvestment(m, s, a, DateTime.Parse("1/1/2003"), 10, 3, InvestmentType.Sell);

            // and we should have 30 in the other account
            AddInvestment(m, s, a2, DateTime.Parse("1/1/2004"), 30, 5, InvestmentType.Sell);

            // Ok, now let's if the cost basis is correct!
            CostBasisCalculator     calc     = new CostBasisCalculator(m, DateTime.Now);
            List <SecurityPurchase> holdings = new List <SecurityPurchase>(calc.GetHolding(a).GetHoldings());

            Assert.AreEqual <int>(0, holdings.Count); // should have nothing left.

            // should have 3 separate cost basis records to cover what we sold.
            List <SecuritySale> sales = new List <SecuritySale>(calc.GetSales());

            Assert.AreEqual <int>(3, sales.Count);

            SecuritySale s1 = sales[0];
            SecuritySale s2 = sales[1];
            SecuritySale s3 = sales[2];

            // since the sale from Ameritrade account happened first it should be returned first
            Assert.AreEqual <decimal>(2, s1.CostBasisPerUnit); // $2, no splits
            Assert.AreEqual(a, s1.Account);                    // Ameritrade
            Assert.AreEqual <decimal>(Math.Round(10M, 5), Math.Round(s1.UnitsSold, 5));

            // Notice here that the Fidelity account inherited the cost basis records correctly
            // from the Ameritrade account as a result of the "Transfer" that happened above.
            Assert.AreEqual <decimal>(Math.Round(1M / 2M, 5), Math.Round(s2.CostBasisPerUnit, 5)); // $1 after 2:1 split
            Assert.AreEqual(a2, s2.Account);                                                       // Fidelity
            Assert.AreEqual <decimal>(Math.Round(20M, 5), Math.Round(s2.UnitsSold, 5));

            Assert.AreEqual <decimal>(2, s3.CostBasisPerUnit); // $2, no splits
            Assert.AreEqual(a2, s2.Account);                   // Fidelity
            Assert.AreEqual <decimal>(Math.Round(10M, 5), Math.Round(s3.UnitsSold, 5));
        }
Exemple #2
0
        void WriteCapitalGains(IReportWriter writer, SecuritySale data)
        {
            writer.StartRow();
            writer.StartCell();
            writer.WriteParagraph(data.Security.Name);
            writer.EndCell();

            writer.StartCell();
            writer.WriteNumber(Rounded(data.UnitsSold, 3));
            writer.EndCell();

            writer.StartCell();
            if (data.DateAcquired == null)
            {
                writer.WriteNumber("VARIOUS");
            }
            else
            {
                writer.WriteNumber(data.DateAcquired.Value.ToShortDateString());
            }
            writer.EndCell();

            writer.StartCell();
            writer.WriteNumber(data.CostBasisPerUnit.ToString("C"));
            writer.EndCell();

            writer.StartCell();
            writer.WriteNumber(data.TotalCostBasis.ToString("C"));
            writer.EndCell();

            writer.StartCell();
            writer.WriteNumber(data.DateSold.ToShortDateString());
            writer.EndCell();

            writer.StartCell();
            writer.WriteNumber(data.SalePricePerUnit.ToString("C"));
            writer.EndCell();

            writer.StartCell();
            writer.WriteNumber(data.SaleProceeds.ToString("C"));
            writer.EndCell();

            writer.StartCell();
            writer.WriteNumber(GiveUpTheFractionalPennies(data.TotalGain).ToString("C"));
            writer.EndCell();

            writer.EndRow();
        }
        /// <summary>
        /// Consolidate capital gains information. If the securities are the same and the sale date is the same then
        /// combine them, and mark the "DateAquired" as null (reported as 'various').
        /// </summary>
        private List <SecuritySale> Consolidate(List <SecuritySale> list, bool consolidateOnDateSold)
        {
            List <SecuritySale> result   = new List <SecuritySale>();
            SecuritySale        previous = null;

            foreach (SecuritySale cg in list)
            {
                if (previous == null || previous.Security != cg.Security || (!consolidateOnDateSold && previous.DateAcquired != cg.DateAcquired) ||
                    (previous.SalePricePerUnit != cg.SalePricePerUnit) ||
                    (consolidateOnDateSold && previous.DateSold != cg.DateSold))
                {
                    previous = cg;
                    result.Add(cg);
                }
                else
                {
                    previous.Consolidate(cg);
                }
            }
            return(result);
        }
 private static void WriteRecordFormat4(TextWriter writer, SecuritySale data, int refnum)
 {
     writer.WriteLine("TD");
     writer.WriteLine("N" + refnum);
     writer.WriteLine("C1");
     writer.WriteLine("L1");
     // convention is to stick the quantity sold in the payee field.
     writer.WriteLine("P" + (int)data.UnitsSold + " " + data.Security);
     if (refnum == 673)
     {
         writer.WriteLine("D");
     }
     else if (data.DateAcquired == null)
     {
         writer.WriteLine("DVARIOUS");
     }
     else
     {
         writer.WriteLine("D" + data.DateAcquired.Value.ToShortDateString());
     }
     writer.WriteLine("D" + data.DateSold.ToShortDateString());
     if (refnum == 673)
     {
         writer.WriteLine("$");
     }
     else
     {
         writer.WriteLine("$" + Round(true, data.TotalCostBasis));
     }
     if (refnum == 673)
     {
         writer.WriteLine("$" + Round(true, data.SaleProceeds));
     }
     else
     {
         writer.WriteLine("$" + Round(true, data.SaleProceeds));
     }
     writer.WriteLine("^"); // end of record
 }