示例#1
0
        private void HandleTradeMessage(TradeEventResponse channel, dynamic data)
        {
            var raw = new JArray();

            if (data[1] is JArray)
            {
                raw = data[1];
            }
            else
            {
                var type = Convert.ToString(data[1]);

                if (type != "tu")
                {
                    return;
                }

                raw.Add(data[2]);
            }

            var pair = Exchange.DecodeSymbol(channel.Symbol);

            var symbol = SymbolFactory.Get(pair[0], pair[1]);

            var additionalData = new NameValueCollection();

            additionalData.Add("SymbolCode", symbol.Code.ToString());

            var result = Exchange.ChangeType <dynamic, TradeResult>(SymbolFactory, raw, null, additionalData);

            OnTradesReceived?.Invoke(this, new TradesReceivedEventArgs {
                Data = result
            });
        }
示例#2
0
        public ISymbol DecodeProductId(string productId)
        {
            var baseCurrencyCode  = this.GetStandardisedCurrencyCode(CurrencyFactory, productId.Substring(0, 3));
            var quoteCurrencyCode = this.GetStandardisedCurrencyCode(CurrencyFactory, productId.Substring(4, 3));

            return(SymbolFactory.Get(baseCurrencyCode, quoteCurrencyCode));
        }
        private async void EnsureHistoricalTrades()
        {
            if (!Exchange.SupportsHistoricalLoad)
            {
                return;
            }

            Logger.LogInformation("Ensure historical trades are captured.");

            foreach (var symbolCode in ExchangeWorker.Configuration.Symbol)
            {
                var symbol          = SymbolFactory.Get(symbolCode);
                var lastTradeFilter = await HistorianRepository.GetTradeFilter(Exchange.Name, symbolCode);

                var priority = string.Equals(lastTradeFilter, Exchange.GetHttpClient().InitialTradeFilter) ? 2 : 1;

                var catchup = new HistorianTradeCatchup
                {
                    Exchange           = Exchange.Name,
                    SymbolCode         = symbolCode,
                    TradeFilter        = lastTradeFilter,
                    EpochTo            = Epoch.Now,
                    CurrentTradeFilter = lastTradeFilter,
                    Priority           = priority
                };

                await HistorianRepository.AddTradeCatchup(catchup);
            }
        }
示例#4
0
        public async Task GetTradesRequestIsValid()
        {
            foreach (var symbolCode in Exchange.Symbol)
            {
                var symbol = SymbolFactory.Get(symbolCode);

                await ExchangeHttpClientTests.HttpGetTradeRequestIsValid(Exchange, symbol);
            }
        }
        private void BeginReceiveTradesWebSocket() => Task.Run(() =>
        {
            ExchangeTradeCatchupWorker.Start(ExchangeWorker, Limit);

            var symbols = ExchangeWorker.Configuration.Symbol.Select(s => SymbolFactory.Get(s)).ToList();

            using (Logger.BeginProtocolScope("Web Socket"))
            {
                Logger.LogInformation($"Establishing connection");

                WebSocketClient.OnOpen += delegate(object sender, EventArgs e)
                {
                    Logger.LogInformation($"Established connection");

                    Logger.LogInformation($"Begin listening for trades");

                    if (WebSocketClient.IsSubscribeModel)
                    {
                        WebSocketClient.BeginListenTrades(symbols);
                    }
                };

                WebSocketClient.OnClose += delegate(object sender, CloseEventArgs e)
                {
                    if (ExchangeWorker.Online)
                    {
                        Logger.LogWarning($"Connection has been closed");
                    }

                    RetryWebSocketConnect();
                };

                WebSocketClient.OnTradesReceived += async delegate(object sender, TradesReceivedEventArgs e)
                {
                    using (Logger.BeginSymbolScope(e.Data.SymbolCode))
                    {
                        Logger.LogInformation($"Trades received");

                        using (var transaction = await StorageTransactionFactory.Begin())
                        {
                            await ExchangeTradeProvider.AddTrades(transaction, Logger, e.Data);

                            await HistorianRepository.SetTradeFilter(transaction, Exchange.Name, e.Data.SymbolCode, e.Data.Filter);

                            await transaction.Commit();
                        }
                    }
                };

                WebSocketClient.Begin();

                if (!WebSocketClient.IsSubscribeModel)
                {
                    WebSocketClient.BeginListenTrades(symbols);
                }
            }
        });
        public void Start(IExchangeWorker exchangeWorker, int pageSize)
        {
            ExchangeWorker = exchangeWorker;

            foreach (var symbolCode in ExchangeWorker.Configuration.Symbol)
            {
                var symbol = SymbolFactory.Get(symbolCode);

                if (symbol.Tradable)
                {
                    AggregateTrades(symbol, pageSize);
                }
            }
        }
