private void CommitStopout(MarginTradingAccount account) { var activeOrders = _ordersCache.ActiveOrders.GetOrdersByAccountIds(account.Id); var ordersToClose = new List <Order>(); var newAccountUsedMargin = account.GetUsedMargin(); foreach (var order in activeOrders.OrderBy(o => o.GetTotalFpl())) { if (newAccountUsedMargin <= 0 || account.GetTotalCapital() / newAccountUsedMargin > account.GetMarginCallLevel()) { break; } ordersToClose.Add(order); newAccountUsedMargin -= order.GetMarginMaintenance(); } if (!ordersToClose.Any()) { return; } _stopoutEventChannel.SendEvent(this, new StopOutEventArgs(account, ordersToClose.ToArray())); foreach (var order in ordersToClose) { SetOrderToClosingState(order, OrderCloseReason.StopOut); } }
public void UpdateBalance(MarginTradingAccount account) { UpdateAccount(account.ClientId, account.Id, x => { x.Balance = account.Balance; x.WithdrawTransferLimit = account.WithdrawTransferLimit; }); }
public StopOutEventArgs(MarginTradingAccount account) { if (account == null) { throw new ArgumentNullException(nameof(account)); } Account = account; }
private static MarginTradingAccount GetDumbMarginTradingAccount() { var result = new MarginTradingAccount(); result.AccountFpl.ActualHash = 1; result.AccountFpl.CalculatedHash = 1; return(result); }
private void NotifyAccountLevelChanged(MarginTradingAccount account, AccountLevel newAccountLevel) { switch (newAccountLevel) { case AccountLevel.MarginCall: _marginCallEventChannel.SendEvent(this, new MarginCallEventArgs(account)); break; } }
private void NotifyAccountStatsChanged(MarginTradingAccount account) { account.CacheNeedsToBeUpdated(); // not needed right now //var stats = account.ToRabbitMqContract(); //_rabbitMqNotifyService.UpdateAccountStats(new AccountStatsUpdateMessage {Accounts = new[] {stats}}); }
public void SendEmailStopOutCyprus() { var testAccount = new MarginTradingAccount { Id = "TestAccountId", BaseAssetId = "EUR", LegalEntity = LykkeConstants.LykkeCyprusLegalEntity }; _emailService.SendStopOutEmailAsync(testAccount); }
public void SendEmailStopOut() { var testAccount = new MarginTradingAccount { Id = "TestAccountId", BaseAssetId = "EUR", LegalEntity = "DEFAULT" }; _emailService.SendStopOutEmailAsync(testAccount); }
private async Task Handle(FreezeAmountForWithdrawalCommand command, IEventPublisher publisher) { var(executionInfo, _) = await _operationExecutionInfoRepository.GetOrAddAsync( operationName : OperationName, operationId : command.OperationId, factory : () => new OperationExecutionInfo <WithdrawalFreezeOperationData>( operationName: OperationName, id: command.OperationId, lastModified: _dateService.Now(), data: new WithdrawalFreezeOperationData { State = OperationState.Initiated, AccountId = command.AccountId, Amount = command.Amount, } )); MarginTradingAccount account = null; try { account = _accountsCacheService.Get(command.AccountId); } catch { publisher.PublishEvent(new AmountForWithdrawalFreezeFailedEvent(command.OperationId, _dateService.Now(), command.AccountId, command.Amount, $"Failed to get account {command.AccountId}")); return; } if (executionInfo.Data.SwitchState(OperationState.Initiated, OperationState.Started)) { if (account.GetFreeMargin() >= command.Amount) { await _accountUpdateService.FreezeWithdrawalMargin(command.AccountId, command.OperationId, command.Amount); _chaosKitty.Meow(command.OperationId); publisher.PublishEvent(new AmountForWithdrawalFrozenEvent(command.OperationId, _dateService.Now(), command.AccountId, command.Amount, command.Reason)); } else { publisher.PublishEvent(new AmountForWithdrawalFreezeFailedEvent(command.OperationId, _dateService.Now(), command.AccountId, command.Amount, "Not enough free margin")); } _chaosKitty.Meow(command.OperationId); await _operationExecutionInfoRepository.Save(executionInfo); } }
public async Task <DataReaderAccountBackendContract> GetAccountById(string id) { var account = await _accountsRepository.GetAsync(id); if (account == null) { throw new AccountNotFoundException(id, "Account was not found."); } return(ToBackendContract(MarginTradingAccount.Create(account), _dataReaderSettings.IsLive)); }
public static AccountRecord ConvertToDto(this MarginTradingAccount account) { return(new AccountRecord { Id = account.Id, ClientId = account.ClientId, TradingConditionId = account.TradingConditionId, BaseAssetId = account.BaseAssetId, Balance = account.Balance.GetValueOrDefault(), WithdrawTransferLimit = account.WithdrawTransferLimit.GetValueOrDefault() }); }
public MarginTradingAccount GuessAccountWithOrder(Order order) { var accountFpl = new AccountFpl(); var newInstance = MarginTradingAccount.Create(_accountsCacheService.Get(order.ClientId, order.AccountId), accountFpl); var orders = _ordersCache.ActiveOrders.GetOrdersByInstrumentAndAccount(order.Instrument, order.AccountId).ToList(); orders.Add(order); UpdateAccount(newInstance, accountFpl, orders.ToArray()); return(newInstance); }
public StopOutEventArgs(MarginTradingAccount account, Order[] orders) { if (account == null) { throw new ArgumentNullException(nameof(account)); } if (orders == null) { throw new ArgumentNullException(nameof(orders)); } Account = account; Orders = orders; }
public void TryAddNew(MarginTradingAccount account) { _lockSlim.EnterWriteLock(); try { account.LastUpdateTime = _dateService.Now(); _accounts.TryAdd(account.Id, account); } finally { _lockSlim.ExitWriteLock(); } }
public MarginTradingAccount GuessAccountWithNewActiveOrder(Order order) { var newInstance = MarginTradingAccount.Create(_accountsCacheService.Get(order.ClientId, order.AccountId)); var activeOrders = GetActiveOrders(newInstance.Id); activeOrders.Add(order); var pendingOrders = GetPendingOrders(newInstance.Id); UpdateAccount(newInstance, activeOrders, pendingOrders); return(newInstance); }
public static AccountStatEntity Create(MarginTradingAccount account, DateTime now) { return(new AccountStatEntity { Id = account.Id, PnL = account.GetPnl(), UnrealizedDailyPnl = account.GetUnrealizedDailyPnl(), UsedMargin = account.GetUsedMargin(), MarginInit = account.GetMarginInit(), OpenPositionsCount = account.GetOpenPositionsCount(), MarginCall1Level = account.GetMarginCall1Level(), MarginCall2Level = account.GetMarginCall2Level(), StopoutLevel = account.GetStopOutLevel(), WithdrawalFrozenMargin = account.GetFrozenMargin(), UnconfirmedMargin = account.GetUnconfirmedMargin(), HistoryTimestamp = now, }); }
private void CommitStopout(MarginTradingAccount account) { var pendingOrders = _ordersCache.WaitingForExecutionOrders.GetOrdersByAccountIds(account.Id); var cancelledPendingOrders = new List <Order>(); foreach (var pendingOrder in pendingOrders) { cancelledPendingOrders.Add(pendingOrder); CancelPendingOrder(pendingOrder.Id, OrderCloseReason.CanceledBySystem, "Stop out"); } var activeOrders = _ordersCache.ActiveOrders.GetOrdersByAccountIds(account.Id); var ordersToClose = new List <Order>(); var newAccountUsedMargin = account.GetUsedMargin(); foreach (var order in activeOrders.OrderBy(o => o.GetTotalFpl())) { if (newAccountUsedMargin <= 0 || account.GetTotalCapital() / newAccountUsedMargin > account.GetMarginCallLevel()) { break; } ordersToClose.Add(order); newAccountUsedMargin -= order.GetMarginMaintenance(); } if (!ordersToClose.Any() && !cancelledPendingOrders.Any()) { return; } _stopoutEventChannel.SendEvent(this, new StopOutEventArgs(account, ordersToClose.Concat(cancelledPendingOrders).ToArray())); foreach (var order in ordersToClose) { SetOrderToClosingState(order, OrderCloseReason.StopOut); } }
public async Task <MarginTradingAccount> UpdateBalanceAsync(string clientId, string accountId, decimal amount, bool changeLimit) { var account = await _tableStorage.GetDataAsync(MarginTradingAccountEntity.GeneratePartitionKey(clientId), MarginTradingAccountEntity.GenerateRowKey(accountId)); if (account != null) { account.Balance += (double)amount; if (changeLimit) { account.WithdrawTransferLimit += (double)amount; } await _tableStorage.InsertOrMergeAsync(account); return(MarginTradingAccount.Create(account)); } return(null); }
public static MarginTradingAccountClientContract ToClientContract(this MarginTradingAccount src) { return(new MarginTradingAccountClientContract { Id = src.Id, TradingConditionId = src.TradingConditionId, BaseAssetId = src.BaseAssetId, Balance = src.Balance, WithdrawTransferLimit = src.WithdrawTransferLimit, MarginCall = src.GetMarginCallLevel(), StopOut = src.GetStopOutLevel(), TotalCapital = src.GetTotalCapital(), FreeMargin = src.GetFreeMargin(), MarginAvailable = src.GetMarginAvailable(), UsedMargin = src.GetUsedMargin(), MarginInit = src.GetMarginInit(), PnL = src.GetPnl(), OpenPositionsCount = src.GetOpenPositionsCount(), MarginUsageLevel = src.GetMarginUsageLevel() }); }
private void CommitStopOut(MarginTradingAccount account, InstrumentBidAskPair quote) { if (account.IsInLiquidation()) { return; } var liquidationType = account.GetUsedMargin() == account.GetCurrentlyUsedMargin() ? LiquidationType.Normal : LiquidationType.Mco; _cqrsSender.SendCommandToSelf(new StartLiquidationInternalCommand { OperationId = _identityGenerator.GenerateGuid(),//TODO: use quote correlationId AccountId = account.Id, CreationTime = _dateService.Now(), QuoteInfo = quote?.ToJson(), LiquidationType = liquidationType, OriginatorType = OriginatorType.System, }); _stopOutEventChannel.SendEvent(this, new StopOutEventArgs(account)); }
public MarginCallEventArgs(MarginTradingAccount account, AccountLevel level) { Account = account ?? throw new ArgumentNullException(nameof(account)); MarginCallLevel = level; }
public void OneTimeSetUp() { RegisterDependencies(); _accountsCacheService = Container.Resolve <IAccountsCacheService>(); _tradingConditionsManager = Container.Resolve <TradingConditionsManager>(); _matchingEngineRoutesManager = Container.Resolve <MatchingEngineRoutesManager>(); if (_matchingEngineRoutesManager == null) { throw new Exception("Unable to resolve MatchingEngineRoutesCacheService"); } // Add user accounts var account1 = new MarginTradingAccount() { ClientId = "CLIENT001" }; var account2 = new MarginTradingAccount() { ClientId = "CLIENT002" }; var account3 = new MarginTradingAccount() { ClientId = "CLIENT003" }; var account4 = new MarginTradingAccount() { ClientId = "CLIENT004" }; _accountsCacheService.UpdateAccountsCache(account1.ClientId, new[] { account1 }); _accountsCacheService.UpdateAccountsCache(account2.ClientId, new[] { account2 }); _accountsCacheService.UpdateAccountsCache(account3.ClientId, new[] { account3 }); _accountsCacheService.UpdateAccountsCache(account4.ClientId, new[] { account4 }); // Add trading conditions System.Threading.Tasks.Task.Run(async() => { await _tradingConditionsManager.AddOrReplaceTradingConditionAsync(new TradingCondition() { Id = "TCID001", Name = "MarginTradingCondition 1", IsDefault = true }); await _tradingConditionsManager.AddOrReplaceTradingConditionAsync(new TradingCondition() { Id = "TCID003", Name = "MarginTradingCondition 3", IsDefault = false }); await _tradingConditionsManager.AddOrReplaceTradingConditionAsync(new TradingCondition() { Id = "TCID004", Name = "MarginTradingCondition 4", IsDefault = false }); await _tradingConditionsManager.AddOrReplaceTradingConditionAsync(new TradingCondition() { Id = "TCID005", Name = "MarginTradingCondition 5", IsDefault = false }); }).Wait(); System.Threading.Tasks.Task.Run(async() => { await _matchingEngineRoutesManager.AddOrReplaceRouteAsync(new MatchingEngineRoute() { Id = "1", Rank = 10, MatchingEngineId = "LYKKE" }); await _matchingEngineRoutesManager.AddOrReplaceRouteAsync(new MatchingEngineRoute() { Id = "2", Rank = 5, Instrument = "BTCUSD", MatchingEngineId = "ICM" }); await _matchingEngineRoutesManager.AddOrReplaceRouteAsync(new MatchingEngineRoute() { Id = "3", Rank = 4, TradingConditionId = "TCID001", Instrument = "EURCHF", Type = OrderDirection.Buy, MatchingEngineId = "LYKKE" }); await _matchingEngineRoutesManager.AddOrReplaceRouteAsync(new MatchingEngineRoute() { Id = "4", Rank = 3, TradingConditionId = "TCID001", ClientId = "CLIENT001", Instrument = "EURCHF", Type = OrderDirection.Buy, MatchingEngineId = "ICM" }); await _matchingEngineRoutesManager.AddOrReplaceRouteAsync(new MatchingEngineRoute() { Id = "5", Rank = 4, TradingConditionId = "TCID001", ClientId = "CLIENT002", Instrument = "EURCHF", Type = OrderDirection.Buy, MatchingEngineId = "LYKKE" }); await _matchingEngineRoutesManager.AddOrReplaceRouteAsync(new MatchingEngineRoute() { Id = "6", Rank = 4, Instrument = "EURCHF", Type = OrderDirection.Buy, MatchingEngineId = "LYKKE" }); await _matchingEngineRoutesManager.AddOrReplaceRouteAsync(new MatchingEngineRoute() { Id = "7", Rank = 4, Instrument = "EURCHF", MatchingEngineId = "LYKKE" }); await _matchingEngineRoutesManager.AddOrReplaceRouteAsync(new MatchingEngineRoute() { Id = "8", Rank = 5, ClientId = "CLIENT003", Instrument = "EURCHF", MatchingEngineId = "LYKKE" }); await _matchingEngineRoutesManager.AddOrReplaceRouteAsync(new MatchingEngineRoute() { Id = "9", Rank = 6, TradingConditionId = "TCID003", ClientId = "CLIENT002", Instrument = "EURCHF", Type = OrderDirection.Sell, MatchingEngineId = "ICM" }); await _matchingEngineRoutesManager.AddOrReplaceRouteAsync(new MatchingEngineRoute() { Id = "10", Rank = 4, TradingConditionId = "TCID004", ClientId = "CLIENT004", Instrument = "EURJPY", MatchingEngineId = "ICM" }); await _matchingEngineRoutesManager.AddOrReplaceRouteAsync(new MatchingEngineRoute() { Id = "11", Rank = 4, TradingConditionId = "TCID004", Instrument = "EURJPY", Type = OrderDirection.Buy, MatchingEngineId = "LYKKE" }); await _matchingEngineRoutesManager.AddOrReplaceRouteAsync(new MatchingEngineRoute() { Id = "12", Rank = 4, TradingConditionId = "TCID005", Instrument = "EURUSD", Type = OrderDirection.Buy, MatchingEngineId = "LYKKE" }); await _matchingEngineRoutesManager.AddOrReplaceRouteAsync(new MatchingEngineRoute() { Id = "13", Rank = 4, TradingConditionId = "TCID005", Instrument = "EURUSD", Type = OrderDirection.Buy, MatchingEngineId = "ICM" }); await _matchingEngineRoutesManager.AddOrReplaceRouteAsync(new MatchingEngineRoute() { Id = "14", Rank = 9, Instrument = "BTCEUR", MatchingEngineId = "LYKKE" }); await _matchingEngineRoutesManager.AddOrReplaceRouteAsync(new MatchingEngineRoute() { Id = "15", Rank = 7, Type = OrderDirection.Buy, MatchingEngineId = "ICM", Asset = "EUR" }); await _matchingEngineRoutesManager.AddOrReplaceRouteAsync(new MatchingEngineRoute() { Id = "16", Rank = 8, Type = OrderDirection.Sell, MatchingEngineId = "ICM", Asset = "EUR" }); }).Wait(); /* TABLE PROTOTYPE * Id Rank tradingConditionId clientId instrument type matchingEngineId asset * * 1 10 * * * * LYKKE * 2 5 * * BTCUSD * ICM * 3 4 TCID001 * EURCHF Buy LYKKE * 4 3 TCID001 CLIENT001 EURCHF Buy ICM * 5 4 TCID001 CLIENT002 EURCHF Buy LYKKE * 6 4 * * EURCHF Buy LYKKE * 7 4 * * EURCHF * LYKKE * 8 5 * CLIENT003 EURCHF * LYKKE * 9 6 TCID003 CLIENT002 EURCHF Sell ICM * 10 4 TCID004 CLIENT004 EURJPY * ICM * 11 4 TCID004 * EURJPY Buy LYKKE * 12 4 TCID005 * EURUSD Buy LYKKE * 13 4 TCID005 * EURUSD Buy ICM * 14 9 * * BTCEUR * LYKKE * 15 7 * * Buy ICM EUR * 16 8 * * Buy LYKKE EUR * * */ }
public async Task AddAsync(MarginTradingAccount account) { var entity = MarginTradingAccountEntity.Create(account); await _tableStorage.InsertOrMergeAsync(entity); }
private async Task Handle(BlockAccountsForDeletionCommand command, IEventPublisher publisher) { var executionInfo = await _operationExecutionInfoRepository.GetOrAddAsync( operationName : OperationName, operationId : command.OperationId, factory : () => new OperationExecutionInfo <DeleteAccountsOperationData>( operationName: OperationName, id: command.OperationId, lastModified: _dateService.Now(), data: new DeleteAccountsOperationData { State = OperationState.Initiated } )); //todo think how to remove state saving from commands handler here and for Withdrawal if (executionInfo.Data.SwitchState(OperationState.Initiated, OperationState.Started)) { var failedAccounts = new Dictionary <string, string>(); foreach (var accountId in command.AccountIds) { MarginTradingAccount account = null; try { account = _accountsCacheService.Get(accountId); } catch (Exception exception) { failedAccounts.Add(accountId, exception.Message); continue; } var positionsCount = _orderReader.GetPositions().Count(x => x.AccountId == accountId); if (positionsCount != 0) { failedAccounts.Add(accountId, $"Account contain {positionsCount} open positions which must be closed before account deletion."); continue; } var orders = _orderReader.GetPending().Where(x => x.AccountId == accountId).ToList(); if (orders.Any()) { var(failedToCloseOrderId, failReason) = ((string)null, (string)null); foreach (var order in orders) { try { _tradingEngine.CancelPendingOrder(order.Id, order.AdditionalInfo, command.OperationId, $"{nameof(DeleteAccountsCommandsHandler)}: force close all orders.", OrderCancellationReason.AccountInactivated); } catch (Exception exception) { failedToCloseOrderId = order.Id; failReason = exception.Message; break; } } if (failedToCloseOrderId != null) { failedAccounts.Add(accountId, $"Failed to close order [{failedToCloseOrderId}]: {failReason}."); continue; } } if (account.AccountFpl.WithdrawalFrozenMarginData.Any()) { await _log.WriteErrorAsync(nameof(DeleteAccountsCommandsHandler), nameof(BlockAccountsForDeletionCommand), account.ToJson(), new Exception("While deleting an account it contained some frozen withdrawal data. Account is deleted.")); } if (account.AccountFpl.UnconfirmedMarginData.Any()) { await _log.WriteErrorAsync(nameof(DeleteAccountsCommandsHandler), nameof(BlockAccountsForDeletionCommand), account.ToJson(), new Exception("While deleting an account it contained some unconfirmed margin data. Account is deleted.")); } if (account.Balance != 0) { await _log.WriteErrorAsync(nameof(DeleteAccountsCommandsHandler), nameof(BlockAccountsForDeletionCommand), account.ToJson(), new Exception("While deleting an account it's balance on side of TradingCore was non zero. Account is deleted.")); } if (!await UpdateAccount(account, true, r => failedAccounts.Add(accountId, r), command.Timestamp)) { continue; } } publisher.PublishEvent(new AccountsBlockedForDeletionEvent( operationId: command.OperationId, eventTimestamp: _dateService.Now(), failedAccountIds: failedAccounts )); _chaosKitty.Meow($"{nameof(BlockAccountsForDeletionCommand)}: " + "Save_OperationExecutionInfo: " + $"{command.OperationId}"); await _operationExecutionInfoRepository.Save(executionInfo); } }
public AccountBalanceChangedEventArgs([NotNull] MarginTradingAccount account) { Account = account ?? throw new ArgumentNullException(nameof(account)); }
private async Task ValidateProductComplexityConfirmation(OrderPlaceRequest order, MarginTradingAccount account) { if (!await _featureManager.IsEnabledAsync(BrokerFeature.ProductComplexityWarning)) { return; } var isBasicOrder = new[] { OrderTypeContract.Market, OrderTypeContract.Limit, OrderTypeContract.Stop } .Contains(order.Type); if (!isBasicOrder) { return; } var shouldShowProductComplexityWarning = AccountAdditionalInfoExtensions.Deserialize(account.AdditionalInfo).ShouldShowProductComplexityWarning ?? true; if (!shouldShowProductComplexityWarning) { return; } var productComplexityConfimationReceived = order.AdditionalInfo.ProductComplexityConfirmationReceived(); if (!productComplexityConfimationReceived) { throw new ValidateOrderException(OrderRejectReason.AccountInvalidState, $"Product complexity warning not received for order, placed by account {account.Id}"); } }
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); } }
public async Task <IActionResult> AddMarginTradingAccount([FromBody] MarginTradingAccount account) { await _accountManager.AddAccountAsync(account.ClientId, account.BaseAssetId, account.TradingConditionId); return(Ok()); }
public async Task <IEnumerable <DataReaderAccountBackendContract> > GetAccountsByClientId(string clientId) { return((await _accountsRepository.GetAllAsync(clientId)) .Select(x => ToBackendContract(MarginTradingAccount.Create(x), _dataReaderSettings.IsLive))); }