protected override async Task ExecuteAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { // Fetch data from BINANCE API for BTC/EUR pair var orderBookBtcEur = await _fetchDataService.FetchOrderBookDataFromUrl("https://api.binance.com/api/v3/depth?symbol=BTCEUR&limit=1000"); // Fetch data from BINANCE API for BTC/USDC pair var orderBookBtcUsd = await _fetchDataService.FetchOrderBookDataFromUrl("https://api.binance.com/api/v3/depth?symbol=BTCUSDC&limit=1000"); // Calculate market depth // Calculate order book depth for BTCEUR var calculatedOrderBookDepthBtcEur = await _calculationService.CalculateOrderBookDepth(orderBookBtcEur); // Calculate order book market depth for BTCUSDC var calculatedOrderBookDepthBtcUsd = await _calculationService.CalculateOrderBookDepth(orderBookBtcUsd); var serializedBtcEurOrderBookDepthDto = JsonSerializer.Serialize(calculatedOrderBookDepthBtcEur); var serializedBtUsdOrderBookDepthDto = JsonSerializer.Serialize(calculatedOrderBookDepthBtcUsd); // Notify clients connected to SignalR hub // Notify all clients subscribed to BTCEUR await _orderBookHub.Clients.Group("BTCEUR").UpdateOrderBook(calculatedOrderBookDepthBtcEur); // Notify all clients subscribed to BTCUSDC await _orderBookHub.Clients.Group("BTCUSD").UpdateOrderBook(calculatedOrderBookDepthBtcUsd); // Save returned data to file system // For the sake of simplicity and purpose of the challenge we will write audit log to file system // In the real case we would write audit to the database using (var sw = File.CreateText($"{_env.ContentRootPath}/Audit/{DateTimeOffset.Now.ToUnixTimeSeconds()}_BTCEUR.txt")) { await sw.WriteAsync(serializedBtcEurOrderBookDepthDto); } using (var sw = File.CreateText($"{_env.ContentRootPath}/Audit/{DateTimeOffset.Now.ToUnixTimeSeconds()}_BTCUSD.txt")) { await sw.WriteAsync(serializedBtUsdOrderBookDepthDto); } await Task.Delay(1000); } }
public async Task FetchDataFromUrl_ShouldThrowExceptionIfInvalidUrl() { await Should.ThrowAsync <Exception>(_fetchDataService.FetchOrderBookDataFromUrl("test")); }