private NewAndUpdatedFilledOrders IdentifyRecentNewAndUpdatedOrders(TimeSortedCollection <FilledOrder> liveOrders, DateTime lookAfterTime) { // After the matching process, any unmatched filled orders will be the new filled orders TimeSortedCollection <FilledOrder> unmatchedRecentLiveOrders = new TimeSortedCollection <FilledOrder>( liveOrders.Where(order => order.Time >= lookAfterTime)); IList <UpdatedFilledOrder> updatedFilledOrders = new List <UpdatedFilledOrder>(); // Only retrieve orders from the last "lookbackMinutes" minutes (call it X) for matching. This assumes that: // 1) Order times will not be updated AFTER X minutes // 2) It takes longer than X minutes for every visible order in the live portfolio to be pushed out of view TimeSortedCollection <FilledOrder> unmatchedRecentDbOrders = new TimeSortedCollection <FilledOrder>( GetTodaysFilledOrders().Where(order => order.Time >= lookAfterTime)); // 1st pass: Match with exact time. DO NOT use ToList(), since it creates a copy of each of the items! foreach (FilledOrder dbOrder in unmatchedRecentDbOrders) { FilledOrder?match = unmatchedRecentLiveOrders.FirstOrDefault(o => dbOrder.StrictEquals(o)); if (match != null) { unmatchedRecentLiveOrders.Remove(match); unmatchedRecentDbOrders.Remove(dbOrder); } } // 2nd pass: Match using closest time foreach (FilledOrder dbOrder in unmatchedRecentDbOrders) { FilledOrder?match = unmatchedRecentLiveOrders.Where(o => dbOrder.EqualsIgnoreTime(o) && o.Time > dbOrder.Time).FirstOrDefault(); if (match != null) { unmatchedRecentLiveOrders.Remove(match); UpdatedFilledOrder updated = new UpdatedFilledOrder(dbOrder, match); updatedFilledOrders.Add(updated); Log.Information("Updated order {@OldOrder} to {@NewOrder}", dbOrder, match); } else { PortfolioDatabaseException ex = new PortfolioDatabaseException("No live order matched to database order"); Log.Error(ex, "No live order matched to database order {@Order}- Symbol {Symbol}. Current live orders {@LiveOrders}", dbOrder, dbOrder.Symbol, liveOrders); throw ex; } } TimeSortedCollection <FilledOrder> newOrders = new TimeSortedCollection <FilledOrder>(unmatchedRecentLiveOrders); return(new NewAndUpdatedFilledOrders(newOrders, updatedFilledOrders)); }
private TimeSortedCollection <FilledOrder> IdentifyOldUnseenOrders(TimeSortedCollection <FilledOrder> liveOrders, DateTime lookBeforeTime) { TimeSortedCollection <FilledOrder> unseenOrders = new TimeSortedCollection <FilledOrder>(); // Add any older olders that have not been seen before to the "newOrders" set. TimeSortedCollection <FilledOrder> oldLiveOrders = new TimeSortedCollection <FilledOrder>( liveOrders.Where(order => order.Time < lookBeforeTime)); foreach (FilledOrder oldLiveOrder in oldLiveOrders.Where(o => !OrderAlreadyExists(o))) { unseenOrders.Add(oldLiveOrder); } if (oldLiveOrders.Count > 0 && unseenOrders.Contains(oldLiveOrders.First())) { Log.Warning("Oldest visible live order was found to be new. This may indicate that some orders were missed."); } return(unseenOrders); }