示例#7
0
        public void Start(IExchangeWorker exchangeWorker, int pageSize)
        {
            ExchangeWorker = exchangeWorker;

            if (Exchange.SupportedStatKeys == null)
            {
                return;
            }

            foreach (var symbolCode in ExchangeWorker.Configuration.Symbol)
            {
                var symbol = SymbolFactory.Get(symbolCode);

                if (symbol.Tradable)
                {
                    foreach (var statsKey in Exchange.SupportedStatKeys)
                    {
                        AggregateTradeStats(symbol, statsKey, pageSize);
                    }
                }
            }
        }
示例#8
0
        private void HandleTradeMessage(SubscriptionEventResponse channel, dynamic data)
        {
            if (!(data[1] is JArray))
            {
                return;
            }

            var raw = data[1] as JArray;

            var pair = channel.Pair.Split('/');

            var baseCurrencyCode  = Exchange.GetStandardisedCurrencyCode(CurrencyFactory, pair[0]);
            var quoteCurrencyCode = Exchange.GetStandardisedCurrencyCode(CurrencyFactory, pair[1]);

            var symbol = SymbolFactory.Get(baseCurrencyCode, quoteCurrencyCode);

            var trades = raw.Select(t => new MarketTrade
            {
                Exchange   = Exchange.Name,
                SymbolCode = symbol.Code,
                Epoch      = Epoch.FromSeconds(Convert.ToDouble(t[2])),
                Price      = Convert.ToDecimal(t[0]),
                Volume     = Convert.ToDecimal(t[1]),
                Side       = (string)t[3] == "b" ? OrderSideEnum.Buy : OrderSideEnum.Sell
            }).ToList();

            var tradeResult = new TradeResult
            {
                Exchange   = Exchange.Name,
                SymbolCode = symbol.Code,
                Filter     = null,
                Trades     = trades
            };

            OnTradesReceived?.Invoke(this, new TradesReceivedEventArgs {
                Data = tradeResult
            });
        }
示例#9
0
        private void HandleTickerMessage(TickerEventResponse channel, dynamic data)
        {
            if (data[1].GetType() != typeof(JArray))
            {
                return;
            }

            var raw = (data[1] as JArray).ToObject <object[]>();

            var pair = Exchange.DecodeSymbol(channel.Symbol);

            var symbol = SymbolFactory.Get(pair[0], pair[1]);

            var additionalData = new NameValueCollection();

            additionalData.Add("SymbolCode", symbol.Code.ToString());

            var result = Exchange.ChangeType <dynamic, MarketTick>(SymbolFactory, raw, null, additionalData);

            OnTickerReceived?.Invoke(this, new TickerReceivedEventArgs {
                Data = result
            });
        }
示例#10
0
        public void CanReceiveTrades()
        {
            var symbol = SymbolFactory.Get(CurrencyCodeEnum.ETH, CurrencyCodeEnum.BTC);

            WebSocketTest.CanReceiveTrades(symbol);
        }
