private async Task Handle(AccountChangedEvent e, ICommandSender sender) { if (e.Source != OperationName) { return; } var executionInfo = await _executionInfoRepository.GetAsync <GiveTemporaryCapitalData>(OperationName, e.BalanceChange.Id); if (executionInfo == null) { return; } if (executionInfo.Data.SwitchState(TemporaryCapitalState.Started, TemporaryCapitalState.ChargedOnAccount)) { sender.SendCommand( new FinishGiveTemporaryCapitalInternalCommand( e.BalanceChange.Id, _systemClock.UtcNow.UtcDateTime, true, null), _contextNames.AccountsManagement); _chaosKitty.Meow($"{nameof(AccountChangedEvent)}: " + "Save_OperationExecutionInfo:" + e.BalanceChange.Id); await _executionInfoRepository.SaveAsync(executionInfo); } }
private async Task Handle(AccountChangedEvent evt, ICommandSender sender) { if (evt.EventType != AccountChangedEventTypeContract.BalanceUpdated) { return; } if (evt.BalanceChange == null) { return; } var account = await _accountsRepository.GetAsync(evt.Account.Id); var amount = await _negativeProtectionService.CheckAsync(evt.OperationId, evt.Account.Id, evt.BalanceChange.Balance, evt.BalanceChange.ChangeAmount); if (account == null || amount == null) { return; } sender.SendCommand(new NotifyNegativeProtectionInternalCommand( Guid.NewGuid().ToString("N"), evt.OperationId, evt.OperationId, _systemClock.UtcNow.UtcDateTime, account.ClientId, account.Id, amount.Value ), _contextNames.AccountsManagement); }
private async Task Handle(AccountChangedEvent e, ICommandSender sender) { if (e.Source != OperationName) { return; } var executionInfo = await _executionInfoRepository.GetAsync <WithdrawalDepositData>(OperationName, e.BalanceChange.Id); if (executionInfo == null) { return; } if (SwitchState(executionInfo.Data, WithdrawalState.UpdatingBalance, WithdrawalState.Succeeded)) { sender.SendCommand( new CompleteWithdrawalInternalCommand( e.BalanceChange.Id), _contextNames.AccountsManagement); _chaosKitty.Meow(e.BalanceChange.Id); await _executionInfoRepository.SaveAsync(executionInfo); } }
private async Task <bool> ValidateAccount(IMarginTradingAccount account, AccountChangedEvent e) { if (account == null) { await _log.WriteWarningAsync(nameof(AccountsProjection), e.ToJson(), $"Account with id {e.Account.Id} was not found"); return(false); } return(true); }
private void HandleSwap(AccountChangedEvent e) { if (_ordersCache.Positions.TryGetPositionById(e.BalanceChange.EventSourceId, out var position)) { position.SetSwapTotal(position.SwapTotal + e.BalanceChange.ChangeAmount); } else { _log.WriteWarning("AccountChangedEvent Handler", e.ToJson(), $"Position [{e.BalanceChange.EventSourceId} was not found]"); } }
public async Task Handle(AccountChangedEvent e) { var accountId = e?.Account?.Id; if (string.IsNullOrEmpty(accountId)) { await _log.WriteWarningAsync( nameof(AccountChangedProjection), nameof(Handle), e.ToJson(), "Account id is empty"); } else { await _accountManagementService.ClearStatsCache(accountId); } }
private void HandleUnrealizedPnLTransaction(AccountChangedEvent e) { if (_ordersCache.Positions.TryGetPositionById(e.BalanceChange.EventSourceId, out var position)) { UnrealizedPnlMetadataContract metadata = null; if (!string.IsNullOrWhiteSpace(e.BalanceChange.AuditLog)) { try { metadata = e.BalanceChange.AuditLog .DeserializeJson <UnrealizedPnlMetadataContract>(); } catch { _log.WriteWarning("AccountChangedEvent Handler", e.ToJson(), $"Metadata for {AccountBalanceChangeReasonTypeContract.UnrealizedDailyPnL} not found"); } } //let's keep it for backward compatibility and for unexpected errors if (metadata == null || metadata.RawTotalPnl == default) { position.ChargePnL(e.BalanceChange.Id, e.BalanceChange.ChangeAmount); } else { position.SetChargedPnL(e.BalanceChange.Id, metadata.RawTotalPnl); } } else { _log.WriteWarning("AccountChangedEvent Handler", e.ToJson(), $"Position [{e.BalanceChange.EventSourceId} was not found]"); } }
private async Task HandleAccountReset(AccountChangedEvent e) { foreach (var pos in _ordersCache.Positions.GetPositionsByAccountIds( e.Account.Id)) { _ordersCache.Positions.Remove(pos); } foreach (var order in _ordersCache.Active.GetOrdersByAccountIds(e.Account.Id)) { _ordersCache.Active.Remove(order); } foreach (var order in _ordersCache.Inactive.GetOrdersByAccountIds(e.Account.Id)) { _ordersCache.Inactive.Remove(order); } foreach (var order in _ordersCache.InProgress.GetOrdersByAccountIds( e.Account.Id)) { _ordersCache.InProgress.Remove(order); } var warnings = _accountsCacheService.Reset(e.Account.Id, e.ChangeTimestamp); if (!string.IsNullOrEmpty(warnings)) { await _log.WriteWarningAsync(nameof(AccountChangedEvent), nameof(AccountBalanceChangeReasonTypeContract.Reset), warnings); } await _log.WriteInfoAsync(nameof(AccountChangedEvent), nameof(AccountBalanceChangeReasonTypeContract.Reset), $"Account {e.Account.Id} was reset."); }
/// <summary> /// Fires an <see cref="AccountChangedEvent"/> to all subscribers. /// </summary> /// <param name="account">the changed account</param> public void OnAccountChangedEvent(Account account) { AccountChangedEvent?.Invoke(account); }
public async Task Handle(AccountChangedEvent e) { var executionInfo = await _operationExecutionInfoRepository.GetOrAddAsync( operationName : OperationName, operationId : e.OperationId, factory : () => new OperationExecutionInfo <OperationData>( operationName: OperationName, id: e.OperationId, lastModified: _dateService.Now(), data: new OperationData { State = OperationState.Initiated } )); if (executionInfo.Data.SwitchState(OperationState.Initiated, OperationState.Finished)) { var updatedAccount = Convert(e.Account); switch (e.EventType) { case AccountChangedEventTypeContract.Created: _accountsCacheService.TryAddNew(MarginTradingAccount.Create(updatedAccount)); break; case AccountChangedEventTypeContract.Updated: { var account = _accountsCacheService.TryGet(e.Account.Id); if (await ValidateAccount(account, e) && await _accountsCacheService.UpdateAccountChanges(updatedAccount.Id, updatedAccount.TradingConditionId, updatedAccount.WithdrawTransferLimit, updatedAccount.IsDisabled, updatedAccount.IsWithdrawalDisabled, e.ChangeTimestamp)) { _accountUpdateService.RemoveLiquidationStateIfNeeded(e.Account.Id, "Trading conditions changed"); } break; } case AccountChangedEventTypeContract.BalanceUpdated: { if (e.BalanceChange != null) { var account = _accountsCacheService.TryGet(e.Account.Id); if (await ValidateAccount(account, e)) { switch (e.BalanceChange.ReasonType) { case AccountBalanceChangeReasonTypeContract.Withdraw: await _accountUpdateService.UnfreezeWithdrawalMargin(updatedAccount.Id, e.BalanceChange.Id); break; case AccountBalanceChangeReasonTypeContract.UnrealizedDailyPnL: if (_ordersCache.Positions.TryGetPositionById(e.BalanceChange.EventSourceId, out var position)) { position.ChargePnL(e.BalanceChange.Id, e.BalanceChange.ChangeAmount); } else { _log.WriteWarning("AccountChangedEvent Handler", e.ToJson(), $"Position [{e.BalanceChange.EventSourceId} was not found]"); } break; case AccountBalanceChangeReasonTypeContract.RealizedPnL: await _accountUpdateService.UnfreezeUnconfirmedMargin(e.Account.Id, e.BalanceChange.EventSourceId); break; } if (await _accountsCacheService.UpdateAccountBalance(updatedAccount.Id, e.BalanceChange.Balance, e.ChangeTimestamp)) { _accountUpdateService.RemoveLiquidationStateIfNeeded(e.Account.Id, "Balance updated"); _accountBalanceChangedEventChannel.SendEvent(this, new AccountBalanceChangedEventArgs(updatedAccount)); } } } else { _log.WriteWarning("AccountChangedEvent Handler", e.ToJson(), "BalanceChange info is empty"); } break; } case AccountChangedEventTypeContract.Deleted: //account deletion from cache is double-handled by CQRS flow _accountsCacheService.Remove(e.Account.Id); break; default: await _log.WriteErrorAsync(nameof(AccountsProjection), nameof(AccountChangedEvent), e.ToJson(), new Exception("AccountChangedEventTypeContract was in incorrect state")); break; } _chaosKitty.Meow(e.OperationId); await _operationExecutionInfoRepository.Save(executionInfo); } }
/// <summary> /// Called when [account changed]. /// </summary> /// <param name="event">The @event.</param> public void OnAccountChanged(AccountChangedEvent @event) { //Globals.CurrentUser = @event.CurrentUser; IMService.Init(@event.CurrentUser, States.����); }