public PortfolioFactory(IStockResolver stockResolver) { _StockResolver = stockResolver; _TransactionHandlers.Register <Aquisition>(() => new AquisitionHandler()); _TransactionHandlers.Register <Disposal>(() => new DisposalHandler()); _TransactionHandlers.Register <CashTransaction>(() => new CashTransactionHandler()); _TransactionHandlers.Register <OpeningBalance>(() => new OpeningBalanceHandler()); _TransactionHandlers.Register <IncomeReceived>(() => new IncomeReceivedHandler()); _TransactionHandlers.Register <ReturnOfCapital>(() => new ReturnOfCapitalHandler()); _TransactionHandlers.Register <CostBaseAdjustment>(() => new CostBaseAdjustmentHandler()); _TransactionHandlers.Register <UnitCountAdjustment>(() => new UnitCountAdjustmentHandler()); }
public PortfolioCorporateActionsService(IReadOnlyPortfolio portfolio, IStockResolver stockResolver) { _Portfolio = portfolio; _StockResolver = stockResolver; }
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); }
private IEnumerable <IPortfolioTransaction> ResultStockTransactionsWithRollover(IReadOnlyHolding holding, IStockResolver stockResolver) { var parcels = holding.Parcels(Date); foreach (var parcel in parcels) { var parcelProperties = parcel.Properties[Date]; // create parcels for resulting stock foreach (var resultingStock in ResultingStocks) { int units = (int)Math.Ceiling(parcelProperties.Units * ((decimal)resultingStock.NewUnits / (decimal)resultingStock.OriginalUnits)); decimal costBase = parcelProperties.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 = parcel.AquisitionDate, Comment = Description }; yield return(transaction); } } }
internal Portfolio(Guid id, IStockResolver stockResolver, IServiceFactory <ITransactionHandler> transactionHandlers) : base(id) { _StockResolver = stockResolver; _TransactionHandlers = transactionHandlers; }
public abstract IEnumerable <IPortfolioTransaction> GetTransactionList(IReadOnlyHolding holding, IStockResolver stockResolver);
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); } 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); }
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>(); 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); }