public async Task RecalculateAllAvgPrices(RecalculateAllRequest request)
        {
            var semaphore = SemaphoreManager.GetOrCreate(request.WalletId, request.AssetId);
            await semaphore.WaitAsync();

            try
            {
                _logger.LogInformation("Recalculating average open prices for wallet {WalletId} and asset {AssetId}", request.WalletId, request.AssetId);
                await using var ctx = DatabaseContext.Create(_dbContextOptionsBuilder);
                var entities = ctx.OperationHistory.Where(t => t.WalletId == request.WalletId && t.AssetId == request.AssetId && t.Status == OperationStatuses.Completed);
                var snapshot = await _snapshotCacheManager.GetSnapshot(request.WalletId, request.AssetId);

                if (snapshot != null)
                {
                    entities = entities.Where(t => t.TimeStamp >= snapshot.OpenTimestamp);
                }

                if (entities.Any())
                {
                    await RecalculatePrices(request.WalletId, request.AssetId, entities.Select(t => (OperationUpdate)t).ToList(), null);
                }
            }
            catch (Exception e)
            {
                _logger.LogError(e, "When recalculating average open prices for wallet {WalletId} and asset {AssetId}", request.WalletId, request.AssetId);
                throw;
            }
            finally
            {
                semaphore.Release();
            }
        }
        public async Task <CorrectPriceResponse> CorrectAvgPrice(CorrectPriceRequest request)
        {
            var semaphore = SemaphoreManager.GetOrCreate(request.WalletId, request.AssetId);
            await semaphore.WaitAsync();

            try
            {
                _logger.LogInformation(
                    "Correcting buying price for operation {OperationId}, wallet {WalletId}, asset {AssetId}",
                    request.OperationId, request.WalletId, request.AssetId);
                await using var ctx = DatabaseContext.Create(_dbContextOptionsBuilder);
                var correctionEntity = await ctx.OperationHistory.FirstOrDefaultAsync(t =>
                                                                                      t.WalletId == request.WalletId && t.AssetId == request.AssetId &&
                                                                                      t.OperationId == request.OperationId);

                if (correctionEntity == null)
                {
                    return new CorrectPriceResponse()
                           {
                               IsSuccess = false,
                               ErrorCode = "OperationNotFound"
                           }
                }
                ;

                correctionEntity.AssetPriceInUsd = request.AssetPriceInUsd;

                var entityBeforeCorrection = ctx.OperationHistory
                                             .Where(t => t.WalletId == request.WalletId && t.AssetId == request.AssetId &&
                                                    t.TimeStamp < correctionEntity.TimeStamp).OrderBy(t => t.TimeStamp).LastOrDefault();
                var entities = ctx.OperationHistory.Where(t =>
                                                          t.WalletId == request.WalletId && t.AssetId == request.AssetId &&
                                                          t.TimeStamp >= correctionEntity.TimeStamp);

                var snapshot =
                    new SnapshotEntity()
                {
                    OpenTimestamp = default,