示例#11
0
        private async Task Ping(bool initial = false)
        {
            try
            {
                var ping = new Ping();

                var uri = new Uri(Exchange.GetHttpClient().ApiUrl);

                var reply = await ping.SendPingAsync(uri.Host);

                if (reply.Status == IPStatus.Success)
                {
                    // If the exchange is running web socket, and supports historical loads, ensure the historian does not produce gaps
                    if (!initial && !Online && Exchange.SupportsHistoricalLoad && Exchange.GetWebSocketClient() != null)
                    {
                        Logger.LogInformation($"Regained connectivity");

                        var symbols = await HistorianRepository.GetSymbols(Exchange.Name);

                        foreach (var historianSymbol in symbols)
                        {
                            var symbol = SymbolFactory.Get(historianSymbol.SymbolCode);

                            if (!symbol.Tradable)
                            {
                                continue;
                            }

                            using (Logger.BeginSymbolScope(symbol.Code))
                            {
                                var now = Epoch.Now;

                                var catchup = new HistorianTradeCatchup
                                {
                                    Exchange           = Exchange.Name,
                                    SymbolCode         = historianSymbol.SymbolCode,
                                    TradeFilter        = historianSymbol.TradeFilter,
                                    EpochTo            = now,
                                    CurrentTradeFilter = historianSymbol.TradeFilter,
                                    Priority           = 1
                                };

                                Logger.LogWarning($"Adding trade catch up job with filter '{historianSymbol.TradeFilter}'");

                                await HistorianRepository.AddTradeCatchup(catchup);
                            }
                        }
                    }

                    Online = true;
                }
                else
                {
                    Logger.LogWarning($"Lost connectivity: {reply.Status}");

                    Online = false;
                }
            }
            catch (Exception ex)
            {
                Logger.LogWarning(ex, $"Unexpected error occurred when pinging");

                Online = false;
            }
        }
        private void BeginReceiveTradesHttp() => Task.Run(async() =>
        {
            using (Logger.BeginProtocolScope("Https"))
            {
                var symbols = ExchangeWorker.Configuration.Symbol.Select(symbolCode => SymbolFactory.Get(symbolCode)).Where(symbol => symbol.Tradable);

                while (true)
                {
                    if (!ExchangeWorker.Online)
                    {
                        await Task.Delay(1000);

                        continue;
                    }

                    foreach (var symbol in symbols)
                    {
                        using (Logger.BeginSymbolScope(symbol.Code))
                        {
                            try
                            {
                                var lastTradeFilter = await HistorianRepository.GetTradeFilter(Exchange.Name, symbol.Code);

                                TradeResult result;

                                using (var transaction = await StorageTransactionFactory.Begin())
                                {
                                    result = await ExchangeTradeProvider.ReceiveTradesHttp(transaction, Logger, Exchange.Name, symbol, HttpClient, Limit, lastTradeFilter);

                                    if (result != null)
                                    {
                                        await HistorianRepository.SetTradeFilter(transaction, Exchange.Name, symbol.Code, result.Filter);
                                    }

                                    await transaction.Commit();
                                }

                                if (result == null)
                                {
                                    await Task.Delay(1000);
                                }
                            }
                            catch (Exception ex)
                            {
                                Logger.LogError(ex, "Unexpected error occurred");
                            }
                        }
                    }
                }
            }
        });
        private void BeginTradeCatchupWorker(int limit) => Task.Run(async() =>
        {
            using (Logger.BeginProtocolScope("Https"))
            {
                while (true)
                {
                    foreach (var symbolCode in ExchangeWorker.Configuration.Symbol)
                    {
                        using (Logger.BeginSymbolScope(symbolCode))
                        {
                            var symbol = SymbolFactory.Get(symbolCode);

                            if (!symbol.Tradable)
                            {
                                continue;
                            }

                            try
                            {
                                if (!ExchangeWorker.Online)
                                {
                                    await Task.Delay(2000);

                                    continue;
                                }

                                var current = await HistorianRepository.GetNextTradeCatchup(Exchange.Name, symbolCode);

                                if (current == null)
                                {
                                    continue;
                                }

                                TradeResult result = null;

                                using (var transaction = await StorageTransactionFactory.Begin())
                                {
                                    result = await ExchangeTradeProvider.ReceiveTradesHttp(transaction, Logger, Exchange.Name, symbol, HttpClient, limit, current.CurrentTradeFilter);

                                    await transaction.Commit();
                                }

                                if (result == null)
                                {
                                    continue;
                                }

                                var lastTrade = result.Trades.LastOrDefault();

                                if (lastTrade.Epoch.TimestampMilliseconds > current.EpochTo.TimestampMilliseconds)
                                {
                                    await HistorianRepository.RemoveTradeCatchup(current);
                                }
                                else
                                {
                                    current.CurrentTradeFilter = result.Filter;
                                    await HistorianRepository.UpdateTradeCatchup(current);
                                }
                            }
                            catch (Exception ex)
                            {
                                Logger.LogError(ex, "Unable to get trade catchup jobs.");
                            }
                        }
                    }
                }
            }
        });
