public override IEnumerable <IPortfolioTransaction> GetTransactionList(IReadOnlyHolding holding, IStockResolver stockResolver) { var transactions = new List <IPortfolioTransaction>(); var holdingProperties = holding.Properties[Date]; if (holdingProperties.Units == 0) { return(transactions); } var dividendRules = Stock.DividendRules[Date]; var returnOfCapital = new UnitCountAdjustment() { Id = Guid.NewGuid(), Date = Date, Stock = Stock, NewUnits = NewUnits, OriginalUnits = OriginalUnits, Comment = Description }; transactions.Add(returnOfCapital); return(transactions); }
private IEnumerable <IPortfolioTransaction> ResultStockTransactions(IReadOnlyHolding holding, IStockResolver stockResolver) { var holdingProperties = holding.Properties[Date]; // create parcels for resulting stock foreach (var resultingStock in ResultingStocks) { int units = (int)Math.Ceiling(holdingProperties.Units * ((decimal)resultingStock.NewUnits / (decimal)resultingStock.OriginalUnits)); decimal costBase = holdingProperties.CostBase * resultingStock.CostBasePercentage; var stock = new Stock(Guid.Empty); var transaction = new OpeningBalance() { Id = Guid.NewGuid(), Date = ImplementationDate, Stock = stockResolver.GetStock(resultingStock.Stock), Units = units, CostBase = costBase, AquisitionDate = ImplementationDate, Comment = Description }; yield return(transaction); } }
public override IEnumerable <IPortfolioTransaction> GetTransactionList(IReadOnlyHolding holding, IStockResolver stockResolver) { var transactions = new List <IPortfolioTransaction>(); var holdingProperties = holding.Properties[Date]; if (holdingProperties.Units == 0) { return(transactions); } var dividendRules = Stock.DividendRules[Date]; var amount = (holdingProperties.Units * Amount).ToCurrency(dividendRules.DividendRoundingRule); var returnOfCapital = new ReturnOfCapital() { Id = Guid.NewGuid(), Date = PaymentDate, Stock = Stock, RecordDate = Date, Amount = amount, CreateCashTransaction = true, Comment = Description }; transactions.Add(returnOfCapital); return(transactions); }
public override IEnumerable <IPortfolioTransaction> GetTransactionList(IReadOnlyHolding holding, IStockResolver stockResolver) { var transactions = new List <IPortfolioTransaction>(); foreach (var action in ChildActions) { var childTransactions = action.GetTransactionList(holding, stockResolver); transactions.AddRange(childTransactions); } return(transactions); }
public override IEnumerable <IPortfolioTransaction> GetTransactionList(IReadOnlyHolding holding, IStockResolver stockResolver) { var transactions = new List <IPortfolioTransaction>(); var holdingProperties = holding.Properties[Date]; if (holdingProperties.Units == 0) { return(transactions); } if (ResultingStocks.Any()) { if (RolloverRefliefApplies) { var resultStockTransactions = ResultStockTransactionsWithRollover(holding, stockResolver); transactions.AddRange(resultStockTransactions); // Reduce the costbase of the original parcels decimal originalCostBasePercentage = 1 - ResultingStocks.Sum(x => x.CostBasePercentage); transactions.Add(new CostBaseAdjustment() { Id = Guid.NewGuid(), Date = ImplementationDate, Stock = Stock, Comment = Description, Percentage = originalCostBasePercentage }); } else { var resultStockTransactions = ResultStockTransactions(holding, stockResolver); transactions.AddRange(resultStockTransactions); // Reduce the costbase of the original parcels var amount = resultStockTransactions.OfType <OpeningBalance>().Sum(x => x.CostBase); transactions.Add(new ReturnOfCapital() { Id = Guid.NewGuid(), Date = ImplementationDate, Stock = Stock, Comment = Description, RecordDate = Date, Amount = amount, CreateCashTransaction = false }); } } // Handle disposal of original parcels if (CashComponent > 0.00m) { transactions.Add(new Disposal() { Id = Guid.NewGuid(), Date = ImplementationDate, Stock = Stock, Units = holdingProperties.Units, AveragePrice = CashComponent, TransactionCosts = 0.00m, CgtMethod = CgtCalculationMethod.FirstInFirstOut, CreateCashTransaction = true, Comment = Description }); } return(transactions); }
public abstract IEnumerable <IPortfolioTransaction> GetTransactionList(IReadOnlyHolding holding, IStockResolver stockResolver);
public void CalculateIRR() { var mockRepository = new MockRepository(MockBehavior.Strict); var dateRange = new DateRange(new Date(2000, 01, 01), new Date(2010, 01, 01)); var holding1 = mockRepository.Create <IReadOnlyHolding>(); holding1.Setup(x => x.Value(dateRange.FromDate)).Returns(1000.00m); var holding2 = mockRepository.Create <IReadOnlyHolding>(); holding2.Setup(x => x.Value(dateRange.FromDate)).Returns(2000.00m); holding2.Setup(x => x.Value(dateRange.ToDate)).Returns(3000.00m); var holding3 = mockRepository.Create <IReadOnlyHolding>(); holding3.Setup(x => x.Value(dateRange.ToDate)).Returns(4000.00m); var initialHoldings = new IReadOnlyHolding[] { holding1.Object, holding2.Object }; var finalHoldings = new IReadOnlyHolding[] { holding2.Object, holding3.Object }; var holdings = mockRepository.Create <IHoldingCollection>(); holdings.Setup(x => x.All(dateRange.FromDate)).Returns(initialHoldings); holdings.Setup(x => x.All(dateRange.ToDate)).Returns(finalHoldings); var transactions = new List <CashAccountTransaction>(); transactions.Add(new CashAccountTransaction(Guid.NewGuid(), new Date(2001, 01, 01), "", 200.00m, BankAccountTransactionType.Deposit, 300.00m)); transactions.Add(new CashAccountTransaction(Guid.NewGuid(), new Date(2002, 01, 01), "", -100.00m, BankAccountTransactionType.Withdrawl, 200.00m)); transactions.Add(new CashAccountTransaction(Guid.NewGuid(), new Date(2004, 01, 01), "", 200.00m, BankAccountTransactionType.Deposit, 500.00m)); transactions.Add(new CashAccountTransaction(Guid.NewGuid(), new Date(2005, 01, 01), "", -450.00m, BankAccountTransactionType.Withdrawl, 50.00m)); var transactionRange = mockRepository.Create <ITransactionRange <CashAccountTransaction> >(); transactionRange.Setup(x => x.GetEnumerator()).Returns(transactions.GetEnumerator()); var transactionList = mockRepository.Create <ITransactionList <CashAccountTransaction> >(); transactionList.Setup(x => x.InDateRange(new DateRange(dateRange.FromDate.AddDays(1), dateRange.ToDate))).Returns(transactionRange.Object); var cashAccount = mockRepository.Create <IReadOnlyCashAccount>(); cashAccount.Setup(x => x.Balance(dateRange.FromDate)).Returns(100.00m); cashAccount.Setup(x => x.Balance(dateRange.ToDate)).Returns(50.00m); cashAccount.Setup(x => x.Transactions).Returns(transactionList.Object); var portfolio = mockRepository.Create <IPortfolio>(); portfolio.Setup(x => x.Holdings).Returns(holdings.Object); portfolio.Setup(x => x.CashAccount).Returns(cashAccount.Object); var irr = portfolio.Object.CalculateIRR(dateRange); irr.Should().Be(0.08745m); mockRepository.Verify(); }
public override IEnumerable <IPortfolioTransaction> GetTransactionList(IReadOnlyHolding holding, IStockResolver stockResolver) { var transactions = new List <IPortfolioTransaction>(); var holdingProperties = holding.Properties[Date]; if (holdingProperties.Units == 0) { return(transactions); } var dividendRules = Stock.DividendRules[Date]; var totalAmount = holdingProperties.Units * DividendAmount; var amountPaid = totalAmount.ToCurrency(dividendRules.DividendRoundingRule); var franked = (totalAmount * PercentFranked).ToCurrency(dividendRules.DividendRoundingRule); var unFranked = (totalAmount * (1 - PercentFranked)).ToCurrency(dividendRules.DividendRoundingRule); var frankingCredits = (((totalAmount / (1 - dividendRules.CompanyTaxRate)) - totalAmount) * PercentFranked).ToCurrency(dividendRules.DividendRoundingRule); var incomeReceived = new IncomeReceived() { Id = Guid.NewGuid(), Date = PaymentDate, Stock = Stock, RecordDate = Date, FrankedAmount = franked, UnfrankedAmount = unFranked, FrankingCredits = frankingCredits, Interest = 0.00m, TaxDeferred = 0.00m, CreateCashTransaction = true, DrpCashBalance = 0.00m, Comment = Description }; transactions.Add(incomeReceived); /* Handle Dividend Reinvestment Plan */ var holdingSettings = holding.Settings; if (dividendRules.DrpActive && holdingSettings.ParticipateInDrp && (DrpPrice != 0.00m)) { incomeReceived.CreateCashTransaction = false; int drpUnits; decimal costBase; if (dividendRules.DrpMethod == DrpMethod.RoundUp) { drpUnits = (int)Math.Ceiling(amountPaid / DrpPrice); costBase = amountPaid; } else if (dividendRules.DrpMethod == DrpMethod.RoundDown) { drpUnits = (int)Math.Floor(amountPaid / DrpPrice); costBase = amountPaid; } else if (dividendRules.DrpMethod == DrpMethod.RetainCashBalance) { var drpCashBalance = holding.DrpAccount.Balance(Date); var availableAmount = amountPaid + drpCashBalance; drpUnits = (int)Math.Floor(availableAmount / DrpPrice); costBase = (drpUnits * DrpPrice).ToCurrency(dividendRules.DividendRoundingRule); incomeReceived.DrpCashBalance = availableAmount - costBase; } else { drpUnits = (int)Math.Round(amountPaid / DrpPrice); costBase = amountPaid; } if (drpUnits > 0) { transactions.Add(new OpeningBalance() { Id = Guid.NewGuid(), Date = PaymentDate, Stock = Stock, Units = drpUnits, CostBase = costBase, AquisitionDate = PaymentDate, Comment = "DRP " + MathUtils.FormatCurrency(DrpPrice, false, true) }); } } return(transactions); }