private async Task CompleteAssetSettlementAsync(AssetSettlement assetSettlement) { try { AssetHedgeSettings assetHedgeSettings = await _assetHedgeSettingsService.GetByAssetIdAsync(assetSettlement.AssetId); if (!assetSettlement.IsDirect && !assetSettlement.IsExternal) { // In this case position will be closed automatically by hedge limit order. } else { await _positionService.CloseAsync(assetSettlement.AssetId, assetHedgeSettings.Exchange, assetSettlement.ActualAmount, assetSettlement.ActualPrice); } assetSettlement.Status = AssetSettlementStatus.Completed; } catch (Exception exception) { _log.ErrorWithDetails(exception, "An error occurred while completing asset settlement", assetSettlement); assetSettlement.Error = SettlementError.Unknown; } await _settlementRepository.UpdateAsync(assetSettlement); }
public async Task ExecuteAssetAsync(string settlementId, string assetId, decimal actualAmount, decimal actualPrice, string userId) { Settlement settlement = await GetByIdAsync(settlementId); AssetSettlement assetSettlement = settlement.GetAsset(assetId); if (assetSettlement == null) { throw new InvalidOperationException("Asset not found"); } if (!assetSettlement.IsDirect || !assetSettlement.IsExternal) { throw new InvalidOperationException("Only direct external assets can be manually executed"); } var allowedStatuses = new[] { SettlementStatus.Reserved, SettlementStatus.Transferred }; if (!allowedStatuses.Contains(settlement.Status) || assetSettlement.Status != AssetSettlementStatus.New) { throw new InvalidOperationException("Can not execute asset."); } assetSettlement.ActualAmount = actualAmount; assetSettlement.ActualPrice = actualPrice; assetSettlement.Status = AssetSettlementStatus.Transferred; await _settlementRepository.UpdateAsync(assetSettlement); _log.InfoWithDetails("Asset updated", new { assetSettlement, userId }); }
public async Task RetryAssetAsync(string settlementId, string assetId, string userId) { Settlement settlement = await GetByIdAsync(settlementId); AssetSettlement assetSettlement = settlement.GetAsset(assetId); if (assetSettlement == null) { throw new InvalidOperationException("Asset not found"); } if (settlement.Status != SettlementStatus.Approved && settlement.Status != SettlementStatus.Reserved || assetSettlement.Status != AssetSettlementStatus.New && assetSettlement.Status != AssetSettlementStatus.Reserved) { throw new InvalidOperationException("Can not retry asset."); } assetSettlement.Error = SettlementError.None; await _settlementRepository.UpdateAsync(assetSettlement); _log.InfoWithDetails("Asset settlement retry", new { assetSettlement, userId }); }
public async Task UpdateAssetAsync(string settlementId, string assetId, decimal amount, bool isDirect, bool isExternal, string userId) { Settlement settlement = await GetByIdAsync(settlementId); if (settlement.Status != SettlementStatus.New) { throw new InvalidOperationException("Only new settlement can be updated"); } AssetSettlement assetSettlement = settlement.GetAsset(assetId); if (assetSettlement == null) { throw new InvalidOperationException("Asset not found"); } assetSettlement.Update(amount, isDirect, isExternal); await ValidateBalanceAsync(settlement); await _settlementRepository.ReplaceAsync(settlement); _log.InfoWithDetails("Asset updated", new { assetSettlement, userId }); }
public Task UpdateAsync(AssetSettlement assetSettlement) { return(_storage.MergeAsync( GetPartitionKey(assetSettlement.SettlementId), GetRowKey(assetSettlement.AssetId), entity => { Mapper.Map(assetSettlement, entity); return entity; })); }
private async Task TransferReservedFundsAsync(AssetSettlement assetSettlement, string clientId, string walletId) { string assetId = assetSettlement.IsDirect ? assetSettlement.AssetId : "USD"; decimal amount = assetSettlement.IsDirect ? assetSettlement.Amount : assetSettlement.Amount * assetSettlement.Price; try { string transactionId = await _settlementTransferService.TransferReservedFundsAsync(walletId, assetId, amount, clientId, assetSettlement.SettlementId); assetSettlement.TransactionId = transactionId; assetSettlement.Status = AssetSettlementStatus.Transferred; _log.InfoWithDetails("Reserved funds transferred to client wallet", new { assetSettlement.SettlementId, assetId, amount, clientId, walletId, transactionId }); } catch (NotEnoughFundsException) { assetSettlement.Error = SettlementError.NotEnoughFunds; _log.WarningWithDetails("Not enough reserved funds to transfer to client wallet", new { assetSettlement.SettlementId, assetId, amount, clientId, walletId }); } catch (Exception exception) { assetSettlement.Error = SettlementError.Unknown; _log.ErrorWithDetails(exception, "An error occurred while transferring reserved funds to client wallet", new { assetSettlement.SettlementId, assetId, amount, clientId, walletId }); } await _settlementRepository.UpdateAsync(assetSettlement); }
private async Task ReserveFundsAsync(AssetSettlement assetSettlement, string clientId) { await _settlementRepository.UpdateAsync(assetSettlement); string assetId = assetSettlement.IsDirect ? assetSettlement.AssetId : "USD"; decimal amount = assetSettlement.IsDirect ? assetSettlement.Amount : assetSettlement.Amount * assetSettlement.Price; try { await _settlementTransferService.ReserveFundsAsync(assetId, amount, clientId, assetSettlement.SettlementId); assetSettlement.Status = AssetSettlementStatus.Reserved; _log.InfoWithDetails("Funds reserved from main wallet", new { assetSettlement.SettlementId, assetId, amount, clientId }); } catch (NotEnoughFundsException) { assetSettlement.Error = SettlementError.NotEnoughFunds; _log.WarningWithDetails("Not enough funds to reserve from main wallet", new { assetSettlement.SettlementId, assetId, amount, clientId }); } catch (Exception exception) { assetSettlement.Error = SettlementError.Unknown; _log.ErrorWithDetails(exception, "An error occurred while reserving funds from main wallet", new { assetSettlement.SettlementId, assetId, amount, clientId }); } await _settlementRepository.UpdateAsync(assetSettlement); }
public Task UpdateAsync(AssetSettlement assetSettlement) { return(_assetSettlementAzureRepository.UpdateAsync(assetSettlement)); }