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;
 }
Ejemplo n.º 6
0
 public abstract IEnumerable <IPortfolioTransaction> GetTransactionList(IReadOnlyHolding holding, IStockResolver stockResolver);
Ejemplo n.º 7
0
        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);
        }
Ejemplo n.º 8
0
        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);
        }
Ejemplo n.º 10
0
        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);
        }