private LatestPriceProvider CreateProvider(IPublicPricingProvider provider) { lock (_commonLock) { var erprov = new LatestPriceProvider(new LatestPriceProviderContext(provider, this) { PollingSpan = TimeSpan.FromMilliseconds(_timerInterval) }); _providers.Add(erprov); return(erprov); } }
public LatestPriceResultMessage(MarketPrice price, Asset intermediary, MarketPrice price1, MarketPrice price2, IPublicPricingProvider provider, IPublicPricingProvider providerConvert) { UtcCreated = price1.UtcCreated > price2.UtcCreated ? price2.UtcCreated : price1.UtcCreated; Provider = provider; MarketPrice = price; MarketPrice1 = price1; MarketPrice2 = price2; AssetIntermediary = intermediary; ProviderConversion = providerConvert; }
private void GetPricing(IPublicPricingProvider provider, List <AssetPair> pairs, bool firstPriceLessThan1) { try { Trace.WriteLine("Pricing interface test\n\n"); if (provider.PricingFeatures.HasSingle) { Trace.WriteLine("\nSingle features test\n"); var context = new PublicPriceContext(pairs.First()) { RequestStatistics = provider.PricingFeatures.Single.CanStatistics, RequestVolume = provider.PricingFeatures.Single.CanVolume }; InternalGetPriceAsync(provider, context, firstPriceLessThan1, true); } if (provider.PricingFeatures.HasBulk) { Trace.WriteLine("\nBulk features test with pairs selection\n"); var context = new PublicPricesContext(pairs) { RequestStatistics = provider.PricingFeatures.Bulk.CanStatistics, RequestVolume = provider.PricingFeatures.Bulk.CanVolume }; InternalGetPriceAsync(provider, context, firstPriceLessThan1, false); if (provider.PricingFeatures.Bulk.CanReturnAll) { Trace.WriteLine("\nBulk features test (provider can return all prices)\n"); context = new PublicPricesContext(); InternalGetPriceAsync(provider, context, firstPriceLessThan1, false); } } TestVolumePricingSanity(provider, pairs); } catch (Exception e) { Assert.Fail(e.Message); } }
public LatestPriceProvider(LatestPriceProviderContext context) { _context = context; Provider = context.Provider; if (context.Provider == null) { throw new ArgumentException($"{nameof(context.Provider)} is null in {GetType()}"); } Network = Provider.Network; _messenger = context.Aggregator.M; _timer = new Timer(10) { AutoReset = false }; _timer.Elapsed += delegate { UpdateTick(); }; _timer.Start(); }
protected void GetPricingTest(IPublicPricingProvider provider, List <AssetPair> pairs, bool firstPriceLessThan1, bool?firstVolumeBaseBiggerThanQuote = null) { OutputWriter.WriteLine("Pricing interface test\n\n"); if (provider.PricingFeatures.HasSingle) { OutputWriter.WriteLine("\nSingle features test\n"); var context = new PublicPriceContext(pairs.First()) { RequestStatistics = provider.PricingFeatures.Single.CanStatistics, RequestVolume = provider.PricingFeatures.Single.CanVolume }; InternalGetPriceAsync(provider, context, true, firstPriceLessThan1, firstVolumeBaseBiggerThanQuote); } if (provider.PricingFeatures.HasBulk) { OutputWriter.WriteLine("\nBulk features test with pairs selection\n"); var context = new PublicPricesContext(pairs) { RequestStatistics = provider.PricingFeatures.Bulk.CanStatistics, RequestVolume = provider.PricingFeatures.Bulk.CanVolume }; InternalGetPriceAsync(provider, context, false, firstPriceLessThan1, firstVolumeBaseBiggerThanQuote); if (provider.PricingFeatures.Bulk.CanReturnAll) { OutputWriter.WriteLine("\nBulk features test (provider can return all prices)\n"); context = new PublicPricesContext(); InternalGetPriceAsync(provider, context, false, firstPriceLessThan1, firstVolumeBaseBiggerThanQuote); } } TestVolumePricingSanity(provider, pairs); }
internal LatestPriceProviderContext(IPublicPricingProvider provider, Aggregator aggregator) { Provider = provider; Aggregator = aggregator; }
public static Task <ApiResponse <MarketPrices> > GetPricingAsync(IPublicPricingProvider provider, PublicPricesContext context) { return(ApiHelpers.WrapExceptionAsync(() => provider.GetPricingAsync(context), nameof(GetPricing), provider, context)); }
public static ApiResponse <MarketPrices> GetPricing(IPublicPricingProvider provider, PublicPricesContext context) { return(AsyncContext.Run(() => GetPricingAsync(provider, context))); }
private void InternalGetPriceAsync(IPublicPricingProvider provider, PublicPricesContext context, bool firstPriceLessThan1, bool runSingle) { Assert.IsTrue(provider.PricingFeatures != null, "Pricing features object is null"); var r = AsyncContext.Run(() => provider.GetPricingAsync(context)); Assert.IsTrue(runSingle ? r.WasViaSingleMethod : !r.WasViaSingleMethod, runSingle ? "Single price request was completed using multiple prices endpoint" : "Multiple price request was completed using single price endpoint"); Assert.IsTrue(r.IsCompleted, "Request is not completed. Missing pairs: " + string.Join(",", r.MissedPairs)); Assert.IsTrue(r.FirstPrice != null, "First price is null"); if (context.IsRequestAll) { Assert.IsTrue(!context.Pairs.Any(), "Context should not have any pairs when requesting prices for all supported by exchange pairs"); } else { Assert.IsTrue(r.FirstPrice.QuoteAsset.Equals(context.Pair.Asset1), "Incorrect base asset"); Assert.IsTrue(r.FirstPrice.Price.Asset.Equals(context.Pair.Asset2), "Incorrect quote asset"); Assert.IsTrue(r.MarketPrices.DistinctBy(x => x.Pair).Count() == context.Pairs.Count, "Pair duplicates found"); } if (context.IsRequestAll == false) { if (firstPriceLessThan1) // Checks if the pair is reversed (price-wise). { Assert.IsTrue(r.FirstPrice.Price < 1, "Reverse check failed. Price is expected to be < 1"); } else { Assert.IsTrue(r.FirstPrice.Price > 1, "Reverse check failed. Price is expected to be > 1"); } } Trace.WriteLine($"First asset: {r.FirstPrice}"); var pricingFeatures = runSingle ? provider.PricingFeatures.Single : provider.PricingFeatures.Bulk as PricingFeaturesItemBase; foreach (var p in r.MarketPrices) { Trace.WriteLine($"Market price: {p}"); if (pricingFeatures.CanStatistics) { Assert.IsTrue(p.HasStatistics, $"Market price does not have statistics but provider supports it - {p.Pair}"); Trace.WriteLine($"Market price statistics for {p.Pair}:"); Trace.WriteLine( $"Bid: {(p.PriceStatistics.HasHighestBid ? p.PriceStatistics.HighestBid.Display : "-")}"); Trace.WriteLine( $"Ask: {(p.PriceStatistics.HasLowestAsk ? p.PriceStatistics.LowestAsk.Display : "-")}"); Trace.WriteLine( $"Low: {(p.PriceStatistics.HasPrice24Low ? p.PriceStatistics.Price24Low.Display : "-")}"); Trace.WriteLine( $"High: {(p.PriceStatistics.HasPrice24High ? p.PriceStatistics.Price24High.Display : "-")}"); } else { Assert.IsTrue(!p.HasStatistics, $"Provider returns statistics but did not announce it - {p.Pair}"); } if (pricingFeatures.CanVolume) { Assert.IsTrue(p.HasVolume, $"Market price does not have volume but provider supports it - {p.Pair}"); if (p.Volume.HasVolume24Base) { Trace.WriteLine($"Base 24h volume: {p.Volume.Volume24Base}"); } if (p.Volume.HasVolume24Quote) { Trace.WriteLine($"Quote 24h volume: {p.Volume.Volume24Quote}"); } } else { Assert.IsTrue(!p.HasVolume, $"Provider returns volume but did not announce it - {p.Pair}"); } Trace.WriteLine(""); } }
private void InternalGetPriceAsync(IPublicPricingProvider provider, PublicPricesContext context, bool runSingle, bool firstPriceLessThan1, bool?firstVolumeBaseBiggerThanQuote = null) { Assert.True(provider.PricingFeatures != null, "Pricing features object is null"); var r = AsyncContext.Run(() => provider.GetPricingAsync(context)); // General. Assert.True(runSingle ? r.WasViaSingleMethod : !r.WasViaSingleMethod, runSingle ? "Single price request was completed using multiple prices endpoint" : "Multiple price request was completed using single price endpoint"); Assert.True(r.IsCompleted, "Request is not completed. Missing pairs: " + string.Join(", ", r.MissedPairs)); var dist = r.DistinctBy(x => x.Pair).ToList(); // Multiple prices. if (context.IsRequestAll) { Assert.True(!context.Pairs.Any(), "Context should not have any pairs when requesting prices for all supported by exchange pairs"); } else { Assert.True(r.DistinctBy(x => x.Pair).Count() == context.Pairs.Count, "Number of returned pairs is not equal to requested"); } // First price, price value. Assert.True(r.FirstPrice != null, "First price is null"); OutputWriter.WriteLine($"First asset price: {r.FirstPrice}"); if (!context.IsRequestAll) { var firstPrice = r.FirstPrice; Assert.True(firstPrice.QuoteAsset.Equals(context.Pair.Asset1), "Incorrect base asset"); Assert.True(firstPrice.Price.Asset.Equals(context.Pair.Asset2), "Incorrect quote asset"); // Checks if the pair is reversed (price-wise). if (firstPriceLessThan1) { Assert.True(firstPrice.Price < 1, "Reverse check failed. Price is expected to be < 1"); } else { Assert.True(firstPrice.Price > 1, "Reverse check failed. Price is expected to be > 1"); } // Checks if statistics price are correct. if (firstPrice.HasStatistics) { if (firstPrice.PriceStatistics.HasHighestBid) { if (firstPriceLessThan1) { Assert.True(firstPrice.PriceStatistics.HighestBid < 1, "Reverse check failed. Highest bid price is expected to be < 1"); } else { Assert.True(firstPrice.PriceStatistics.HighestBid > 1, "Reverse check failed. Highest bid price is expected to be > 1"); } } if (firstPrice.PriceStatistics.HasLowestAsk) { if (firstPriceLessThan1) { Assert.True(firstPrice.PriceStatistics.LowestAsk < 1, "Reverse check failed. Lowest ask price is expected to be < 1"); } else { Assert.True(firstPrice.PriceStatistics.LowestAsk > 1, "Reverse check failed. Lowest ask price is expected to be > 1"); } } if (firstPrice.PriceStatistics.HasPrice24High) { if (firstPriceLessThan1) { Assert.True(firstPrice.PriceStatistics.Price24High < 1, "Reverse check failed. Highest 24h price is expected to be < 1"); } else { Assert.True(firstPrice.PriceStatistics.Price24High > 1, "Reverse check failed. Highest 24h price is expected to be > 1"); } } if (firstPrice.PriceStatistics.HasPrice24Low) { if (firstPriceLessThan1) { Assert.True(firstPrice.PriceStatistics.Price24Low < 1, "Reverse check failed. Lowest 24h price is expected to be < 1"); } else { Assert.True(firstPrice.PriceStatistics.Price24Low > 1, "Reverse check failed. Lowest 24h price is expected to be > 1"); } } // Check if 24 highest >= 24 lowest. if (firstPrice.PriceStatistics.HasPrice24Low && firstPrice.PriceStatistics.HasPrice24High) { Assert.True(firstPrice.PriceStatistics.Price24High >= firstPrice.PriceStatistics.Price24Low, "24h highest price is smaller that 24h lowest price"); } } // First price. Volume base/quote relation. var canAllVolume = r.FirstPrice.HasVolume && r.FirstPrice.Volume.HasVolume24Base && r.FirstPrice.Volume.HasVolume24Quote; if (provider.PricingFeatures.HasSingle && provider.PricingFeatures.Single.CanVolume && canAllVolume) { TestVolumesRelationWithinPricing(r.FirstPrice, firstVolumeBaseBiggerThanQuote); } if (provider.PricingFeatures.HasBulk && provider.PricingFeatures.Bulk.CanVolume && canAllVolume) { TestVolumesRelationWithinPricing(r.FirstPrice, firstVolumeBaseBiggerThanQuote); } } // All market prices and pricing features. var pricingFeatures = runSingle ? provider.PricingFeatures.Single : provider.PricingFeatures.Bulk as PricingFeaturesItemBase; foreach (var p in r) { OutputWriter.WriteLine($"Market price: {p}"); // Statistics. if (pricingFeatures.CanStatistics) { Assert.True(p.HasStatistics, $"Market price does not have statistics but provider supports it - {p.Pair}"); OutputWriter.WriteLine($"Market price statistics for {p.Pair}:"); OutputWriter.WriteLine( $"Bid: {(p.PriceStatistics.HasHighestBid ? p.PriceStatistics.HighestBid.Display : "-")}"); OutputWriter.WriteLine( $"Ask: {(p.PriceStatistics.HasLowestAsk ? p.PriceStatistics.LowestAsk.Display : "-")}"); OutputWriter.WriteLine( $"Low: {(p.PriceStatistics.HasPrice24Low ? p.PriceStatistics.Price24Low.Display : "-")}"); OutputWriter.WriteLine( $"High: {(p.PriceStatistics.HasPrice24High ? p.PriceStatistics.Price24High.Display : "-")}"); } else { Assert.True(!p.HasStatistics, $"Provider returns statistics but did not announce it - {p.Pair}"); } // Volume. if (pricingFeatures.CanVolume) { Assert.True(p.HasVolume, $"Market price does not have volume but provider supports it - {p.Pair}"); if (p.Volume.HasVolume24Base) { OutputWriter.WriteLine($"Base 24h volume: {p.Volume.Volume24Base}"); } if (p.Volume.HasVolume24Quote) { OutputWriter.WriteLine($"Quote 24h volume: {p.Volume.Volume24Quote}"); } } else { Assert.True(!p.HasVolume, $"Provider returns volume but did not announce it - {p.Pair}"); } OutputWriter.WriteLine(""); } }
public LatestPriceResultMessage(IPublicPricingProvider provider, MarketPrice marketPrice) { UtcCreated = marketPrice.UtcCreated; Provider = provider; MarketPrice = marketPrice; }