public bool AddTransferFee(Money transferFee, IGLLookupRecords lookups, string description) { bool success = false; if (transferFee == null || lookups == null) throw new ApplicationException("It is not possible to add transfer fee since not all parameters are valid."); IGeneralOperationsComponent comp = Components.Where(u => u.BookingComponentType == BookingComponentTypes.CashTransfer).FirstOrDefault(); if (!(comp != null && comp.MainLine != null && comp.MainLine.IsAllowedToAddTransferFee)) throw new ApplicationException("It is not possible to add transfer fee to this transfer."); if (TransferFee != null && TransferFee.IsNotZero) throw new ApplicationException("It is not possible to add transfer fee more than once."); if (transferFee.Sign || transferFee.Abs().Quantity > TransferAmount.Abs().Quantity) throw new ApplicationException("The transfer fee can not be higher than the transfer amount."); if (transferFee != null && transferFee.IsNotZero) { ICashTransferComponent newComponent = new CashTransferComponent(this, BookingComponentTypes.CashTransferFee, this.CreationDate); newComponent.AddLinesToComponent(transferFee, BookingComponentTypes.CashTransferFee, true, false, false, lookups, Account); newComponent.Component.SetDescription(description); this.Components.Add(newComponent); success = true; } return success; }
public CrumbleTransaction(IOrder order, ICrumbleAccount acctA, IAccount acctB, InstrumentSize valueSize, Price price, decimal exRate, DateTime transactionDate, DateTime transactionDateTime, Decimal ServiceChargePercentage, Side txSide, ITradingJournalEntry tradingJournalEntry, IGLLookupRecords lookups, ListOfTransactionComponents[] components) : base(order, acctA, acctB, valueSize, price, exRate, transactionDate, transactionDateTime, ServiceChargePercentage, txSide, tradingJournalEntry, lookups, components) { }
public TransactionNTM(IAccountTypeInternal acctA, IAccount acctB, InstrumentSize valueSize, Price price, decimal exRate, DateTime transactionDate, DateTime transactionDateTime, Decimal ServiceChargePercentage, Side txSide, ITradingJournalEntry tradingJournalEntry, IGLLookupRecords lookups, ListOfTransactionComponents[] components, string description) : base(acctA, acctB, valueSize, price, exRate, transactionDate, transactionDateTime, ServiceChargePercentage, txSide, tradingJournalEntry, lookups, components) { this.Description = description; }
public void setCommission(IGLLookupRecords lookups, Money Commission) { if (this.Components.Any(x => x.BookingComponentType == BookingComponentTypes.Commission)) { } else { ListOfTransactionComponents comm = new ListOfTransactionComponents() { ComponentType = BookingComponentTypes.Commission, ComponentValue = Commission }; createComponents(lookups, new ListOfTransactionComponents[1] { comm }); } }
/// <summary> /// Constructor /// </summary> /// <param name="dividendDetails">The details of the cash dividend (date, price)</param> /// <param name="units">The total number of units over which dividend is paid</param> public CashDividend(IAccountTypeCustomer account, IMemorialBooking journalEntry, string description, decimal taxPercentage, IDividendHistory dividendDetails, InstrumentSize units, IGLLookupRecords lookups) : base(account, journalEntry, description, taxPercentage) { if (dividendDetails == null) throw new ApplicationException("Dividend details are mandatory."); if (units == null || units.IsZero) throw new ApplicationException("The number of units is mandatory."); this.DividendDetails = dividendDetails; this.UnitsInPossession = units; //this.CashGeneratingInstrument = dividendDetails.Instrument; createComponents(lookups); }
public BonusDistribution(IAccountTypeInternal acctA, IAccount acctB, InstrumentSize valueSize, Price price, decimal exRate, DateTime transactionDate, DateTime transactionDateTime, Decimal ServiceChargePercentage, Side txSide, ICorporateActionBonusDistribution bonusDistributionDetails, ITradingJournalEntry tradingJournalEntry, IGLLookupRecords lookups, ListOfTransactionComponents[] components) : base(acctA, acctB, valueSize, price, exRate, transactionDate, transactionDateTime, ServiceChargePercentage, txSide, tradingJournalEntry, lookups, components) { this.CorporateActionType = CorporateActionTypes.BonusDistribution; this.CorporateActionDetails = bonusDistributionDetails; }
public InstrumentConversion(IAccountTypeInternal acctA, IAccount acctB, InstrumentSize valueSize, InstrumentSize convertedInstrumentSize, Money additionalCash, decimal exRate, IInstrumentHistory instrumentTransformation, ITradingJournalEntry tradingJournalEntry, IGLLookupRecords lookups) : base(acctA, acctB, valueSize, valueSize.GetPrice(0M), exRate, instrumentTransformation.ChangeDate, instrumentTransformation.ChangeDate, 0M, (valueSize.Sign ? Side.XI : Side.XO), tradingJournalEntry, lookups, null) { if (instrumentTransformation == null) throw new ApplicationException("Corporate action information is missing"); if (!(valueSize != null && valueSize.IsNotZero && convertedInstrumentSize != null && convertedInstrumentSize.IsNotZero)) throw new ApplicationException("Not all instrument information for this corporate action is available, both instruments have to be supplied"); if (valueSize.Underlying.Equals(convertedInstrumentSize.Underlying)) throw new ApplicationException("Both instruments can not be the same in a corporate action"); if (valueSize.Sign.Equals(convertedInstrumentSize.Sign)) throw new ApplicationException("Both instruments can not have the same side in a corporate action"); IInstrumentsHistoryConversion conversion = (IInstrumentsHistoryConversion)instrumentTransformation; if (!(conversion.Instrument.Equals(valueSize.Underlying) && conversion.NewInstrument.Equals(convertedInstrumentSize.Underlying))) throw new ApplicationException("Corporate action does not equal the instrument history data"); decimal diff = (convertedInstrumentSize.Abs().Quantity / valueSize.Abs().Quantity) - conversion.ConversionRate; if (diff != 0) throw new ApplicationException("Sizes do not correspond with conversion rate of the Corporate action"); if (additionalCash != null && additionalCash.IsNotZero) { ListOfTransactionComponents[] components = new ListOfTransactionComponents[1]; components[0] = new ListOfTransactionComponents() { ComponentType = BookingComponentTypes.Conversion, ComponentValue = additionalCash }; createComponents(lookups, components); } this.CorporateActionType = CorporateActionTypes.Conversion; ConvertedInstrumentSize = convertedInstrumentSize; CorporateActionType = instrumentTransformation.CorporateActionType; InstrumentTransformation = instrumentTransformation; }
public ManagementFee(IAccountTypeCustomer account, DateTime startDate, DateTime endDate, IList<IManagementPeriodUnit> units, IMemorialBooking journalEntry, decimal taxPercentage, IGLLookupRecords lookups) : base(account, journalEntry, journalEntry.Description, taxPercentage) { this.StartDate = startDate; this.EndDate = endDate; if (units == null) throw new ApplicationException("The units can not be null"); foreach (IManagementPeriodUnit unit in units) { if (unit.ManagementFee != null) throw new ApplicationException(string.Format("The unit {0} is already used for a management fee transaction.", unit.Key.ToString())); if (!(unit.Success && unit.FeesCalculated == FeesCalculatedStates.Yes)) throw new ApplicationException(string.Format("The unit {0} is not correct for the management fee transaction.", unit.Key.ToString())); } this.Units = units; this.GeneralOpsJournalEntry = journalEntry; createComponents(lookups); }
protected void createComponents(IGLLookupRecords lookups) { Money div = null; if (UnitsInPossession != null && UnitsInPossession.Underlying.IsCorporateAction) div = UnitsInPossession.CalculateAmount(this.DividendDetails.StockDivUnitPrice); else div = UnitsInPossession.CalculateAmount(this.DividendDetails.UnitPrice); if (div != null && div.IsNotZero) { Money tax = div * (TaxPercentage * -1); ICashDividendComponent newComponent = new CashDividendComponent(this, BookingComponentTypes.Dividend, this.CreationDate); newComponent.AddLinesToComponent(div, BookingComponentTypes.Dividend, true, false, false, lookups, Account); newComponent.Component.SetDescription(this.DividendDetails.DisplayString); this.Components.Add(newComponent); if (tax != null && tax.IsNotZero) { ICashDividendComponent taxComponent = new CashDividendComponent(this, BookingComponentTypes.DividendTax, this.CreationDate); taxComponent.AddLinesToComponent(tax, BookingComponentTypes.DividendTax, true, false, false, lookups, Account); taxComponent.Component.SetDescription("tax " + this.DividendDetails.DisplayString); this.Components.Add(taxComponent); } } }
private IGLLookupRecord GetLookupRecord(Money componentValue, BookingComponentTypes bookingComponentType, bool isSettled, bool isExternalExecution, bool isInternalExecution, IGLLookupRecords lookups) { ICurrency currency = componentValue.Underlying.ToCurrency; return lookups.GetGLLookupRecord(currency, isExternalExecution, isInternalExecution, !isSettled, bookingComponentType); }
public void AddLinesToComponent(Money componentValue, BookingComponentTypes bookingComponentType, bool isSettled, bool isExternalExecution, bool isInternalExecution, IGLLookupRecords lookups, IAccount accountA, IAccount accountB, DateTime? valueDate) { IGLLookupRecord lookupRecord = GetLookupRecord(componentValue, bookingComponentType, isSettled, isExternalExecution, isInternalExecution, lookups); this.Component.AddLinesToComponent(componentValue, lookupRecord, accountA, accountB, valueDate); }
public void AddLinesToComponent(Money componentValue, BookingComponentTypes bookingComponentType, bool isSettled, bool isExternalExecution, bool isInternalExecution, IGLLookupRecords lookups, IAccount accountA, IAccount accountB) { AddLinesToComponent(componentValue, bookingComponentType, isSettled, isExternalExecution, isInternalExecution, lookups, accountA, null, null); }
protected void createComponents(IGLLookupRecords lookups) { var fees = (from u in Units from f in u.FeeItems group f by new { FeeType = f.FeeType, Period = f.Parent.Period } into g let amounts = from pair in g select pair.Amount select new { FeeTypePeriod = g.Key, Amount = amounts.Sum() }) .Union( from u in Units from f in u.AverageHoldingFeeItems group f by new { FeeType = f.FeeType, Period = f.Parent.Period } into g let amounts = from pair in g select pair.Amount select new { FeeTypePeriod = g.Key, Amount = amounts.Sum() }); if (fees != null && fees.Count() > 0) { IAccountTypeCustomer account = ((IAccountTypeCustomer)Account).ExitFeePayingAccount; Money taxeableAmount = null; foreach (var feeItem in fees.OrderBy(x => x.FeeTypePeriod.Period)) { if ((feeItem != null) && ((feeItem.Amount != null) && (feeItem.Amount.IsNotZero))) { IManagementFeeComponent newComponent = new ManagementFeeComponent(this, feeItem.FeeTypePeriod.FeeType.BookingComponentType, feeItem.FeeTypePeriod.Period, feeItem.FeeTypePeriod.FeeType, this.CreationDate); newComponent.AddLinesToComponent(feeItem.Amount, feeItem.FeeTypePeriod.FeeType.BookingComponentType, true, false, false, lookups, account); newComponent.Component.SetDescription(string.Format("{0} {1}", feeItem.FeeTypePeriod.FeeType.Description, feeItem.FeeTypePeriod.Period)); this.Components.Add(newComponent); if (feeItem.FeeTypePeriod.FeeType.UseTax) taxeableAmount += feeItem.Amount; } } if (taxeableAmount != null && taxeableAmount.IsNotZero) { if (TaxPercentage < 0 || TaxPercentage > 1) throw new ApplicationException("The BTW Percentage can only be between 0 and 1"); Money tax = Money.Multiply(taxeableAmount, TaxPercentage); if (tax != null && tax.IsNotZero) { IManagementFeeComponent taxComponent = new ManagementFeeComponent(this, BookingComponentTypes.Tax, 0, null, this.CreationDate); taxComponent.AddLinesToComponent(tax, BookingComponentTypes.Tax, true, false, false, lookups, account); taxComponent.Component.SetDescription("BTW " + getTaxDescription()); this.Components.Add(taxComponent); } } } }
public IOrderExecution Fill(InstrumentSize size, Price price, Money amount, decimal exRate, IAccount counterParty, DateTime transactionDate, DateTime transactionDateTime, IExchange exchange, bool isCompleteFill, Money serviceCharge, decimal serviceChargePercentage, Money accruedInterest, ITradingJournalEntry tradingJournalEntry, IGLLookupRecords lookups) { IOrderExecution returnValue = null; if (size == null || price == null || amount == null) throw new Exception("Size, Price and Amount are mandatory when filling the order."); if (IsFillable != OrderFillability.True) throw new ApplicationException("This Order is not fillable."); setSignServiceCharge(ref serviceCharge, ref serviceChargePercentage); if (accruedInterest != null && accruedInterest.IsNotZero) accruedInterest = accruedInterest.Abs() * (decimal)this.Side * -1M; CheckMaximalRoundOffError(IsSizeBased, size, amount, price, accruedInterest, this.Side); if (isCompleteFill) { // Check whether the order has not been filled before if (Transactions.Count > 0) throw new ApplicationException("The order has already been filled and so it can not be a complete fill."); if (this.OpenValue.IsZero) throw new ApplicationException("The open value of this order is zero."); InstrumentSize diff = getTradeDifferenceOpenValue(size, amount, serviceCharge, accruedInterest); if (diff.IsNotZero) { const decimal maxAllowed = 0.05m; // TickSize && NominalValue decimal tickSize = 0M; if (this.OrderType == OrderTypes.SizeBased) { IInstrumentExchange ie = getInstrumentExchange(exchange); if (ie != null) tickSize = ie.TickSize; } if (this.RequestedInstrument.SecCategory.Key == SecCategories.Bond) tickSize = ((IBond)this.RequestedInstrument).NominalValue.Quantity; if (!(tickSize > 0M && Math.Abs(diff.Quantity / tickSize) < 1M)) { decimal fillRatio = diff.Abs().Quantity / this.OpenValue.Abs().Quantity; if (fillRatio > maxAllowed) throw new ApplicationException( string.Format("The size of this transaction is different from the order size by more than {0:0.##}%.", maxAllowed * 100)); } } amount.XRate = exRate; } else { orderInitialCheck(ref amount, size, exRate, serviceCharge, accruedInterest); } this.IsCompleteFilled = isCompleteFill; orderCheckSide(this.Side, ref amount, ref size); checkServiceChargePercentage(serviceCharge, serviceChargePercentage, amount); ListOfTransactionComponents[] components = packageComponents(amount, serviceCharge, accruedInterest); returnValue = new OrderExecution(this, counterParty, size, price, exRate, transactionDate, transactionDateTime, serviceChargePercentage, tradingJournalEntry, lookups, components); fillOrder(returnValue, size, price, amount, serviceCharge, accruedInterest); return returnValue; }
public override bool CalculateCosts(IOrderAllocation transaction, IFeeFactory feeFactory, IGLLookupRecords lookups) { throw new ApplicationException("The method is mot supported for a corpa."); }
public void CalculateDailyInterest(InstrumentSize size, DateTime calcDate, DateTime settlementDate, IList<IBondCouponPaymentDailyCalculation> oldCalculations, IGLLookupRecords lookups) { if (!HasSettled) { AccruedInterestDetails details = Bond.AccruedInterest(size, settlementDate, Bond.DefaultExchange ?? Bond.HomeExchange); if (details.IsRelevant || (oldCalculations != null && oldCalculations.Count > 0)) { this.DailyCalculations.AddCalculation(calcDate, settlementDate, size, details.AccruedInterest, oldCalculations); Money dailyInterest = DailyCalculations.GetCalculationByDate(settlementDate).DailyInterest; IBondCouponPaymentComponent component = (IBondCouponPaymentComponent)this.Components[0]; Money lineAmountAlreadyCharged = null; if (component.JournalLines.Any(x => x.ValueDate.Equals(calcDate) && x.GiroAccount != null && x.GiroAccount.Key == this.Account.Key)) lineAmountAlreadyCharged = component.JournalLines.Where(x => x.ValueDate.Equals(calcDate) && x.GiroAccount != null && x.GiroAccount.Key == this.Account.Key).Select(x => x.Balance).Sum(); if ((dailyInterest != null && dailyInterest.IsNotZero) || (lineAmountAlreadyCharged != null && lineAmountAlreadyCharged.IsNotZero)) { Money lineAmount = dailyInterest + lineAmountAlreadyCharged; if (lineAmount != null && lineAmount.IsNotZero) { component.AddLinesToComponent(lineAmount, BookingComponentTypes.AccruedInterest, false, false, false, lookups, Account, null, calcDate); foreach (IJournalEntryLine line in component.Component.JournalLines.Where(x => x.ValueDate.Equals(calcDate) && string.IsNullOrEmpty(x.Description))) line.Description = string.Format("Interest {0}", settlementDate.ToString("dd-MM-yyyy")); this.GeneralOpsJournalEntry.BookLines(); } } } } else throw new ApplicationException("This interest payment already settled."); }
public static bool ProcessBondPosition(IDalSession session, IAccountTypeInternal account, ITradeableInstrument instrument, IExchange exchange, DateTime upToDate, IGLLookupRecords lookups) { bool success = false; IFundPosition pos = account.Portfolio.PortfolioInstrument.Where(x => x.Instrument.Key == instrument.Key).FirstOrDefault(); if (pos != null) { IList<IBondCouponPaymentDailyCalculation> oldCalculations = null; if (pos.BondCouponCalculations != null) oldCalculations = pos.BondCouponCalculations .Where(x => x.CalcDate > upToDate && x.Parent.Status == BondCouponPaymentStati.Settled && x.Parent.StornoBooking == null) .ToList(); IBondCouponPaymentDailyCalculation lastCalc = pos.BondCouponPayments.Get(e => e.ActivePayment).Get(e => e.DailyCalculations).Get(e => e.LastCalculation); success = processBondPosition(pos, exchange, lastCalc != null ? lastCalc.CalcDate : upToDate, oldCalculations, lookups, session); } // Check for cancel InstrumentSize size = pos.PositionTransactions.Where(x => x.TransactionDate <= upToDate).Select(x => x.Size).Sum(); if (size != null && size.IsZero && pos.BondCouponPayments.ActivePayment != null) { IBondCouponPayment bip = pos.BondCouponPayments.ActivePayment; if (Util.DateBetween(bip.CouponHistory.StartAccrualDate, bip.CouponHistory.EndAccrualDate, upToDate)) success = bip.Cancel(); } return success; }
public override bool CalculateCosts(IOrderAllocation transaction, IFeeFactory feeFactory, IGLLookupRecords lookups) { checkCostCalculater(transaction, feeFactory); Commission commDetails = feeFactory.CalculateCommission(transaction); if (commDetails != null) transaction.setCommission(lookups, commDetails.Amount); return true; }
public IOrderAllocation FillasAllocation(IOrderExecution ParentExecution, ITradingJournalEntry tradingJournalEntry, IGLLookupRecords lookups, IFeeFactory feeFactory) { if (!RequestedInstrument.IsTradeable) throw new Exception("FillasAllocation not possible when the instrument is not tradeable."); ITradeableInstrument instrument = (ITradeableInstrument)RequestedInstrument; IExchange exchange = ParentExecution.Exchange ?? instrument.DefaultExchange ?? instrument.HomeExchange; TransactionFillDetails details = instrument.GetTransactionFillDetails( this, ParentExecution.Price, ParentExecution.ContractualSettlementDate, feeFactory, ParentExecution.FillRatio, exchange); // convert servicecharge? if (details.ServiceCharge != null && details.ServiceCharge.IsNotZero) { if (!details.ServiceCharge.Underlying.Equals(ParentExecution.Price.Underlying) && !ParentExecution.Price.Underlying.IsObsoleteCurrency) details.ServiceCharge = details.ServiceCharge.Convert(ExRate, ParentExecution.Price.Underlying); } decimal exRate = (ExRate != 0 ? ExRate : ParentExecution.ExchangeRate); if (IsMonetary) exRate = ParentExecution.ExchangeRate; ListOfTransactionComponents[] components = packageComponents(details.Amount, details.ServiceCharge, details.AccruedInterest); OrderAllocation newTrade = new OrderAllocation( this, this.account, ParentExecution.AccountA, details.Size, ParentExecution.Price, exRate, ParentExecution.TransactionDate, ParentExecution.TransactionDateTime, details.ServiceChargePercentage, this.Side, feeFactory, tradingJournalEntry, lookups, components); newTrade.Exchange = ParentExecution.Exchange; newTrade.ContractualSettlementDate = ParentExecution.ContractualSettlementDate; if (details.Commission == null) instrument.CalculateCosts(newTrade, feeFactory, lookups); else newTrade.setCommission(lookups, details.Commission); fillOrder(newTrade, details.Size, ParentExecution.Price, details.Amount, details.ServiceCharge, details.AccruedInterest); ParentExecution.Allocations.AddAllocation(newTrade); return newTrade; }
private static bool processBondPosition( IFundPosition pos, IExchange exchange, DateTime upToDate, IList<IBondCouponPaymentDailyCalculation> oldCalculations, IGLLookupRecords lookups, IDalSession session) { bool success = false; IBond bond = pos.Instrument as IBond; if (bond == null || bond.SecCategory.Key != SecCategories.Bond) throw new ApplicationException(string.Format("The instrument {0} is not a bond.", pos.Instrument.DisplayIsinWithName)); if (bond.DoesPayInterest) { DateTime calcDate; if (Util.IsNotNullDate(pos.LastBondCouponCalcDate)) calcDate = pos.LastBondCouponCalcDate.AddDays(1); else calcDate = pos.OpenDate; while (calcDate <= upToDate) { if (exchange == null) exchange = bond.DefaultExchange ?? bond.HomeExchange; InstrumentSize size = pos.PositionTransactions.Where(x => x.TransactionDate <= calcDate).Select(x => x.Size).Sum(); if (size != null && size.IsNotZero) { if (!Util.IsWeekendOrHoliday(calcDate, exchange.ExchangeHolidays)) { DateTime settlementDate = bond.GetSettlementDate(calcDate, exchange); IBondCouponPayment bip = null; DateTime lastCouponDate = bond.LastCouponDate(settlementDate); if (Util.IsNullDate(lastCouponDate)) lastCouponDate = bond.IssueDate; DateTime nextCouponDate = bond.NextCouponDate(settlementDate); if ((bond.IsPerpetual || bond.MaturityDate >= settlementDate) && Util.IsNotNullDate(lastCouponDate) && lastCouponDate <= settlementDate && Util.IsNotNullDate(nextCouponDate) && nextCouponDate >= settlementDate) { // Per position -> Does have an Active BondCouponPayment bip = pos.BondCouponPayments.GetBondCouponPaymentByDate(settlementDate); if (bip == null) { ICouponHistory couponHistory = bond.Coupons.GetCouponByDate(settlementDate); if (couponHistory == null) { couponHistory = new CouponHistory(bond, lastCouponDate, nextCouponDate); bond.Coupons.AddCoupon(couponHistory); } int journalID = int.Parse((string)(System.Configuration.ConfigurationManager.AppSettings.Get("DefaultAccruedInterestJournal"))); IJournal journal = JournalMapper.GetJournal(session, journalID); string nextJournalEntryNumber = JournalEntryMapper.GetNextJournalEntryNumber(session, journal); IMemorialBooking memorialBooking = new MemorialBooking(journal, nextJournalEntryNumber); memorialBooking.TransactionDate = couponHistory.EndAccrualDate; bip = new BondCouponPayment(pos, couponHistory, memorialBooking); pos.BondCouponPayments.AddPayment(bip); } if (bip != null) { // Add interest accrual bip.CalculateDailyInterest(size, calcDate, settlementDate, oldCalculations != null && oldCalculations.Count > 0 ? oldCalculations.Where(x => x.CalcDate == calcDate).ToList() : null, lookups); } } // If coupon payment date equals settlementDate -> set to status -> to-be-settled if (bip != null && nextCouponDate <= settlementDate) bip.SetToBeSettled(calcDate, settlementDate); // If coupon payment date -> pay (unsettled to settled) // Settle the interest List<IBondCouponPayment> bipsToBeSettled = pos.BondCouponPayments.ToBeSettledPayments(calcDate); if (bipsToBeSettled != null && bipsToBeSettled.Count > 0) { foreach (IBondCouponPayment bipToBeSettled in bipsToBeSettled) bipToBeSettled.SettleInterest(calcDate); } success = true; } pos.LastBondCouponCalcDate = calcDate; } calcDate = calcDate.AddDays(1); } } return success; }
private static bool createMgtFeeTransactionForMP(IJournal journalMgmtFee, IGLLookupRecords lookups, int mgtPeriodId, int year, int quarter, ManagementTypes managementType, FeeFactory feeFactory, DateTime minDate, DateTime maxDate, decimal taxPercentage, bool createCashInitiatedOrders) { bool retVal = false; IDalSession session = NHSessionFactory.CreateSession(); Hashtable parameterLists = new Hashtable(1); Hashtable parameters = new Hashtable(2); Util.GetDatesFromQuarter(year, quarter, out minDate, out maxDate); parameterLists.Add("periods", Util.GetPeriodsFromQuarter(year, quarter)); parameters.Add("mgtPeriodId", mgtPeriodId); parameters.Add("managementType", managementType); IList<IManagementPeriodUnit> unitsUnsorted = session.GetTypedListByNamedQuery<IManagementPeriodUnit>( "B4F.TotalGiro.ApplicationLayer.Fee.ManagementPeriodUnitsForMgtFeeTransactionCreation", parameters, parameterLists); if (unitsUnsorted != null && unitsUnsorted.Count > 0) { var unitsByMP = from a in unitsUnsorted group a by a.ManagementPeriod into g select new { ManagementPeriod = g.Key, Units = g.ToList() }; if (unitsByMP.Count() != 1) throw new ApplicationException("The number of management periods is not what is expected."); IManagementPeriod managementPeriod = unitsByMP.First().ManagementPeriod; IList<IManagementPeriodUnit> units = unitsByMP.First().Units; DateTime feeStartDate = minDate; DateTime feeEndDate = maxDate; if (managementPeriod.StartDate > minDate) feeStartDate = managementPeriod.StartDate; if (Util.IsNotNullDate(managementPeriod.EndDate) && managementPeriod.EndDate < maxDate) feeEndDate = managementPeriod.EndDate.Value; if (feeStartDate.Year != feeEndDate.Year) throw new ApplicationException("The year of the start date and end date for the management fee should equal"); string mgtFeeDescription; decimal mgtFeeThreshold; getMgtFeeInfo(managementPeriod, feeEndDate, year, quarter, out mgtFeeDescription, out mgtFeeThreshold); if (units != null && units.Count > 0) { // check the number of units int expectedUnitCount = Util.DateDiff(DateInterval.Month, feeStartDate, feeEndDate) + 1; if (expectedUnitCount != units.Count) throw new ApplicationException(string.Format("The number of units {0} does not equal the number of expected units {1}.", units.Count, expectedUnitCount)); // check if all have the same management period var mps = from a in units group a by a.ManagementPeriod into g select g.Key; if (mps.Count() != 1) throw new ApplicationException("Not all units belong to the same management period."); if (mps.First().Key != managementPeriod.Key) throw new ApplicationException("The management period is not ok."); if (Util.GetPeriodFromDate(managementPeriod.StartDate) == Util.GetPeriodFromDate(feeStartDate) && managementPeriod.StartDate.Day != feeStartDate.Day) throw new ApplicationException(string.Format("The start date of the management period ({0}) does not equal the presented start date ({1}).", managementPeriod.StartDate.ToString("yyyy-MM-dd"), feeStartDate.ToString("yyyy-MM-dd"))); if (managementPeriod.EndDate.HasValue) { if (feeEndDate > managementPeriod.EndDate) throw new ApplicationException(string.Format("The end date of the management period ({0}) does not equal the presented end date ({1}).", managementPeriod.EndDate.Value.ToString("yyyy-MM-dd"), feeEndDate.ToString("yyyy-MM-dd"))); else if (Util.GetPeriodFromDate(managementPeriod.EndDate.Value) == Util.GetPeriodFromDate(feeEndDate) && managementPeriod.EndDate.Value.Day != feeEndDate.Day) throw new ApplicationException(string.Format("The end date of the management period ({0}) does not equal the presented end date ({1}).", managementPeriod.EndDate.Value.ToString("yyyy-MM-dd"), feeEndDate.ToString("yyyy-MM-dd"))); } IAccountTypeCustomer account = (IAccountTypeCustomer)managementPeriod.Account; if (!account.ExitFeePayingAccount.Equals(account)) mgtFeeDescription += string.Format(" voor {0}", account.Number); string nextJournalEntryNumber = JournalEntryMapper.GetNextJournalEntryNumber(session, journalMgmtFee); IMemorialBooking memorialBooking = new MemorialBooking(journalMgmtFee, nextJournalEntryNumber); memorialBooking.TransactionDate = feeEndDate.AddDays(1); memorialBooking.Description = mgtFeeDescription; IManagementFee mgtFee = new ManagementFee(account, feeStartDate, feeEndDate, units, memorialBooking, taxPercentage, lookups); if (mgtFee != null && mgtFee.NettAmount != null && mgtFee.NettAmount.IsNotZero) { if (mgtFee.NettAmount.Quantity < mgtFeeThreshold) { ITradeableInstrument instrument; account = account.ExitFeePayingAccount; if (createCashInitiatedOrders && mgtFee.NeedToCreateCashInitiatedOrder(out instrument)) { if (instrument != null) { OrderAmountBased order = new OrderAmountBased(account, mgtFee.Components.TotalAmount, instrument, true, feeFactory, true); order.OrderInfo = mgtFeeDescription; mgtFee.CashInitiatedOrder = order; } else { // Sell from the biggest position IFundPosition pos = account.Portfolio.PortfolioInstrument.Where(x => x.Size.IsGreaterThanZero).OrderByDescending(x => x.CurrentValue).FirstOrDefault(); if (pos != null && (pos.CurrentBaseValue + mgtFee.NettAmount).IsGreaterThanOrEqualToZero) { OrderAmountBased order = new OrderAmountBased(account, mgtFee.Components.TotalAmount, pos.Instrument, true, feeFactory, true); order.OrderInfo = mgtFeeDescription; mgtFee.CashInitiatedOrder = order; } } } if (mgtFee.CashInitiatedOrder == null && (account.Portfolio.TotalValue() + mgtFee.TotalAmount).IsLessThanZero) throw new ApplicationException(string.Format("Could not create a management fee booking for account {0} since the total portfolio value ({1}) is insufficient.", account.DisplayNumberWithName, account.Portfolio.TotalValue().DisplayString)); mgtFee.BookLines(); GeneralOperationsBookingMapper.Update(session, mgtFee); retVal = true; } } } } session.Close(); return retVal; }
public override bool CalculateCosts(IOrderAllocation transaction, IFeeFactory feeFactory, IGLLookupRecords lookups) { return true; }