/// <summary> /// Receive and cache rule breach in memory /// </summary> public void Send(ICancelledOrderRuleBreach ruleBreach) { if (ruleBreach == null) { // ReSharper disable once InconsistentlySynchronizedField this._logger.LogInformation( $"Cancelled Order Rule Cached Message Sender received a null rule breach {ruleBreach.Security.Identifiers}. Returning."); return; } lock (this._lock) { this._logger.LogInformation( $"Cancelled Order Rule Cached Message Sender received rule breach for {ruleBreach.Security.Identifiers}"); var duplicates = this._messages.Where(msg => msg.Trades.PositionIsSubsetOf(ruleBreach.Trades)).ToList(); if (duplicates != null && duplicates.Any()) { this._logger.LogInformation( $"Cancelled Order Rule Cached Message Sender removing {duplicates.Count} duplicates for {ruleBreach.Security.Identifiers}"); } this._messages = this._messages.Except(duplicates).ToList(); this._messages.Add(ruleBreach); } }
private string PositionSizeText( ICancelledOrderRuleEquitiesParameters parameters, ICancelledOrderRuleBreach ruleBreach, decimal percentagePositionCancelled) { return(ruleBreach.ExceededPercentagePositionCancellations ? $" Position cancelled exceeded threshold at {percentagePositionCancelled}% cancelled. Limit was set at {parameters.CancelledOrderPercentagePositionThreshold * 100}%. {ruleBreach.AmountOfPositionInTotal} orders in the security in during the breach in total of which {ruleBreach.AmountOfPositionCancelled} were cancelled." : string.Empty); }
private string OrderRatioText( ICancelledOrderRuleEquitiesParameters parameters, ICancelledOrderRuleBreach ruleBreach, decimal tradeCountCancelled) { return(ruleBreach.ExceededPercentageTradeCountCancellations ? $" Number of orders cancelled exceeded threshold at {tradeCountCancelled}% cancelled. Limit was set at {parameters.CancelledOrderCountPercentageThreshold * 100}%." : string.Empty); }
public async Task Send(ICancelledOrderRuleBreach ruleBreach) { if (ruleBreach?.Trades == null || !ruleBreach.Trades.Get().Any()) { return; } var description = this.BuildDescription( ruleBreach.Parameters, ruleBreach, ruleBreach.Trades.Get().FirstOrDefault()); await this.Send(ruleBreach, description); }
private string BuildDescription( ICancelledOrderRuleEquitiesParameters parameters, ICancelledOrderRuleBreach ruleBreach, Order anyOrder) { var percentagePositionCancelled = Math.Round( ruleBreach.PercentagePositionCancelled.GetValueOrDefault(0) * 100m, 2, MidpointRounding.AwayFromZero); var tradeCountCancelled = Math.Round( ruleBreach.PercentageTradeCountCancelled.GetValueOrDefault(0) * 100m, 2, MidpointRounding.AwayFromZero); var positionSizeSegment = this.PositionSizeText(parameters, ruleBreach, percentagePositionCancelled); var orderRatioSegment = this.OrderRatioText(parameters, ruleBreach, tradeCountCancelled); var description = $"Cancelled Order Rule Breach. Traded ({anyOrder?.OrderDirection.GetDescription()}) security {anyOrder?.Instrument?.Name} with excessive cancellations in {parameters.Windows.BackwardWindowSize.TotalMinutes} minute time period.{positionSizeSegment}{orderRatioSegment}"; return(description); }