public async Task <IReadOnlyList <TickPrice> > GetAllAsync()
        {
            var tickPrices = _tickPricesService.GetTickPrices();

            var entities = tickPrices.SelectMany(x => x.Value).OrderBy(x => x.Source).ThenBy(x => x.AssetPair).ToList();

            var models = Mapper.Map <IReadOnlyList <TickPrice> >(entities);

            return(models);
        }
예제 #2
0
        private async Task CalculateThenSaveAndPublishAsync()
        {
            _log.Info("Started calculating index...");

            var settings = Settings;

            var whiteListAssets = settings.Assets;

            if (!whiteListAssets.Any())
            {
                _log.Info("There are no assets in the white list, skipped index calculation.");
                return;
            }

            IReadOnlyCollection <string>         topAssets;
            IReadOnlyCollection <AssetMarketCap> allMarketCaps;

            lock (_sync)
            {
                allMarketCaps = _allMarketCaps.ToList();
                topAssets     = _topAssets; // Must be obtained from _topAssets (daily rebuild changes it)
            }
            if (!topAssets.Any())
            {
                _log.Info("There are no top assets yet, skipped index calculation.");
                return;
            }

            var lastIndex = await _indexStateRepository.GetAsync();

            var sources        = settings.Sources.ToList();
            var tickPrices     = _tickPricesService.GetTickPrices(sources);
            var assetPrices    = _tickPricesService.GetAssetPrices(sources);
            var assetsSettings = settings.AssetsSettings;
            var topUsingPrices = GetAssetsUsingPrices(topAssets, assetPrices, assetsSettings);

            // If just started and prices are not present yet, then skip.
            // If started more then {_waitForTopAssetsPricesFromStart} ago then write warning to DB and log.
            var areAllPricesPresent = await ArePricesPresentForAllAssets(topAssets, topUsingPrices);

            if (!areAllPricesPresent)
            {
                return;
            }

            // Auto freeze
            await AutoFreezeIfNeeded(topAssets, topUsingPrices, lastIndex, settings);

            assetsSettings = Settings.AssetsSettings;

            // Recalculate top weights
            var topSupplies   = new Dictionary <string, decimal>();
            var topMarketCaps = allMarketCaps.Where(x => topAssets.Contains(x.Asset)).ToList();

            foreach (var mc in topMarketCaps)
            {
                topSupplies.Add(mc.Asset, mc.CirculatingSupply);
            }

            var calculatedTopMarketCaps = CalculateMarketCaps(topAssets, topSupplies, topUsingPrices);

            lock (_sync)
            {
                _lastTopAssetMarketCaps.Clear();
                foreach (var mc in calculatedTopMarketCaps)
                {
                    _lastTopAssetMarketCaps[mc.Asset] = mc.MarketCap.Value;
                }
            }

            var calculatedTopWeights = CalculateWeightsOrderedByDesc(calculatedTopMarketCaps);

            // Calculate current index state
            var indexState = CalculateIndex(lastIndex, calculatedTopWeights, topUsingPrices);

            // Calculate current index history element
            var indexHistory = new IndexHistory(
                indexState.Value,
                calculatedTopMarketCaps,
                calculatedTopWeights,
                tickPrices.SelectMany(x => x.Value).ToList(),
                assetPrices.SelectMany(x => x.Value).ToList(),
                topUsingPrices,
                DateTime.UtcNow,
                assetsSettings);

            // if there was a reset then skip until next iteration which will have initial state
            if (State == null)
            {
                if (indexState.Value != InitialIndexValue)
                {
                    _log.Info($"Skipped saving and publishing index because of reset - previous state is null and current index not equals {InitialIndexValue}.");
                    return;
                }

                await _firstStateAfterResetTimeRepository.SetAsync(indexHistory.Time);

                lock (_syncLastReset)
                    _lastReset = indexHistory.Time;

                _log.Info($"Reset at: {indexHistory.Time.ToIsoDateTime()}.");
            }

            // Skip if changed to 'disabled'
            if (!Settings.Enabled)
            {
                _log.Info($"Skipped saving and publishing index because {nameof(Settings)}.{nameof(Settings.Enabled)} = {Settings.Enabled}.");
                return;
            }

            lock (_syncLastIndexHistory)
                _lastIndexHistory = indexHistory;

            await SaveAsync(indexState, indexHistory);

            Publish(indexHistory);

            await _indexHandler.HandleAsync(indexHistory);

            _log.Info($"Finished calculating index for {calculatedTopMarketCaps.Count} assets, value: {indexState.Value}.");
        }