Ejemplo n.º 1
0
        IReadOnlyDictionary <CurrencyCode, SumState> CalculateAssetSums(
            AssetISIN isin, IReadOnlyCollection <VirtualAsset> allAssets, DateTimeOffset date)
        {
            var assets = allAssets
                         .Where(a => a.Isin == isin)
                         .ToArray();

            if (assets.Length == 0)
            {
                return(new Dictionary <CurrencyCode, SumState>());
            }
            var baseCurrency   = assets[0].Currency;
            var baseRealSum    = assets.Sum(a => a.RealSum);
            var baseVirtualSum = assets.Sum(a => a.VirtualSum);

            return(_currencyConfig.GetAll()
                   .ToDictionary(
                       c => c,
                       c => {
                if (c == baseCurrency)
                {
                    return new SumState(baseRealSum, baseVirtualSum);
                }
                var realSum = _exchangeManager.Exchange(baseCurrency, c, baseRealSum, date);
                var virtualSum = _exchangeManager.Exchange(baseCurrency, c, baseRealSum, date);
                return new SumState(realSum, virtualSum);
            }
                       ));
        }
Ejemplo n.º 2
0
 public ReadOnlyAsset(Asset asset)
 {
     Id       = asset.Id;
     Isin     = asset.Isin;
     Currency = asset.Currency;
     RawName  = asset.RawName;
     Count    = asset.Count;
 }
Ejemplo n.º 3
0
 public Asset(AssetId id, AssetISIN isin, CurrencyCode currency, string rawName, int count)
 {
     Id       = id;
     Isin     = isin;
     Currency = currency;
     Count    = count;
     RawName  = rawName;
 }
Ejemplo n.º 4
0
        AssetMetadata?GetMetadata(AssetISIN isin)
        {
            var models = _repository.GetAll();
            var model  = models.FirstOrDefault(m => m.Isin == isin);

            return((model != null)
                                ? new AssetMetadata(new(model.Isin), new(model.Figi), model.Name, new(model.Type))
                                : null);
        }
Ejemplo n.º 5
0
        AssetMetadata GetFallbackMetadata(AssetISIN isin, UserId user)
        {
            var rawName = _stateManager.ReadState(user).Brokers
                          .SelectMany(b => b.Inventory)
                          .Where(a => a.Isin == isin)
                          .Select(a => a.RawName)
                          .FirstOrDefault();

            return(new AssetMetadata(isin, null, rawName ?? string.Empty, null));
        }
