예제 #1
0
        /// <inheritdoc />
        public async Task <IReadOnlyCollection <MarketSummaryDto> > GetAsync(ICoinBuilder builder)
        {
            try
            {
                IReadOnlyList <BittrexCurrencyDto> currencies = await this.GetCurrenciesAsync();

                if (!currencies.Any())
                {
                    return(Array.Empty <MarketSummaryDto>());
                }

                foreach (BittrexCurrencyDto currency in currencies.Where(predicate: c => c.IsActive && !c.IsRestricted))
                {
                    builder.Get(symbol: currency.Symbol, name: currency.Name);
                }

                IReadOnlyList <BittrexMarketSummaryDto> summaries = await this.GetMarketSummariesAsync();

                return(summaries.Select(selector: summary => this.CreateMarketSummaryDto(marketSummary: summary, builder: builder))
                       .RemoveNulls()
                       .ToList());
            }
            catch (Exception e)
            {
                this.Logger.LogError(new EventId(e.HResult), exception: e, message: e.Message);

                throw;
            }
        }
예제 #2
0
        private async Task UpdateCoinsAsync(ICoinBuilder builder)
        {
            this.Logger.LogInformation(message: "Updating All CoinInfos");

            IReadOnlyCollection <ICoinInfo>[] allCoinInfos = await Task.WhenAll(this._coinClients.Select(this.GetCoinInfoAsync));

            var cryptoInfos = allCoinInfos.SelectMany(selector: ci => ci)
                              .GroupBy(keySelector: c => c.Symbol)
                              .Select(selector: c => new { Symbol = c.Key, Coins = c.ToArray() });

            foreach (var cryptoInfo in cryptoInfos)
            {
                ICoinInfo name = cryptoInfo.Coins[0];

                Currency?currency = builder.Get(symbol: cryptoInfo.Symbol, name: name.Name);

                if (currency != null)
                {
                    foreach (ICoinInfo info in cryptoInfo.Coins)
                    {
                        currency.AddDetails(info);
                    }
                }
            }
        }
예제 #3
0
 public ApiViewModel(ICoinBuilder coinBuilder,
                     IExchangeApiBuilder exchangeApiBuilder,
                     IExchangeHubBuilder exchangeHubBuilder)
 {
     _coinBuilder        = coinBuilder;
     _exchangeApiBuilder = exchangeApiBuilder;
     _exchangeHubBuilder = exchangeHubBuilder;
 }
예제 #4
0
        /// <inheritdoc />
        public async Task <IReadOnlyCollection <MarketSummaryDto> > GetAsync(ICoinBuilder builder)
        {
            IReadOnlyCollection <FunFairWalletPriceResultPairDto?> products = await this.GetBasePricesAsync();

            return(products.RemoveNulls()
                   .Select(selector: product => this.CreateMarketSummaryDto(pkt: product, builder: builder))
                   .RemoveNulls()
                   .ToList());
        }
예제 #5
0
 public ExchangeViewModel(IAlertBuilder alertBuilder,
                          ICoinBuilder coinBuilder,
                          IExchangeApiBuilder exchangeApiBuilder,
                          IExchangeHubBuilder exchangeHubBuilder,
                          IExchangeOrderBuilder exchangeOrderBldr,
                          IWatchBuilder watchBuilder)
 {
     _alertBuilder         = alertBuilder;
     _coinBuilder          = coinBuilder;
     _exchangeApiBuilder   = exchangeApiBuilder;
     _exchangeHubBuilder   = exchangeHubBuilder;
     _exchangeOrderBuilder = exchangeOrderBldr;
     _watchBuilder         = watchBuilder;
 }
