private async Task Handle(OrderHistoryEvent e) { var order = e.OrderSnapshot; var isBasicOrder = new[] { OrderTypeContract.Market, OrderTypeContract.Limit, OrderTypeContract.Stop } .Contains(order.Type); if (!isBasicOrder || !order.ProductComplexityConfirmationReceived()) { return; } _log.LogInformation($"Product complexity confirmation received for account {order.AccountId} and orderId {order.Id}"); var entity = await _complexityWarningRepository.GetOrCreate(order.AccountId, () => ComplexityWarningState.Start(order.AccountId)); entity.OnConfirmedOrderReceived(order.Id, order.CreatedTimestamp, _settings.ComplexityWarningsCount, out var confirmationFlagShouldBeSwitched); if (confirmationFlagShouldBeSwitched) { await _accountManagementService.UpdateComplexityWarningFlag(order.AccountId, shouldShowProductComplexityWarning : false, order.Id); _log.LogInformation($"Flag {BrokerFeature.ProductComplexityWarning} for account {entity.AccountId} is switched to off"); } await _complexityWarningRepository.Save(entity); }
public void ShouldBeAbleToSwitchFlag() { var subject = ComplexityWarningState.Start(AccountId); var epoch = DateTime.UnixEpoch; var dtAfterFirstOrder = epoch.AddDays(1); subject.OnConfirmedOrderReceived(orderId: Guid.NewGuid().ToString(), dtAfterFirstOrder, 2, out var confirmationFlagSwitched); confirmationFlagSwitched.Should().BeFalse("After first order confirmation flag should not be switched"); subject.ShouldShowComplexityWarning.Should().BeTrue(); subject.SwitchedToFalseAt.Should().BeNull(); subject.ConfirmedOrders.Count.Should().Be(1); var dtAfterSecondOrder = epoch.AddDays(2); subject.OnConfirmedOrderReceived(orderId: Guid.NewGuid().ToString(), dtAfterSecondOrder, 2, out confirmationFlagSwitched); confirmationFlagSwitched.Should().BeTrue("After second order confirmation flag should be switched"); subject.ShouldShowComplexityWarning.Should().BeFalse(); subject.SwitchedToFalseAt.Should().Be(dtAfterSecondOrder); subject.ConfirmedOrders.Count.Should().Be(2); var dtAfterThirdOrder = epoch.AddDays(3); subject.OnConfirmedOrderReceived(orderId: Guid.NewGuid().ToString(), dtAfterThirdOrder, 2, out confirmationFlagSwitched); confirmationFlagSwitched.Should().BeFalse("After all next orders confirmation flag should be untouched"); subject.ShouldShowComplexityWarning.Should().BeFalse(); subject.SwitchedToFalseAt.Should().Be(dtAfterSecondOrder); subject.ConfirmedOrders.Count.Should().Be(3); }
public async Task Save(ComplexityWarningState entity) { await using var conn = new SqlConnection(_connectionString); var propsToUpdate = typeof(DbSchema).GetProperties().Where(p => p.Name != nameof(DbSchema.RowVersion)); var updateStatement = string.Join(",", propsToUpdate.Select(x => "[" + x.Name + "]=@" + x.Name)); //Dapper.Contrib does not support optimistic concurrency, that's why we have to write plain sql here instead of Update //see https://github.com/StackExchange/Dapper/issues/851 var sql = @$ " update dbo.MarginTradingAccountsComplexityWarnings set {updateStatement} where AccountId = @{nameof(DbSchema.AccountId)} and RowVersion = @{nameof(DbSchema.RowVersion)}
public void ShouldNotRaiseFlagChangeOnRetry() { var subject = ComplexityWarningState.Start(AccountId); var orderId = Guid.NewGuid().ToString(); var cnt = 0; do { subject.OnConfirmedOrderReceived(orderId: orderId, DateTime.Now, 2, out var confirmationFlagSwitched); confirmationFlagSwitched.Should().BeFalse(); subject.ShouldShowComplexityWarning.Should().BeTrue(); subject.ConfirmedOrders.Count.Should().Be(1); cnt++; } while (cnt < 10); }
public void ShouldBeAbleToResetConfirmation() { //Arrange var subject = ComplexityWarningState.Start(AccountId); var cnt = 0; do { subject.OnConfirmedOrderReceived(Guid.NewGuid().ToString(), DateTime.Now, 2, out var _); cnt++; } while (cnt < 10); subject.ShouldShowComplexityWarning.Should().BeFalse(); subject.SwitchedToFalseAt.Should().NotBeNull(); //Act subject.ResetConfirmation(); //Assert subject.ShouldShowComplexityWarning.Should().BeTrue(); subject.SwitchedToFalseAt.Should().BeNull(); subject.ConfirmedOrders.Should().BeEmpty(); }