private async Task PublishOrderBookAndTickPrice(OrderBook orderBook) { if (IsStale(orderBook)) { _log.Info("Stale instrument.", new { orderBook.Asset }); return; } InternalMetrics.OrderBookOutCount .WithLabels(orderBook.Asset) .Inc(); InternalMetrics.OrderBookOutDelayMilliseconds .WithLabels(orderBook.Asset) .Set((DateTime.UtcNow - orderBook.Timestamp).TotalMilliseconds); await _orderBookPublisher.PublishAsync(orderBook); var tickPrice = TickPrice.FromOrderBook(orderBook); InternalMetrics.QuoteOutCount .WithLabels(tickPrice.Asset) .Inc(); InternalMetrics.QuoteOutSidePrice .WithLabels(tickPrice.Asset, "ask") .Set((double)tickPrice.Ask); InternalMetrics.QuoteOutSidePrice .WithLabels(tickPrice.Asset, "bid") .Set((double)tickPrice.Bid); await _tickPricePublisher.PublishAsync(tickPrice); }
private void AddOrUpdateTickPrice(string asset, TickPrice tickPrice) { // new list if (!_assetsTickPricesCache.ContainsKey(asset)) { var newList = new List <TickPrice> { tickPrice }; _assetsTickPricesCache[asset] = newList; } // existed list else { var exchangesPrices = _assetsTickPricesCache[asset]; // Replace by source and assetPair Predicate <TickPrice> existedTickPrices = x => x.AssetPair == tickPrice.AssetPair && x.Source == tickPrice.Source; exchangesPrices.RemoveAll(existedTickPrices); exchangesPrices.Add(tickPrice); } }
public async Task PublishAsync(TickPrice message) { if (_publisher == null || !_settting.Enabled) { return; } try { await _publisher.ProduceAsync(message); } catch (Exception e) { var logMessage = $"TickPricePublisher.PublishAsync() exception: ${e}."; if (e.Message.Contains("isn't started yet")) { _log.Info(logMessage); } else { _log.Warning(logMessage); } } }
private async Task HandleOrderBook(OrderBook orderBook) { var instrument = Instruments.SingleOrDefault(x => string.Compare(x.Name, orderBook.AssetPair, StringComparison.InvariantCultureIgnoreCase) == 0); if (instrument != null) { if (orderBook.Prices.Any()) { decimal bestBid = 0; decimal bestAsk = 0; if (orderBook.IsBuy) { _lastBids[instrument.Name] = bestBid = orderBook.Prices.Select(x => x.Price).OrderByDescending(x => x).First(); bestAsk = _lastAsks[instrument.Name]; } else { _lastAsks[instrument.Name] = bestAsk = orderBook.Prices.Select(x => x.Price).OrderBy(x => x).First(); bestBid = _lastBids[instrument.Name]; } if (bestBid > 0 && bestAsk > 0) { var tickPrice = new TickPrice(instrument, orderBook.Timestamp, bestAsk, bestBid); await _tickPriceHandler.Handle(tickPrice); } } } }
private Task ProcessMessageAsync(TickPrice tickPrice) { _quoteService.Set(new Quote(tickPrice.Asset, tickPrice.Timestamp, tickPrice.Ask, tickPrice.Bid, tickPrice.Source)); return(Task.CompletedTask); }
public void usd_orderbook() { var now = DateTime.UtcNow; var ob = new OrderBook("bitstamp", "BTCUSD", now, new[] { new OrderBookItem(6244.96M, 1.5M), }, new[] { new OrderBookItem(6239.85M, 0.8M) }); var tp = new TickPrice { Source = "lykke", Asset = "EURUSD", Timestamp = now, Ask = 0.9M, Bid = 0.8M }; var synOb = OrderbookGeneratorService.CreateSyntheticOrderBook( tp, ob, "BTCEUR", "synthetic-bitstamp-BTCUSD", 5); Console.WriteLine(JsonConvert.SerializeObject(synOb)); }
private Task ProcessMessageAsync(TickPrice tickPrice) { // workaround for Lykke production var internalAssetPair = tickPrice.Asset.Replace("EOS", "EOScoin"); return(_quoteService.SetAsync(new Quote(internalAssetPair, tickPrice.Timestamp, tickPrice.Ask, tickPrice.Bid, tickPrice.Source))); }
public virtual void tickPrice(int tickerId, int field, double price, TickAttrib attribs) { Console.WriteLine("Tick Price. Ticker Id:" + tickerId + ", Field: " + field + ", Price: " + price + ", CanAutoExecute: " + attribs.CanAutoExecute + ", PastLimit: " + attribs.PastLimit + ", PreOpen: " + attribs.PreOpen); TickPrice tickPrice = new TickPrice(tickerId, field, price, attribs); RaiseTickPriceUpdatedEvent(new TickPriceArgs(tickPrice)); }
private async Task HandleResponse(TickerResponse ticker) { var pair = _channels[ticker.ChannelId].Pair; var tickPrice = new TickPrice(new Instrument(ExchangeName, pair), DateTime.UtcNow, ticker.Ask, ticker.Bid); await CallTickPricesHandlers(tickPrice); }
private Task ProcessMessageAsync(TickPrice tickPrice) { if (!_assetPairs.Contains(tickPrice.Asset, StringComparer.OrdinalIgnoreCase)) { return(Task.CompletedTask); } return(_candlesRepository.AddAsync(new Candle(tickPrice))); }
private Task ProcessMessageAsync(TickPrice tickPrice) { // TODO: Remove this workaround string assetPair = _assetPairMapping .FirstOrDefault(o => o.Key.Equals(tickPrice.Asset, StringComparison.InvariantCultureIgnoreCase)).Value; return(_quoteService.UpdateAsync(new Quote(assetPair ?? tickPrice.Asset, tickPrice.Timestamp, tickPrice.Ask, tickPrice.Bid, tickPrice.Source))); }
private async Task PublishOrderBookAsync(OrderBook orderBook) { if (!orderBook.IsEmpty) { await _orderBookPublisher.PublishAsync(_exchangeName, orderBook); await _tickPricePublisher.PublishAsync(TickPrice.FromOrderBook(_exchangeName, orderBook)); } }
private static TickPrice Reverse(TickPrice tickPrice, string reverseAsset) { return(new TickPrice { Ask = tickPrice.Bid == 0 ? 0 : 1 / tickPrice.Bid, Bid = tickPrice.Ask == 0 ? 0 : 1 / tickPrice.Ask, Asset = reverseAsset, Timestamp = tickPrice.Timestamp, Source = tickPrice.Source }); }
public Task <TickPriceModel> GetTickPriceAsync(string exchange, string assetPair) { TickPrice ob = _tickPriceStore.GetTickPrice(exchange, assetPair); if (ob == null) { throw new ValidationApiException(HttpStatusCode.NotFound, "Tick price does not exist."); } return(Task.FromResult(Mapper.Map <TickPriceModel>(ob))); }
private Task ProcessMessageAsync(TickPrice tickPrice) { AssetPairModel assetPairSettings = _marketInstrumentService.GetAssetPairs() .FirstOrDefault(o => o.Exchange == tickPrice.Source && o.Id == tickPrice.Asset); if (assetPairSettings != null) { _quoteService.Update(new Quote(assetPairSettings.Name, tickPrice.Timestamp, tickPrice.Ask, tickPrice.Bid, tickPrice.Source)); } return(Task.CompletedTask); }
public void tickprice_from_empty_orderbook() { var ts = DateTime.UtcNow; var ob = new OrderBook("source", "asset", ts, new OrderBookItem [] {}, new OrderBookItem[] {}); var tp = TickPrice.FromOrderBook(ob); Assert.AreEqual(ts, tp.Timestamp); Assert.AreEqual("source", tp.Source); Assert.AreEqual("asset", tp.Asset); Assert.AreEqual(0M, tp.Ask); Assert.AreEqual(0M, tp.Bid); }
// TODO: wamp sends strange tickprices with ask=bid, temporary switch to direct rabbitmq connection // private void StartWampConnection() // { // var wampSettings = new WampSubscriberSettings() // { // Address = Config.WampEndpoint.Url, // Realm = Config.WampEndpoint.PricesRealm, // Topics = Instruments.SelectMany(i => new string[] { // String.Format(Config.WampEndpoint.PricesTopic, i.Name.ToLowerInvariant(), "ask", "sec"), // String.Format(Config.WampEndpoint.PricesTopic, i.Name.ToLowerInvariant(), "bid", "sec") }).ToArray() // }; // // this.wampSubscriber = new WampSubscriber<Candle>(wampSettings, this.LykkeLog) // .Subscribe(HandlePrice); // // this.wampSubscriber.Start(); // } /// <summary> /// Called on incoming prices /// </summary> /// <param name="candle">Incoming candlestick</param> /// <remarks>Can be called simultaneously from multiple threads</remarks> private async Task HandlePrice(Candle candle) { var instrument = Instruments.FirstOrDefault(i => string.Equals(i.Name, candle.Asset, StringComparison.InvariantCultureIgnoreCase)); if (instrument != null) { var tickPrice = new TickPrice( instrument, candle.Timestamp, ask: candle.L, bid: candle.H); await _tickPriceHandler.Handle(tickPrice); } }
private static TickPrice GetCrossTickPrice( string syntheticSourceName, string asset, int decimals, TickPrice source, TickPrice target) { return(new TickPrice { Source = syntheticSourceName, Asset = asset, Timestamp = source.Timestamp > target.Timestamp ? source.Timestamp : target.Timestamp, Ask = source.Bid == 0M? 0: Math.Round(target.Ask / source.Bid, decimals), Bid = source.Ask == 0M? 0: Math.Round(target.Bid / source.Ask, decimals) }); }
public Task PublishAsync(Domain.TickPrice tickPrice) { if (tickPrice.Ask == 0 || tickPrice.Bid == 0) { return(Task.CompletedTask); } var message = new TickPrice { Source = tickPrice.Source, Asset = tickPrice.AssetPair, Timestamp = tickPrice.Timestamp, Ask = tickPrice.Ask, Bid = tickPrice.Bid }; return(_publisher.ProduceAsync(message)); }
public bool IsTheSameAsLatestTickPrice(TickPrice currnetTickPrice) { if (!_latestTickPricePerInstrument.ContainsKey(currnetTickPrice.Asset)) { _latestTickPricePerInstrument.Add(currnetTickPrice.Asset, currnetTickPrice); return(false); } var latestTickPriceForInstrument = _latestTickPricePerInstrument[currnetTickPrice.Asset]; if (latestTickPriceForInstrument.Ask == currnetTickPrice.Ask && latestTickPriceForInstrument.Bid == currnetTickPrice.Bid) { _latestTickPricePerInstrument[currnetTickPrice.Asset].Timestamp = currnetTickPrice.Timestamp; //update the timestamp only, just to keep track of when tick was recived, but dont consider it when comparing ticks as we only care for ask and bid values. return(true); } _latestTickPricePerInstrument[currnetTickPrice.Asset] = currnetTickPrice; return(false); }
public Task Handle(TickPrice tickPrice) { lock (_gate) { if (!_lastTickPrices.ContainsKey(tickPrice.Source)) { _lastTickPrices[tickPrice.Source] = new Dictionary <string, TickPrice> { [tickPrice.Asset] = tickPrice }; } else { _lastTickPrices[tickPrice.Source][tickPrice.Asset] = tickPrice; } return(Task.CompletedTask); } }
public void order_book() { var ob = new OrderBook("source", "asset", DateTime.UtcNow, new[] { new OrderBookItem(100, 5), new OrderBookItem(101, 5), }, new[] { new OrderBookItem(99, 5), new OrderBookItem(97, 5), }); Assert.AreEqual(100M, ob.BestAskPrice); Assert.AreEqual(99M, ob.BestBidPrice); var tp = TickPrice.FromOrderBook(ob); Assert.AreEqual(100M, tp.Ask); Assert.AreEqual(99M, tp.Bid); }
public static OrderBook CreateSyntheticOrderBook( TickPrice tickPrice, OrderBook orderBook, string resultPair, string source, int decimals) { return(new OrderBook( source, resultPair, tickPrice.Timestamp > orderBook.Timestamp ? tickPrice.Timestamp : orderBook.Timestamp, orderBook.Asks.Select(x => new OrderBookItem { Price = Math.Round(x.Price * tickPrice.Ask, decimals), Volume = x.Volume }), orderBook.Bids.Select(x => new OrderBookItem { Price = Math.Round(x.Price * tickPrice.Bid, decimals), Volume = x.Volume }))); }
private async Task HandleOrderBook(OrderBook orderBook) { var instrument = Instruments.FirstOrDefault(x => string.Compare(x.Name, orderBook.AssetPair, StringComparison.InvariantCultureIgnoreCase) == 0); if (instrument == null && Config.UseSupportedCurrencySymbolsAsFilter == false) { instrument = new Instrument(Name, orderBook.AssetPair); } if (instrument != null) { if (orderBook.Prices.Any()) { decimal bestBid = 0; decimal bestAsk = 0; if (orderBook.IsBuy) { _lastBids[instrument.Name] = bestBid = orderBook.Prices.Select(x => x.Price).OrderByDescending(x => x).First(); bestAsk = _lastAsks.ContainsKey(instrument.Name) ? _lastAsks[instrument.Name] : 0; } else { _lastAsks[instrument.Name] = bestAsk = orderBook.Prices.Select(x => x.Price).OrderBy(x => x).First(); bestBid = _lastBids.ContainsKey(instrument.Name) ? _lastBids[instrument.Name] : 0; } if (bestBid > 0 && bestAsk > 0) { var tickPrice = new TickPrice(instrument, orderBook.Timestamp, bestAsk, bestBid); await _tickPriceHandler.Handle(tickPrice); await _orderBookHandler.Handle(orderBook); } } } }
void EWrapper.tickPrice(int tickerId, int field, double price, int canAutoExecute) { TickPrice?.Invoke(tickerId, field, price, canAutoExecute); }
private Task ProcessMessageAsync(TickPrice tickPrice) { return(_quoteService.SetAsync(new Quote(tickPrice.Asset, tickPrice.Timestamp, tickPrice.Ask, tickPrice.Bid, tickPrice.Source))); }
void IEWrapper.TickPrice(int tickerId, int field, double price, TickAttrib attribs) { TickPrice?.Invoke(new TickPriceMessage(tickerId, field, price, attribs)); }
public TickPriceArgs(TickPrice tickPrice) { TickPrice = tickPrice; }
private Task CallTickPricesHandlers(TickPrice tickPrice) { return(_tickPriceHandler.Handle(tickPrice)); }
/// <summary> /// TickPrice event invocator /// </summary> protected virtual void OnTickPrice(TickPriceEventArgs e) { TickPrice?.Invoke(this, e); }