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); }
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}."); }