public static AssetCoinholdersViewModel Create(AssetViewModel asset,
                                                       IBalanceSummary balanceSummary,
                                                       int?atBlockHeight,
                                                       IDictionary <string, double> addressChanges,
                                                       IEnumerable <IBalanceBlock> blocksWithChanges,
                                                       IBlockHeader currentBlock,
                                                       IBlockHeader atBlockInfo)
        {
            var total            = balanceSummary.AddressSummaries.Sum(p => p.Balance);
            var addressSummaries = balanceSummary.AddressSummaries
                                   .Select(
                p =>
                BalanceAddressSummary.Create(p, total, asset.Divisibility,
                                             addressChanges.ContainsKey(p.Address) ? addressChanges[p.Address] : 0))
                                   .Where(p => p.Balance != 0 || p.ChangeAtBlock != 0)
                                   .OrderByDescending(p => p.Balance)
                                   .ToList();

            return(new AssetCoinholdersViewModel
            {
                Asset = asset,
                AddressSummaries = addressSummaries,
                Total = BitcoinUtils.CalculateColoredAssetQuantity(total, asset.Divisibility),
                Pagination = BlockPagination.Create(blocksWithChanges.Select(p => p.Height), atBlockHeight ?? currentBlock?.Height, currentBlock),
                CoinholdersCount = addressSummaries.Count,
                AtBlockDateTime = (atBlockInfo ?? currentBlock)?.Time.ToUniversalTime()
            });
        }
        public static AssetCoinholdersIndex Create(IBalanceSummary balanceSummary, IEnumerable <IBalanceBlock> blocksWithChanges, int transactionCount, int lastMonthTransactionCount, DateTime?lastTxDate)
        {
            var addressDic    = balanceSummary.AddressSummaries.GroupBy(p => p.Address).Where(p => p.Sum(x => x.Balance) != 0).ToDictionary(p => p.Key, p => p.Sum(x => x.Balance));
            var totalQuantity = addressDic.Sum(p => p.Value);

            return(new AssetCoinholdersIndex
            {
                AssetIds = balanceSummary.AssetIds,
                CoinholdersCount = addressDic.Count,
                TotalQuantity = totalQuantity,
                HerfindalShareIndex = HerfindahlIndex.Calculate(addressDic.Values.Select(p => HerfindahlIndex.CalculateShare(p, totalQuantity))),
                TopCoinholderShare = HerfindahlIndex.CalculateShare(addressDic.Values.DefaultIfEmpty().Max(), totalQuantity),
                TransactionsCount = transactionCount,
                LastTxDate = lastTxDate,
                LastMonthTransactionCount = lastMonthTransactionCount
            });
        }