public void Setup() { this.logger = new NullLogger <FixedIncomeHighVolumeJudgementMapper>(); this.context = A.Fake <IFixedIncomeHighVolumeJudgementContext>(); this.financialInstrument = A.Fake <IFinancialInstrument>(); A.CallTo(() => this.context.Security).Returns(this.financialInstrument); }
/// <summary> /// The judgement. /// </summary> /// <param name="highVolumeJudgementContext"> /// The high volume judgement context. /// </param> /// <returns> /// The <see cref="Task"/>. /// </returns> public async Task Judgement(IFixedIncomeHighVolumeJudgementContext highVolumeJudgementContext) { if (highVolumeJudgementContext == null) { this.logger?.LogError("Fixed Income High Volume Judgement was null"); return; } if (string.IsNullOrWhiteSpace(highVolumeJudgementContext?.Judgement?.OrderId)) { this.logger?.LogError("Fixed Income High Volume Judgement had no order id"); return; } await this.judgementRepository.SaveAsync(highVolumeJudgementContext.Judgement); if (!highVolumeJudgementContext.RaiseRuleViolation) { return; } var projectedBreach = this.fixedIncomeHighVolumeJudgementMapper.MapContextToBreach(highVolumeJudgementContext); this.ruleViolationService.AddRuleViolation(projectedBreach); }
/// <summary> /// The build description functionality for a case. /// </summary> /// <param name="judgementContext"> /// The judgement context. /// </param> /// <returns> /// The <see cref="string"/>. /// </returns> public string BuildDescription(IFixedIncomeHighVolumeJudgementContext judgementContext) { var issuanceTitleSegment = judgementContext.IsIssuanceBreach ? " (%) issuance" : string.Empty; var description = $"Fixed Income High Volume{issuanceTitleSegment} rule breach detected for {judgementContext.Security?.Name}."; var dailyDescription = this.BuildDailyBreachDescription(judgementContext); var windowDescription = this.BuildWindowBreachDescription(judgementContext); description = $"{description}{dailyDescription}{windowDescription}"; return(description); }
/// <summary> /// The mapping from judgement to rule breach . /// </summary> /// <param name="judgementContext"> /// The judgement context. /// </param> /// <returns> /// The <see cref="IRuleBreach"/>. /// </returns> public IRuleBreach MapContextToBreach(IFixedIncomeHighVolumeJudgementContext judgementContext) { if (judgementContext == null) { this.logger?.LogInformation($"{nameof(judgementContext)} was null in map. Returning."); return(null); } var issuanceTitleSegment = judgementContext.IsIssuanceBreach ? " (%) issuance" : string.Empty; var caseTitle = $"Automated Fixed Income High Volume{issuanceTitleSegment} Rule Breach Detected"; var description = this.BuildDescription(judgementContext); var ruleBreach = new RuleBreach(judgementContext.RuleBreachContext, description, caseTitle); return(ruleBreach); }
/// <summary> /// The build daily breach description. /// </summary> /// <param name="judgementContext"> /// The judgement context. /// </param> /// <returns> /// The <see cref="string"/>. /// </returns> private string BuildDailyBreachDescription(IFixedIncomeHighVolumeJudgementContext judgementContext) { if (!judgementContext?.Judgement?.DailyAnalysisAnalysis?.VolumeBreach ?? false) { return(string.Empty); } var dailyPercentage = Math.Round(judgementContext.Judgement.DailyAnalysisAnalysis.VolumeThresholdPercentage.GetValueOrDefault(0) * 100, 2); var dailyBreachPercentage = Math.Round(judgementContext.Judgement.DailyAnalysisAnalysis.VolumeTradedPercentage.GetValueOrDefault(0) * 100, 2); var venueDailyDescription = judgementContext.Venue != null ? $" at the venue ({judgementContext.Venue?.MarketIdentifierCode}) {judgementContext.Venue?.Name}" : string.Empty; var dailyDescription = $" Percentage of daily volume breach has occured. A daily volume limit of {dailyPercentage.ToString("0.##")}% was exceeded by trading {dailyBreachPercentage.ToString("0.##")}% of daily volume{venueDailyDescription}. {judgementContext?.Judgement?.DailyAnalysisAnalysis?.VolumeTradedAmount?.ToString("0.##")} volume was the allocated fill against a breach threshold volume of {judgementContext?.Judgement?.DailyAnalysisAnalysis?.VolumeThresholdAmount?.ToString("0.##")}."; return(dailyDescription); }
/// <summary> /// The build window breach description. /// </summary> /// <param name="judgementContext"> /// The judgement context. /// </param> /// <returns> /// The <see cref="string"/>. /// </returns> private string BuildWindowBreachDescription(IFixedIncomeHighVolumeJudgementContext judgementContext) { if (!judgementContext?.Judgement?.WindowAnalysisAnalysis?.VolumeBreach ?? false) { return(string.Empty); } var windowPercentage = Math.Round(judgementContext.Judgement.WindowAnalysisAnalysis.VolumeThresholdPercentage.GetValueOrDefault(0) * 100, 2); var windowBreachPercentage = Math.Round(judgementContext.Judgement.WindowAnalysisAnalysis.VolumeTradedPercentage.GetValueOrDefault(0) * 100, 2); var venueWindowDescription = judgementContext.Venue != null ? $" at the venue ({judgementContext.Venue?.MarketIdentifierCode}) {judgementContext.Venue?.Name}" : string.Empty; var windowDescription = $" Percentage of window volume breach has occured. A window volume limit of {windowPercentage.ToString("0.##")}% was exceeded by trading {windowBreachPercentage.ToString("0.##")}% of window volume within the window of {judgementContext?.FixedIncomeParameters?.Windows?.BackwardWindowSize.TotalMinutes} minutes{venueWindowDescription}. {judgementContext?.Judgement?.WindowAnalysisAnalysis?.VolumeTradedAmount?.ToString("0.##")} volume was the allocated fill against a breach threshold volume of {judgementContext?.Judgement?.WindowAnalysisAnalysis?.VolumeThresholdAmount?.ToString("0.##")}."; return(windowDescription); }
public void Setup() { this.judgementRepository = A.Fake <IJudgementRepository>(); this.highProfitJudgementContext = A.Fake <IHighProfitJudgementContext>(); this.cancelledOrderJudgementContext = A.Fake <ICancelledOrderJudgement>(); this.highVolumeJudgementContext = A.Fake <IHighVolumeJudgement>(); this.layeringJudgementContext = A.Fake <ILayeringJudgement>(); this.placingOrdersWithNoIntentJudgementContext = A.Fake <IPlacingOrdersWithNoIntentToExecuteJudgement>(); this.rampingJudgementContext = A.Fake <IRampingJudgement>(); this.markingTheCloseJudgementContext = A.Fake <IMarkingTheCloseJudgement>(); this.spoofingJudgementContext = A.Fake <ISpoofingJudgement>(); this.highProfitJudgementMapper = A.Fake <IHighProfitJudgementMapper>(); this.fixedIncomeProfitJudgementMapper = A.Fake <IFixedIncomeHighProfitJudgementMapper>(); this.fixedIncomeProfitJudgementContext = A.Fake <IFixedIncomeHighProfitJudgementContext>(); this.fixedIncomeHighVolumeJudgementMapper = A.Fake <IFixedIncomeHighVolumeJudgementMapper>(); this.fixedIncomeHighVolumeJudgementContext = A.Fake <IFixedIncomeHighVolumeJudgementContext>(); this.ruleViolationService = A.Fake <IRuleViolationService>(); this.logger = A.Fake <ILogger <JudgementService> >(); }