Exemple #1
0
        /// <inheritdoc/>
        public async Task <SnapshotValidationResult> ValidateCurrentStateAsync()
        {
            await _log.WriteInfoAsync(nameof(SnapshotValidationService), nameof(ValidateCurrentStateAsync),
                                      $"Snapshot validation started: {DateTime.UtcNow}");

            var currentOrders    = _orderCache.GetAllOrders();
            var currentPositions = _orderCache.GetPositions();

            var tradingEngineSnapshot = await _tradingEngineSnapshotsRepository.GetLastAsync();

            await _log.WriteInfoAsync(nameof(SnapshotValidationService), nameof(ValidateCurrentStateAsync),
                                      $"Last snapshot correlationId {tradingEngineSnapshot.CorrelationId}, tradingDay {tradingEngineSnapshot.TradingDay}, timestamp {tradingEngineSnapshot.Timestamp}");

            var lastOrders    = GetOrders(tradingEngineSnapshot);
            var lastPositions = GetPositions(tradingEngineSnapshot);

            var ordersHistory = await _ordersHistoryRepository.GetLastSnapshot(tradingEngineSnapshot.Timestamp);

            var positionsHistory = await _positionsHistoryRepository.GetLastSnapshot(tradingEngineSnapshot.Timestamp);

            var restoredOrders    = RestoreOrdersCurrentStateFromHistory(lastOrders, ordersHistory);
            var restoredPositions = RestorePositionsCurrentStateFromHistory(lastPositions, positionsHistory);

            var ordersValidationResult    = CompareOrders(currentOrders, restoredOrders);
            var positionsValidationResult = ComparePositions(currentPositions, restoredPositions);

            if (ordersValidationResult.IsValid)
            {
                await _log.WriteInfoAsync(nameof(SnapshotValidationService), nameof(ValidateCurrentStateAsync),
                                          $"Orders validation result is valid");
            }
            else
            {
                await _log.WriteWarningAsync(nameof(SnapshotValidationService), nameof(ValidateCurrentStateAsync),
                                             $"Orders validation result is NOT valid. Extra: {ordersValidationResult.Extra.Count}, missed: {ordersValidationResult.Missed.Count}, inconsistent: {ordersValidationResult.Inconsistent.Count}");
            }

            if (positionsValidationResult.IsValid)
            {
                await _log.WriteInfoAsync(nameof(SnapshotValidationService), nameof(ValidateCurrentStateAsync),
                                          $"Positions validation result is valid");
            }
            else
            {
                await _log.WriteWarningAsync(nameof(SnapshotValidationService), nameof(ValidateCurrentStateAsync),
                                             $"Positions validation result is NOT valid. Extra: {positionsValidationResult.Extra.Count}, missed: {positionsValidationResult.Missed.Count}, inconsistent: {positionsValidationResult.Inconsistent.Count}");
            }

            return(new SnapshotValidationResult
            {
                Orders = ordersValidationResult,
                Positions = positionsValidationResult,
                PreviousSnapshotCorrelationId = tradingEngineSnapshot.CorrelationId
            });
        }
Exemple #2
0
        /// <summary>
        /// Infer init data from blob and history.
        /// </summary>
        private (List <Order> Orders, List <Position> Positions) InferInitDataFromBlobAndHistory()
        {
            _log.WriteInfo(nameof(OrderCacheManager), nameof(InferInitDataFromBlobAndHistory),
                           $"Start reading order and position data from blob.");

            var blobOrdersTask = _blobRepository.ReadWithTimestampAsync <List <Order> >(
                LykkeConstants.StateBlobContainer, OrdersBlobName);
            var blobPositionsTask = _blobRepository.ReadWithTimestampAsync <List <Position> >(
                LykkeConstants.StateBlobContainer, PositionsBlobName);

            var(blobOrders, blobOrdersTimestamp)       = blobOrdersTask.GetAwaiter().GetResult();
            var(blobPositions, blobPositionsTimestamp) = blobPositionsTask.GetAwaiter().GetResult();

            _log.WriteInfo(nameof(OrderCacheManager), nameof(InferInitDataFromBlobAndHistory),
                           $"Finish reading data from blob, there are [{blobOrders.Count}] orders, [{blobPositions.Count}] positions. Start checking historical data.");

            var orderSnapshotsTask    = _ordersHistoryRepository.GetLastSnapshot(blobOrdersTimestamp);
            var positionSnapshotsTask = _positionsHistoryRepository.GetLastSnapshot(blobPositionsTimestamp);
            var orderSnapshots        = orderSnapshotsTask.GetAwaiter().GetResult().Select(OrderHistory.Create).ToList();

            PreProcess(orderSnapshots);
            var positionSnapshots = positionSnapshotsTask.GetAwaiter().GetResult();

            _log.WriteInfo(nameof(OrderCacheManager), nameof(InferInitDataFromBlobAndHistory),
                           $"Finish reading historical data. #{orderSnapshots.Count} order history items since [{blobOrdersTimestamp:s}], #{positionSnapshots.Count} position history items since [{blobPositionsTimestamp:s}].");

            var(ordersResult, orderIdsChangedFromHistory) = MapOrders(blobOrders.ToDictionary(x => x.Id, x => x),
                                                                      orderSnapshots.ToDictionary(x => x.Id, x => x), _log);
            var(positionsResult, positionIdsChangedFromHistory) = MapPositions(
                blobPositions.ToDictionary(x => x.Id, x => x), positionSnapshots.ToDictionary(x => x.Id, x => x));

            if (positionIdsChangedFromHistory.Any())
            {
                var swapTotalPerPosition = _accountHistoryRepository.GetSwapTotalPerPosition(positionIdsChangedFromHistory).GetAwaiter().GetResult();
                swapTotalPerPosition.ForEach(x =>
                {
                    var position = positionsResult.Single(p => p.Id == x.Key);
                    position.SetSwapTotal(x.Value);
                });
            }

            RefreshRelated(ordersResult.ToDictionary(x => x.Id), positionsResult.ToDictionary(x => x.Id), orderSnapshots);
            ApplyExpirationDateFix(ordersResult);

            _log.WriteInfo(nameof(OrderCacheManager), nameof(InferInitDataFromBlobAndHistory),
                           $"Initializing cache with [{ordersResult.Count}] orders and [{positionsResult.Count}] positions.");

            _orderCache.InitOrders(ordersResult, positionsResult);

            if (orderIdsChangedFromHistory.Any() || positionIdsChangedFromHistory.Any())
            {
                _log.WriteInfo(nameof(OrderCacheManager), nameof(InferInitDataFromBlobAndHistory),
                               (orderIdsChangedFromHistory.Any() ? $"Some orders state was different from history: [{string.Join(",", orderIdsChangedFromHistory)}]. " : string.Empty)
                               + (positionIdsChangedFromHistory.Any() ? $"Some positions state was different from history: [{string.Join(",", positionIdsChangedFromHistory)}]. " : string.Empty)
                               + "Dumping merged order and position data to the blob."
                               );

                if (orderIdsChangedFromHistory.Any())
                {
                    DumpOrdersToRepository().Wait();
                }

                if (positionIdsChangedFromHistory.Any())
                {
                    DumpPositionsToRepository().Wait();
                }

                _log.WriteInfo(nameof(OrderCacheManager), nameof(InferInitDataFromBlobAndHistory),
                               "Finished dumping merged order and position data to the blob."
                               );
            }

            return(ordersResult, positionsResult);
        }