Ejemplo n.º 6
0
        DateTime GetStartDate(AssetISIN isin)
        {
            var price = _priceManager.TryGet(isin);

            if (price == null)
            {
                _logger.LogTrace($"Asset price for ISIN '{isin}' is unknown, lookup first add date");
                return(GetFirstAddDate(isin));
            }
            var lastRecordedDate = price.Candles[^ 1].Date;
Ejemplo n.º 7
0
        public decimal?GetVirtualPricePerOne(AssetISIN isin, DateTimeOffset date)
        {
            var model = TryGetModel(isin);

            if (model == null)
            {
                _logger.LogWarning($"No model for ISIN '{isin}'");
                return(null);
            }
            var lastCandleBeforeDate = model.Candles
                                       .LastOrDefault(c => c.Date < date);

            _logger.LogTrace($"Last candle value for ISIN '{isin}' before {date} is {lastCandleBeforeDate}");
            return(lastCandleBeforeDate?.Close);
        }
Ejemplo n.º 8
0
        public async Task RemoveTag(UserId user, AssetISIN asset, AssetTag tag)
        {
            var model = await _repository.Get(user);

            if (model == null)
            {
                return;
            }
            if (!model.Tags.TryGetValue(asset, out var tags))
            {
                return;
            }
            tags.Remove(tag);
            await _repository.Update(model);
        }
Ejemplo n.º 9
0
        public async Task AddTag(UserId user, AssetISIN asset, AssetTag tag)
        {
            var model = await _repository.Get(user);

            Func <UserAssetTagsModel, Task> apply =
                (model != null) ? _repository.Update : _repository.Add;

            if (model == null)
            {
                model = new UserAssetTagsModel(user, new Dictionary <string, List <string> >());
            }
            if (!model.Tags.TryGetValue(asset, out var tags))
            {
                tags = new List <string>();
                model.Tags[asset] = tags;
            }
            tags.Add(tag);
            await apply(model);
        }
Ejemplo n.º 10
0
 public async Task Handle(UserId user, AssetISIN asset, AssetTag tag)
 {
     _logger.LogTrace($"Remove tag '{tag}' from asset '{asset}' for user '{user}'");
     await _assetTagManager.RemoveTag(user, asset, tag);
 }
Ejemplo n.º 11
0
 public IEnumerable <AddAssetCommand> GetAddAssetCommands(AssetISIN isin) =>
 _stateManager.ReadCommands <AddAssetCommand>()
 .Where(c => c.Isin == isin);
Ejemplo n.º 12
0
 AssetPriceModel?TryGetModel(AssetISIN isin) =>
 _repository.GetAll()
 .FirstOrDefault(m => m.Isin == isin);
Ejemplo n.º 13
0
        public async Task <AssetId> Handle(
            DateTimeOffset date, UserId user, BrokerId brokerId, AccountId payAccountId, AccountId feeAccountId,
            AssetISIN isin, decimal price, decimal fee, string name, int count)
        {
            if (string.IsNullOrWhiteSpace(isin.Value))
            {
                throw new InvalidAssetException();
            }
            if (count <= 0)
            {
                throw new InvalidCountException();
            }
            var state  = _stateManager.ReadState(date, user);
            var broker = state.Brokers.FirstOrDefault(b => b.Id == brokerId);

            if (broker == null)
            {
                throw new InvalidBrokerException();
            }
            var payAccount = broker.Accounts.FirstOrDefault(a => a.Id == payAccountId);

            if (payAccount == null)
            {
                throw new InvalidAccountException();
            }
            var feeAccount = broker.Accounts.FirstOrDefault(a => a.Id == feeAccountId);

            if (feeAccount == null)
            {
                throw new InvalidAccountException();
            }
            var     asset = broker.Inventory.FirstOrDefault(a => a.Isin == isin);
            AssetId id;

            if (asset != null)
            {
                id = asset.Id;
                await _stateManager.AddCommand(new IncreaseAssetCommand(date, user, brokerId, asset.Id, count));
            }
            else
            {
                id = new AssetId(_idGenerator.GenerateNewId());
                var currency = payAccount.Currency;
                await _stateManager.AddCommand(new AddAssetCommand(date, user, brokerId, id, isin, currency, name, count));
            }
            switch (price)
            {
            case < 0:
                throw new InvalidPriceException();

            case 0:
                break;

            default:
                await _addExpense.Handle(
                    date, user, brokerId, payAccountId, price, ExpenseCategory.BuyAsset, id);

                break;
            }
            switch (fee)
            {
            case < 0:
                throw new InvalidPriceException();

            case 0:
                break;

            default:
                await _addExpense.Handle(
                    date, user, brokerId, feeAccountId, fee, ExpenseCategory.BuyAssetFee, id);

                break;
            }
            return(id);
        }
Ejemplo n.º 14
0
        public AssetMetadata GetMetadataWithFallback(AssetISIN isin, UserId user)
        {
            var metadata = GetMetadata(isin);

            return((metadata != null) ? metadata : GetFallbackMetadata(isin, user));
        }
Ejemplo n.º 15
0
        public IReadOnlyCollection <(DateTime, DateTime)> TryCalculateRequiredIntervals(AssetISIN isin)
        {
            var startDate = GetStartDate(isin);
            var endDate   = GetEndDate();

            _logger.LogTrace($"Interval for ISIN '{isin}' is {startDate}-{endDate}");
            var result = new List <(DateTime, DateTime)>();
            var diff   = (endDate - startDate);

            if (diff < TimeSpan.FromDays(1))
            {
                _logger.LogTrace("No processing required");
                return(result);
            }
            var date = startDate;

            while (date < endDate)
            {
                var interval = (endDate - date);
                var nextDate = (interval.TotalDays < 365) ? endDate : date.AddDays(365);
                result.Add((date, nextDate));
                date = nextDate.AddDays(1);
            }
            _logger.LogTrace(
                $"Interval splits into {result.Count} parts: {string.Join("; ", result.Select(r => r.ToString()))}");
            return(result);
        }