internal static bool Approve(Approval approval, ISINAvailability availability) { if (approval == null || availability == null || Math.Abs(approval.Amount) > availability.Available) { return false; } return true; }
internal List<ISINAvailability> GetISINAvailability(DateTime settleDate) { //1. Get limits by ISIN (aggregate party limits) //2. Get approvals by ISIN (aggregate approvals) //3. Merge results //4. Include open positions List<PartyLimit> partyLimits = GetShortSalePartyLimits(settleDate); IEnumerable<IGrouping<String,PartyLimit>> partyLimitsByISIN = partyLimits.GroupBy(o => o.ISIN, o => o); IEnumerable<ISINAvailability> isinsLocated = partyLimitsByISIN.Select(o => new ISINAvailability { ISIN = o.Key, Date = settleDate, Maturity = o.Max(p => p.Maturity), Description = o.Max(p => p.Description), Located = o.Sum(p => p.Size) }); List<Approval> approvals = GetShortSaleApprovalRequests(settleDate); IEnumerable<IGrouping<String, Approval>> approvalsByISIN = approvals.Where(o => o.ApprovalStatus.Code == ApprovalStatus.Approved.Code).GroupBy(o => o.ISIN, o => o); IEnumerable<ISINAvailability> isinsApproved = approvalsByISIN.Select(o => new ISINAvailability { ISIN = o.Key, Date = o.Max(p => p.SettlementDate), Approved = o.Sum(p => p.Amount) }); List<ISINAvailability> merged = isinsLocated.GroupJoin( isinsApproved, loc => new { loc.ISIN, loc.Date }, app => new { app.ISIN, app.Date }, (x, y) => new ISINAvailability { ISIN = x.ISIN, Date = x.Date, Maturity = x.Maturity, Description = x.Description, Located = x.Located, Approved = y.SingleOrDefault() == null ? 0.0M : y.Single().Approved } ).ToList(); List<ISINAvailability> isinAvailabilityList = merged.Union(isinsApproved.Except(merged.Intersect(isinsLocated))).ToList(); var currentPositions = OrchestradeUtils.GetPositionsForDate(settleDate, "Bond", "Repo", "ReverseRepo"); foreach(var position in currentPositions) { var ia = isinAvailabilityList.FirstOrDefault(o => o.ISIN == position.Product.Isin); if(ia == null) { ia = new ISINAvailability(); ia.ISIN = position.Product.Isin; ia.Date = settleDate; ia.Description = position.ProductDescription; isinAvailabilityList.Add(ia); } if (ia.Maturity == null) { ia.Maturity = position.Product.RiskMaturity.ToDateTime(); } ia.CurrentPosition = ia.CurrentPosition + Convert.ToDecimal(position.TotalSettledNominal); } var openPositions = OrchestradeUtils.GetPositionsForDate(OrchestradeUtils.GetRelativeBusinessDate(settleDate, -1), "Bond", "Repo", "ReverseRepo"); var trades = OrchestradeUtils.GetTradesForDateRange(null, settleDate, settleDate, "Bond", "Repo", "ReverseRepo"); var maturingRepos = OrchestradeUtils.GetTradesForMaturityDate(null, settleDate, "Repo", "ReverseRepo"); foreach (var ia in isinAvailabilityList) { var openingPositionValue = openPositions. Where(o => o.Product.Isin.Equals(ia.ISIN, StringComparison.InvariantCultureIgnoreCase)). Sum(o => o.TotalSettledNominal); ia.OpeningPosition = Convert.ToDecimal(openingPositionValue); Product p = Env.Current.Trade.GetProductByCode(Product.IsinProductCode, ia.ISIN); if (p != null) { //ia.Trades = Convert.ToDecimal( // trades.Where(o => o.Product.UnderlyingAsset.Id == p.Id).Sum(o => o.Product.UnderlierNominal(o, o.TradeTime))); ia.BondTrades = Convert.ToDecimal( trades.Where(o => o.Product.UnderlyingAsset.Id == p.Id && o.Product.ProcessingType == "Bond") .Sum(o => o.Product.UnderlierNominal(o, o.TradeTime))); ia.RepoTrades = Convert.ToDecimal( trades.Where(o => o.Product.UnderlyingAsset.Id == p.Id && o.Product.ProcessingType != "Bond") .Sum(o => o.Product.UnderlierNominal(o, o.TradeTime))); ia.MaturingRepos = Convert.ToDecimal( -1 * maturingRepos.Where(o => o.Product.UnderlyingAsset.Id == p.Id).Sum(o => o.Product.UnderlierNominal(o, o.TradeTime))); } } return isinAvailabilityList; }