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]"); } }
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]"); } }
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); } }
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); } }