예제 #6
0
        private async Task UpdateOneClientAsync(IMarketClient client, ICoinBuilder builder)
        {
            if (this._exchanges.TryGetValue(key: client.Name, out Exchange? exchange))
            {
                this.Logger.LogInformation($"Start updating exchange '{client.Name}'.");
                Stopwatch watch = new Stopwatch();
                watch.Start();

                IReadOnlyCollection <MarketSummaryDto> markets;

                try
                {
                    markets = await client.GetAsync(builder);
                }
                catch (Exception e)
                {
                    this.Logger.LogError(eventId: 0, exception: e, $"An error occurred while fetching results from the exchange '{client.Name}'.");
                    exchange.Lock.EnterWriteLock();

                    try
                    {
                        // Remove out-of-date market summaries
                        exchange.Markets = Array.Empty <MarketSummaryDto>();
                    }
                    finally
                    {
                        exchange.Lock.ExitWriteLock();
                    }

                    return;
                }

                // Update market summaries
                exchange.Lock.EnterWriteLock();

                try
                {
                    exchange.Markets = markets;
                    watch.Stop();
                    this.Logger.LogInformation($"Finished updating exchange '{client.Name}' in {watch.ElapsedMilliseconds}ms.");
                }
                finally
                {
                    exchange.Lock.ExitWriteLock();
                }
            }
예제 #7
0
        /// <inheritdoc />
        public async Task <IReadOnlyCollection <MarketSummaryDto> > GetAsync(ICoinBuilder builder)
        {
            try
            {
                IReadOnlyList <PoloniexTicker> tickers = await this.GetTickersAsync();

                return(tickers.Select(selector: ticker => this.CreateMarketSummaryDto(ticker: ticker, builder: builder))
                       .RemoveNulls()
                       .ToList());
            }
            catch (Exception e)
            {
                this.Logger.LogError(new EventId(e.HResult), exception: e, message: e.Message);

                throw;
            }
        }
예제 #8
0
        /// <inheritdoc />
        public async Task <IReadOnlyCollection <MarketSummaryDto> > GetAsync(ICoinBuilder builder)
        {
            try
            {
                IReadOnlyList <BinanceProduct> products = await this.GetProductsAsync();

                return(products.Select(selector: product => this.CreateMarketSummaryDto(product: product, builder: builder))
                       .RemoveNulls()
                       .ToList());
            }
            catch (Exception exception)
            {
                EventId eventId = new EventId(exception.HResult);
                this.Logger.LogError(eventId: eventId, exception: exception, message: exception.Message);

                throw;
            }
        }
예제 #9
0
        /// <inheritdoc />
        public async Task <IReadOnlyCollection <MarketSummaryDto> > GetAsync(ICoinBuilder builder)
        {
            try
            {
                IReadOnlyList <GdaxProduct> products = await this.GetProductsAsync();

                IReadOnlyList <GdaxTicker?> tickers = await Batched.WhenAllAsync(concurrent : 2, products.Select(selector: product => this.GetTickerAsync(product.Id)));

                return(tickers.RemoveNulls()
                       .Select(selector: ticker => this.CreateMarketSummaryDto(ticker: ticker, builder: builder))
                       .RemoveNulls()
                       .ToList());
            }
            catch (Exception e)
            {
                this.Logger.LogError(new EventId(e.HResult), exception: e, message: e.Message);

                throw;
            }
        }
예제 #10
0
        private MarketSummaryDto?CreateMarketSummaryDto(PoloniexTicker ticker, ICoinBuilder builder)
        {
            Currency?baseCurrency = builder.Get(ticker.Pair.Substring(startIndex: 0, ticker.Pair.IndexOf(value: '_')));

            if (baseCurrency == null)
            {
                return(null);
            }

            Currency?marketCurrency = builder.Get(ticker.Pair.Substring(ticker.Pair.IndexOf(value: '_') + 1));

            if (marketCurrency == null)
            {
                return(null);
            }

            return(new MarketSummaryDto(market: this.Name,
                                        baseCurrency: baseCurrency,
                                        marketCurrency: marketCurrency,
                                        volume: ticker.BaseVolume,
                                        last: ticker.Last,
                                        lastUpdated: null));
        }
예제 #11
0
        private MarketSummaryDto?CreateMarketSummaryDto(BinanceProduct product, ICoinBuilder builder)
        {
            // always look at the quoted currency first as if that does not exist, then no point creating doing any more
            Currency?marketCurrency = builder.Get(product.QuoteAsset);

            if (marketCurrency == null)
            {
                return(null);
            }

            Currency?baseCurrency = builder.Get(symbol: product.BaseAsset, name: product.BaseAssetName);

            if (baseCurrency == null)
            {
                return(null);
            }

            return(new MarketSummaryDto(market: this.Name,
                                        baseCurrency: baseCurrency,
                                        marketCurrency: marketCurrency,
                                        volume: product.Volume,
                                        last: product.PrevClose,
                                        lastUpdated: null));
        }
예제 #12
0
        private MarketSummaryDto?CreateMarketSummaryDto(GdaxTicker ticker, ICoinBuilder builder)
        {
            // always look at the quoted currency first as if that does not exist, then no point creating doing any more
            Currency?marketCurrency = builder.Get(ticker.ProductId.Substring(ticker.ProductId.IndexOf(value: '-') + 1));

            if (marketCurrency == null)
            {
                return(null);
            }

            Currency?baseCurrency = builder.Get(ticker.ProductId.Substring(startIndex: 0, ticker.ProductId.IndexOf(value: '-')));

            if (baseCurrency == null)
            {
                return(null);
            }

            return(new MarketSummaryDto(market: this.Name,
                                        baseCurrency: baseCurrency,
                                        marketCurrency: marketCurrency,
                                        volume: ticker.Volume,
                                        last: ticker.Price,
                                        lastUpdated: ticker.Time));
        }
예제 #13
0
        private MarketSummaryDto?CreateMarketSummaryDto(GateIoTicker marketSummary, ICoinBuilder builder)
        {
            // always look at the quoted currency first as if that does not exist, then no point creating doing any more
            Currency?marketCurrency = builder.Get(marketSummary.Pair.Substring(marketSummary.Pair.IndexOf(PAIR_SEPARATOR) + 1));

            if (marketCurrency == null)
            {
                return(null);
            }

            Currency?baseCurrency = builder.Get(marketSummary.Pair.Substring(startIndex: 0, marketSummary.Pair.IndexOf(PAIR_SEPARATOR)));

            if (baseCurrency == null)
            {
                return(null);
            }

            return(new MarketSummaryDto(market: this.Name,
                                        baseCurrency: baseCurrency,
                                        marketCurrency: marketCurrency,
                                        volume: marketSummary.BaseVolume,
                                        last: marketSummary.Last,
                                        lastUpdated: null));
        }
예제 #14
0
        private MarketSummaryDto?CreateMarketSummaryDto(BittrexMarketSummaryDto marketSummary, ICoinBuilder builder)
        {
            // always look at the quoted currency first as if that does not exist, then no point creating doing any more
            Currency?marketCurrency = builder.Get(marketSummary.MarketName.Substring(marketSummary.MarketName.IndexOf(value: '-') + 1));

            if (marketCurrency == null)
            {
                return(null);
            }

            Currency?baseCurrency = builder.Get(marketSummary.MarketName.Substring(startIndex: 0, marketSummary.MarketName.IndexOf(value: '-')));

            if (baseCurrency == null)
            {
                return(null);
            }

            return(new MarketSummaryDto(market: this.Name,
                                        baseCurrency: baseCurrency,
                                        marketCurrency: marketCurrency,
                                        volume: marketSummary.BaseVolume,
                                        last: marketSummary.Last,
                                        lastUpdated: marketSummary.TimeStamp));
        }
예제 #15
0
        private MarketSummaryDto?CreateMarketSummaryDto(FunFairWalletPriceResultPairDto pkt, ICoinBuilder builder)
        {
            // always look at the quoted currency first as if that does not exist, then no point creating doing any more
            Currency?marketCurrency = builder.Get(pkt.FiatCurrencySymbol);

            if (marketCurrency == null)
            {
                return(null);
            }

            Currency?baseCurrency = builder.Get(pkt.TokenSymbol);

            if (baseCurrency == null)
            {
                return(null);
            }

            return(new MarketSummaryDto(market: this.Name, baseCurrency: baseCurrency, marketCurrency: marketCurrency, volume: 0m, last: pkt.Price, lastUpdated: pkt.LastUpdated));
        }
예제 #16
0
        /// <inheritdoc />
        public async Task <IReadOnlyCollection <MarketSummaryDto> > GetAsync(ICoinBuilder builder)
        {
            try
            {
                IReadOnlyList <KrakenAsset> assets = await this.GetAssetsAsync();

                bool IsValid(KrakenPair pair)
                {
                    // todo: can't get kraken details on these markets
                    if (pair.PairId.EndsWith(value: ".d", comparisonType: StringComparison.Ordinal))
                    {
                        return(false);
                    }

                    string?bc = FindCurrency(assets: assets, search: pair.BaseCurrency);

                    if (bc == null)
                    {
                        return(false);
                    }

                    string?qc = FindCurrency(assets: assets, search: pair.QuoteCurrency);

                    if (qc == null)
                    {
                        return(false);
                    }

                    Currency?baseCurrency = builder.Get(bc);

                    if (baseCurrency == null)
                    {
                        return(false);
                    }

                    Currency?quoteCurrency = builder.Get(qc);

                    if (quoteCurrency == null)
                    {
                        return(false);
                    }

                    return(true);
                }

                IReadOnlyList <KrakenPair> pairs = await this.GetPairsAsync();

                IReadOnlyList <KrakenTicker?> tickers = await Batched.WhenAllAsync(concurrent : 5,
                                                                                   pairs.Where(IsValid)
                                                                                   .Select(this.GetTickerAsync));

                return(tickers.RemoveNulls()
                       .Select(selector: m => this.CreateMarketSummaryDto(assets: assets, ticker: m, builder: builder))
                       .RemoveNulls()
                       .ToList());
            }
            catch (Exception e)
            {
                this.Logger.LogError(new EventId(e.HResult), exception: e, message: e.Message);

                throw;
            }
        }
예제 #17
0
        private MarketSummaryDto?CreateMarketSummaryDto(IReadOnlyList <KrakenAsset> assets, KrakenTicker ticker, ICoinBuilder builder)
        {
            if (ticker.Last == null || ticker.Volume == null)
            {
                return(null);
            }

            string?baseCurrencySymbol = FindCurrency(assets: assets, search: ticker.BaseCurrency);

            if (baseCurrencySymbol == null)
            {
                return(null);
            }

            string?marketCurrencySymbol = FindCurrency(assets: assets, search: ticker.QuoteCurrency);

            if (marketCurrencySymbol == null)
            {
                return(null);
            }

            // always look at the quoted currency first as if that does not exist, then no point creating doing any more
            Currency?marketCurrency = builder.Get(marketCurrencySymbol);

            if (marketCurrency == null)
            {
                return(null);
            }

            Currency?baseCurrency = builder.Get(baseCurrencySymbol);

            if (baseCurrency == null)
            {
                return(null);
            }

            return(new MarketSummaryDto(market: this.Name,
                                        baseCurrency: baseCurrency,
                                        marketCurrency: marketCurrency,
                                        volume: ticker.Volume[1],
                                        last: ticker.Last[0],
                                        lastUpdated: null));
        }