示例#14
0
        public void Start(IExchangeWorker exchangeWorker) => Task.Run(async() =>
        {
            ExchangeWorker = exchangeWorker;

            if (Exchange.SupportedStatKeys == null)
            {
                return;
            }

            Logger = LoggerFactory.CreateLogger($"Historian.{Exchange.Name}.Worker.TradeStats");

            HttpClient = Exchange.GetHttpClient();

            using (Logger.BeginExchangeScope(Exchange.Name))
            {
                using (Logger.BeginProtocolScope("Https"))
                {
                    while (true)
                    {
                        if (!ExchangeWorker.Online)
                        {
                            await Task.Delay(1000);

                            continue;
                        }

                        var symbols = ExchangeWorker.Configuration.Symbol.Select(symbolCode => SymbolFactory.Get(symbolCode)).Where(s => s.Tradable);

                        foreach (var symbol in symbols)
                        {
                            using (Logger.BeginSymbolScope(symbol.Code))
                            {
                                foreach (var statsKey in Exchange.SupportedStatKeys)
                                {
                                    using (Logger.BeginExchangeStatsScope(statsKey))
                                    {
                                        await ReceiveTradeStatsHttp(symbol, statsKey);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        });
        public async Task <bool> Run(ILogger logger)
        {
            logger.LogInformation("Running repository bootstrapper");

            try
            {
                foreach (var currency in CurrencyFactory.List())
                {
                    await CurrencyRepository.Add(currency);
                }

                foreach (var symbol in SymbolFactory.List())
                {
                    await SymbolRepository.Add(symbol);
                }

                foreach (var group in IntervalFactory.ListGroups())
                {
                    foreach (var ik in IntervalFactory.ListIntervalKeys(group.IntervalGroup))
                    {
                        await IntervalRepository.Add(ik);
                    }
                }

                foreach (var exchange in ExchangeFactory.List())
                {
                    await ExchangeRepository.Add(exchange);

                    var httpClient = exchange.GetHttpClient();

                    foreach (var symbolCode in exchange.Symbol)
                    {
                        var symbol = SymbolFactory.Get(symbolCode);

                        await SymbolRepository.Add(symbol);

                        await ExchangeRepository.AddSymbol(exchange.Name, symbolCode);

                        var tradeFilter = await HistorianRepository.GetTradeFilter(exchange.Name, symbolCode);

                        if (tradeFilter == null)
                        {
                            using (var transaction = await StorageTransactionFactory.Begin())
                            {
                                await HistorianRepository.SetTradeFilter(transaction, exchange.Name, symbolCode, httpClient.InitialTradeFilter);

                                await transaction.Commit();
                            }
                        }
                    }
                }

                foreach (var orderSide in OrderSideFactory.List())
                {
                    await OrderSideRepository.Add(orderSide);
                }

                return(true);
            }
            catch (Exception ex)
            {
                logger.LogCritical(ex, "Unable to run repository bootstrapper");

                return(false);
            }
        }