public MarkingTheCloseBreach( IFactorValue factorValue, ISystemProcessOperationContext operationContext, string correlationId, TimeSpan window, FinancialInstrument security, MarketOpenClose marketClose, ITradePosition tradingPosition, IMarkingTheCloseEquitiesParameters equitiesParameters, VolumeBreach dailyBreach, VolumeBreach windowBreach, string description, string caseTitle, DateTime universeDateTime) { this.FactorValue = factorValue; this.Window = window; this.Security = security ?? throw new ArgumentNullException(nameof(security)); this.MarketClose = marketClose ?? throw new ArgumentNullException(nameof(marketClose)); this.Trades = tradingPosition ?? new TradePosition(new List <Order>()); this.EquitiesParameters = equitiesParameters ?? throw new ArgumentNullException(nameof(equitiesParameters)); this.DailyBreach = dailyBreach; this.WindowBreach = windowBreach; this.RuleParameterId = equitiesParameters?.Id ?? string.Empty; this.SystemOperationId = operationContext.Id.ToString(); this.CorrelationId = correlationId; this.RuleParameters = equitiesParameters; this.Description = description ?? string.Empty; this.CaseTitle = caseTitle ?? string.Empty; this.UniverseDateTime = universeDateTime; }
/// <summary> /// The run post order event. /// </summary> /// <param name="history"> /// The history. /// </param> protected override void RunPostOrderEvent(ITradingHistoryStack history) { if (!this.processingMarketClose || this.latestMarketClosure == null) { return; } history.ArchiveExpiredActiveItems(this.latestMarketClosure.MarketClose); var securities = history.ActiveTradeHistory(); if (!securities.Any()) { // no securities were being traded within the market closure time window return; } // filter the security list by the mic of the closing market.... var filteredMarketSecurities = securities .Where(i => string.Equals( i.Market?.MarketIdentifierCode, this.latestMarketClosure.MarketId, StringComparison.InvariantCultureIgnoreCase)) .ToList(); if (!filteredMarketSecurities.Any()) { // no relevant securities were being traded within the market closure time window return; } var marketSecurities = new Stack <Order>(filteredMarketSecurities); VolumeBreach dailyVolumeBreach = null; if (this.equitiesParameters.PercentageThresholdDailyVolume != null) { dailyVolumeBreach = this.CheckDailyVolumeTraded(marketSecurities); } VolumeBreach windowVolumeBreach = null; if (this.equitiesParameters.PercentageThresholdWindowVolume != null) { windowVolumeBreach = this.CheckWindowVolumeTraded(marketSecurities); } if ((dailyVolumeBreach == null || !dailyVolumeBreach.HasBreach()) && (windowVolumeBreach == null || !windowVolumeBreach.HasBreach())) { this.logger.LogInformation($"had no breaches for {marketSecurities.FirstOrDefault()?.Instrument?.Identifiers} at {UniverseDateTime}"); return; } var position = new TradePosition(marketSecurities.ToList()); // wrong but should be a judgement var breach = new MarkingTheCloseBreach( this.OrganisationFactorValue, this.ruleContext.SystemProcessOperationContext(), this.ruleContext.CorrelationId(), this.equitiesParameters.Windows.BackwardWindowSize, marketSecurities.FirstOrDefault()?.Instrument, this.latestMarketClosure, position, this.equitiesParameters, dailyVolumeBreach ?? new VolumeBreach(), windowVolumeBreach ?? new VolumeBreach(), null, null, this.UniverseDateTime); this.logger.LogInformation($"had a breach for {marketSecurities.FirstOrDefault()?.Instrument?.Identifiers} at {UniverseDateTime}. Adding to alert stream."); var alertEvent = new UniverseAlertEvent(Domain.Surveillance.Scheduling.Rules.MarkingTheClose, breach, this.ruleContext); this.alertStream.Add(alertEvent); }