public IParcel AddParcel(Date date, Date aquisitionDate, int units, decimal amount, decimal costBase, IPortfolioTransaction transaction) { var parcel = new Parcel(Guid.NewGuid(), date, aquisitionDate, new ParcelProperties(units, amount, costBase), transaction); _Parcels.Add(parcel.Id, parcel); var exisingProperties = Properties[date]; var newProperties = new HoldingProperties(exisingProperties.Units + units, exisingProperties.Amount + amount, exisingProperties.CostBase + costBase); _Properties.Change(date, newProperties); return(parcel); }
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); }