public void CgtMethodCalculation(Date aquisitionDate, CgtMethod method, string reason)
        {
            var saleDate = new Date(2020, 01, 01);

            var cgtMethod = CgtUtils.CgtMethodForParcel(aquisitionDate, saleDate);

            cgtMethod.Should().Be(method, reason);
        }
Пример #2
0
        public static decimal DiscountedCgt(decimal cgtAmount, CgtMethod cgtMethod)
        {
            if ((cgtMethod == CgtMethod.Discount) && (cgtAmount > 0.00m))
            {
                return((cgtAmount / 2).ToCurrency(RoundingRule.Round));
            }

            return(cgtAmount);
        }
 public ParcelSold(IReadOnlyParcel parcel, int unitsSold, decimal costBase, decimal amountReceived, decimal capitalGain, CgtMethod cgtMethod, decimal discountedGain)
 {
     Parcel         = parcel;
     UnitsSold      = unitsSold;
     CostBase       = costBase;
     AmountReceived = amountReceived;
     CapitalGain    = capitalGain;
     CgtMethod      = cgtMethod;
     DiscountedGain = discountedGain;
 }
Пример #4
0
        private void OnCgtEventOccured(Date eventDate, IReadOnlyStock stock, int units, decimal costBase, decimal amountReceived, decimal capitalGain, CgtMethod cgtMethod, IPortfolioTransaction transaction)
        {
            // Make a temporary copy of the event to avoid possibility of
            // a race condition if the last subscriber unsubscribes
            // immediately after the null check and before the event is raised.
            var handler = CgtEventOccurred;

            if (handler != null)
            {
                var e = new CgtEventArgs()
                {
                    EventDate      = eventDate,
                    Stock          = stock,
                    Units          = units,
                    CostBase       = costBase,
                    AmountReceived = amountReceived,
                    CapitalGain    = capitalGain,
                    CgtMethod      = cgtMethod,
                    Transaction    = transaction
                };

                handler(this, e);
            }
        }
Пример #5
0
        public void DisposeOfParcel(Guid parcelId, Date date, int units, decimal amount, decimal capitalGain, CgtMethod cgtMethod, IPortfolioTransaction transaction)
        {
            if (!_Parcels.TryGetValue(parcelId, out var parcel))
            {
                throw new ArgumentException("Parcel is not part of this holding");
            }

            var parcelProperties = parcel.Properties[date];

            if (units > parcelProperties.Units)
            {
                throw new NotEnoughSharesForDisposal("Not enough shares in parcel");
            }

            // Adjust Parcel
            decimal costBaseChange;
            decimal amountChange;

            if (units == parcelProperties.Units)
            {
                amountChange   = parcelProperties.Amount;
                costBaseChange = parcelProperties.CostBase;
            }
            else
            {
                amountChange   = (parcelProperties.Amount * ((decimal)units / parcelProperties.Units)).ToCurrency(RoundingRule.Round);
                costBaseChange = (parcelProperties.CostBase * ((decimal)units / parcelProperties.Units)).ToCurrency(RoundingRule.Round);
            }
            parcel.Change(date, -units, -amountChange, -costBaseChange, transaction);

            // Adjust holding
            var holdingProperties = Properties[date];
            HoldingProperties newProperties;

            if (units == holdingProperties.Units)
            {
                End(date);
                newProperties = new HoldingProperties(0, 0.00m, 0.00m);
            }
            else
            {
                newProperties = new HoldingProperties(holdingProperties.Units - units, holdingProperties.Amount - amountChange, holdingProperties.CostBase - costBaseChange);
            }
            _Properties.Change(date, newProperties);

            OnCgtEventOccured(date, Stock, units, costBaseChange, amount, capitalGain, cgtMethod, transaction);
        }
 public void Add(Date date, IReadOnlyStock stock, int units, decimal costBase, decimal amountReceived, decimal capitalGain, CgtMethod cgtMethod)
 {
     Add(new CgtEvent()
     {
         Id             = Guid.NewGuid(),
         Date           = date,
         Stock          = stock,
         Units          = units,
         CostBase       = costBase,
         AmountReceived = amountReceived,
         CapitalGain    = capitalGain,
         CgtMethod      = cgtMethod
     });
 }
        public void CalculateParcelCgt(Date disposalDate, int unitsSold, decimal saleAmount, decimal expectedCostBase, decimal expectedCapitalGain, decimal expectedDiscountedGain, CgtMethod expectedCgtMethod, string because)
        {
            var aquisitionDate = new Date(2017, 01, 01);
            var properties     = new ParcelProperties(1000, 1000.00m, 2000.00m);
            var parcel         = new Parcel(Guid.NewGuid(), aquisitionDate, aquisitionDate, properties, null);

            parcel.Change(new Date(2017, 08, 01), 1000, 2000.00m, 2000.00m, null);

            var calculator = new CgtCalculator();

            var parcelSold = calculator.CalculateParcelCgt(parcel, disposalDate, unitsSold, saleAmount);

            parcelSold.Should().BeEquivalentTo(new
            {
                AmountReceived = saleAmount,
                CostBase       = expectedCostBase,
                CapitalGain    = expectedCapitalGain,
                DiscountedGain = expectedDiscountedGain,
                CgtMethod      = expectedCgtMethod
            }, because);
        }