public void UpdateProductHistoricCandles_ShouldReturnOrderBook_WhenAccountExists() { //Arrange _httpMessageHandlerMock .Protected() .Setup <Task <HttpResponseMessage> >("SendAsync", ItExpr.IsAny <HttpRequestMessage>(), ItExpr.IsAny <CancellationToken>()) .Returns(Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK) { StatusCode = HttpStatusCode.OK, Content = new StringContent( @"[ [1594131000000,""8244.44000000"",""8247.71000000"",""8234.56000000"",""8247.53000000"",""0.57541000"",1594131299999,""4743.74677830"",29,""0.51348500"",""4233.45949059"",""0""], [1594131300000,""8251.92000000"",""8263.73000000"",""8235.49000000"",""8261.31000000"",""0.73944300"",1594131599999,""6104.99268016"",73,""0.44151600"",""3646.66755442"",""0""], [1594131600000,""8258.99000000"",""8266.70000000"",""8253.56000000"",""8265.01000000"",""0.21730200"",1594131899999,""1795.04159624"",61,""0.12557200"",""1037.27246541"",""0""]]") })) .Verifiable(); HttpClient httpClient = new HttpClient(_httpMessageHandlerMock.Object); _connectionAdapter.HttpClient = httpClient; Binance subjectUnderTest = new Binance { ConnectionAdapter = _connectionAdapter }; HistoricCandlesSearch historicCandlesSearch = new HistoricCandlesSearch { Symbol = "BTCEUR", StartingDateTime = new DateTime(2015, 4, 23).Date.ToUniversalTime() }; historicCandlesSearch.EndingDateTime = historicCandlesSearch.StartingDateTime.AddMonths(6).ToUniversalTime(); //Act subjectUnderTest.UpdateProductHistoricCandlesAsync(historicCandlesSearch).Wait(); //Assert Assert.IsNotNull(subjectUnderTest.HistoricRates); Assert.AreEqual(3, subjectUnderTest.HistoricRates.Count); Assert.AreEqual((decimal)8234.56000000, subjectUnderTest.HistoricRates[0].Low); Assert.AreEqual((decimal)0.57541000, subjectUnderTest.HistoricRates[0].Volume); }
public override async Task <List <HistoricRate> > UpdateProductHistoricCandlesAsync( HistoricCandlesSearch historicCandlesSearch) { string json = null; try { ProcessLogBroadcast?.Invoke(ApplicationName, MessageType.General, "Updating Product Historic Candles Information."); if (historicCandlesSearch.StartingDateTime.AddMilliseconds((double)historicCandlesSearch .Granularity) >= historicCandlesSearch.EndingDateTime) { return(null); } Request request = new Request(ConnectionAdapter.Authentication.EndpointUrl, "GET", $"/products/{historicCandlesSearch.Symbol}/candles?start={historicCandlesSearch.StartingDateTime:o}&end={historicCandlesSearch.EndingDateTime:o}&granularity={(int) historicCandlesSearch.Granularity}"); json = await ConnectionAdapter.RequestAsync(request); if (json.StartsWith('[') && json.EndsWith(']')) { ArrayList[] candles = JsonSerializer.Deserialize <ArrayList[]>(json); HistoricRates = candles.ToHistoricRateList(); HistoricRates.Reverse(); } else { ProcessLogBroadcast?.Invoke(ApplicationName, MessageType.JsonOutput, $"Method: UpdateProductHistoricCandlesAsync\r\nJSON: {json}"); } } catch (Exception e) { ProcessLogBroadcast?.Invoke(ApplicationName, MessageType.Error, $"Method: UpdateProductHistoricCandlesAsync\r\nException Stack Trace: {e.StackTrace}\r\nJSON: {json}"); } return(HistoricRates); }
public void UpdateProductHistoricCandles_ShouldReturnOrderBook_WhenAccountExists() { //Arrange _httpMessageHandlerMock .Protected() .Setup <Task <HttpResponseMessage> >("SendAsync", ItExpr.IsAny <HttpRequestMessage>(), ItExpr.IsAny <CancellationToken>()) .Returns(Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK) { StatusCode = HttpStatusCode.OK, Content = new StringContent( @"[[1415398998, 0.33, 4.9, 0.40, 4.5, 15.3],[1415398768, 0.32, 4.2, 0.35, 4.2, 12.3]]") })) .Verifiable(); HttpClient httpClient = new HttpClient(_httpMessageHandlerMock.Object); _connectionAdapter.HttpClient = httpClient; Coinbase subjectUnderTest = new Coinbase { ConnectionAdapter = _connectionAdapter }; HistoricCandlesSearch historicCandlesSearch = new HistoricCandlesSearch { Symbol = "BTC-EUR", StartingDateTime = new DateTime(2015, 4, 23).Date.ToUniversalTime(), EndingDateTime = new DateTime(2015, 4, 23).Date.ToUniversalTime().AddMonths(6).ToUniversalTime() }; //Act subjectUnderTest.UpdateProductHistoricCandlesAsync(historicCandlesSearch).Wait(); //Assert Assert.IsNotNull(subjectUnderTest.HistoricRates); Assert.AreEqual(2, subjectUnderTest.HistoricRates.Count); Assert.AreEqual((decimal)0.32, subjectUnderTest.HistoricRates[0].Low); Assert.AreEqual((decimal)12.3, subjectUnderTest.HistoricRates[0].Volume); }
private async void ProcessHistoryQuarterlyChartDownload() { await _processHistorySemaphoreSlim.WaitAsync(); try { string fileName = FileName + $"_{RelativeStrengthIndexSettings.Product.ID.ToLower()}_15M.csv"; string data = "DateTime,High,Open,Close,Low,Volume,MA7,RSI14\n"; //Validate file if (!File.Exists(fileName)) { if (!Directory.Exists(Path.GetDirectoryName(fileName))) { Directory.CreateDirectory(Path.GetDirectoryName(fileName)); } File.Create(fileName).Close(); SaveAnalyticData(fileName, data); } //Initialise fields const int period = 14; const int maPeriod = 7; const int granularity = 900; DateTime startingDateTime; HistoricRate previousHistoricRate = null; decimal increases = 0; decimal decreases = 0; Queue <HistoricRate> maQueue = new Queue <HistoricRate>(); //Check if we have an empty file or not if (string.IsNullOrWhiteSpace(RelativeStrengthIndexSettings .HistoricChartPreviousHistoricDateTimeQuarterly)) { startingDateTime = new DateTime(2015, 4, 23).Date; RelativeStrengthIndexSettings.HistoricChartAverageGainQuarterly = 0; RelativeStrengthIndexSettings.HistoricChartAverageLossQuarterly = 0; RelativeStrengthIndexSettings.HistoricChartCurrentPeriodCountQuarterly = 0; RelativeStrengthIndexSettings.RelativeIndexQuarterly = -1; } else { startingDateTime = RelativeStrengthIndexSettings.HistoricChartPreviousHistoricDateTimeQuarterly .ToDateTime().AddMinutes(15); previousHistoricRate = new HistoricRate { Close = RelativeStrengthIndexSettings.HistoricChartPreviousHistoricRateCloseQuarterly, Open = RelativeStrengthIndexSettings.HistoricChartPreviousHistoricRateOpenQuarterly, Low = RelativeStrengthIndexSettings.HistoricChartPreviousHistoricRateLowQuarterly, High = RelativeStrengthIndexSettings.HistoricChartPreviousHistoricRateHighQuarterly, Volume = RelativeStrengthIndexSettings.HistoricChartPreviousHistoricRateVolumeQuarterly, DateAndTime = RelativeStrengthIndexSettings.HistoricChartPreviousHistoricDateTimeQuarterly .ToDateTime() }; } //Begin data parsing DateTime now = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, DateTime.Now.Hour, DateTime.Now.Minute, 0); while (startingDateTime < now) { DateTime endingDateTime = startingDateTime.AddDays(2); //Get the latest historic data HistoricCandlesSearch historicCandlesSearch = new HistoricCandlesSearch { Symbol = RelativeStrengthIndexSettings.Product.ID, StartingDateTime = startingDateTime, EndingDateTime = endingDateTime, Granularity = (Granularity)granularity }; //Prevent overloaded calls by delaying for 1 second before call await Task.Delay(1000); //Get the latest historic data List <HistoricRate> result = await UpdateProductHistoricCandles(historicCandlesSearch); if (!result.Any()) { //in the case that no data is available but current search date is not current date startingDateTime = new DateTime(startingDateTime.Year, startingDateTime.Month, 1, 0, 0, 0) .AddMonths(1); continue; } //Iterate though the historic data foreach (HistoricRate rate in result) { if (rate.DateAndTime >= now) { break; } if (previousHistoricRate != null && previousHistoricRate.DateAndTime.ToString("dd/MM/yyyy HH:mm") == rate.DateAndTime.ToString("dd/MM/yyyy HH:mm")) { continue; } //Moving Average 7 days if (maQueue.Count == maPeriod) { maQueue.Dequeue(); } maQueue.Enqueue(rate); //Calculate RSI 14 days if (RelativeStrengthIndexSettings.HistoricChartCurrentPeriodCountQuarterly > 0) { decimal change = rate.Close - previousHistoricRate.Close; if (change > 0) { increases += change; if (RelativeStrengthIndexSettings.HistoricChartCurrentPeriodCountQuarterly > period) { RelativeStrengthIndexSettings.HistoricChartAverageGainQuarterly = (RelativeStrengthIndexSettings.HistoricChartAverageGainQuarterly * (period - 1) + change) / period; RelativeStrengthIndexSettings.HistoricChartAverageLossQuarterly = RelativeStrengthIndexSettings.HistoricChartAverageLossQuarterly * (period - 1) / period; } } else if (change < 0) { decreases += change * -1; if (RelativeStrengthIndexSettings.HistoricChartCurrentPeriodCountQuarterly > period) { RelativeStrengthIndexSettings.HistoricChartAverageGainQuarterly = RelativeStrengthIndexSettings.HistoricChartAverageGainQuarterly * (period - 1) / period; RelativeStrengthIndexSettings.HistoricChartAverageLossQuarterly = (RelativeStrengthIndexSettings.HistoricChartAverageLossQuarterly * (period - 1) + change * -1) / period; } } if (RelativeStrengthIndexSettings.HistoricChartCurrentPeriodCountQuarterly >= period) { if (RelativeStrengthIndexSettings.HistoricChartCurrentPeriodCountQuarterly == period) { RelativeStrengthIndexSettings.HistoricChartAverageGainQuarterly = increases / period; RelativeStrengthIndexSettings.HistoricChartAverageLossQuarterly = decreases / period; } if (RelativeStrengthIndexSettings.HistoricChartCurrentPeriodCountQuarterly >= period) { RelativeStrengthIndexSettings.RelativeIndexQuarterly = RelativeStrengthIndexSettings.HistoricChartAverageLossQuarterly == 0 ? 100 : Math.Round( 100 - 100 / (1 + RelativeStrengthIndexSettings.HistoricChartAverageGainQuarterly / RelativeStrengthIndexSettings.HistoricChartAverageLossQuarterly), 2); } //Generate data data = $"{rate.DateAndTime}," + $"{rate.High}," + $"{rate.Open}," + $"{rate.Close}," + $"{rate.Low}," + $"{rate.Volume}," + $"{maQueue.Average(x => x.Close)}," + $"{RelativeStrengthIndexSettings.RelativeIndexQuarterly}" + "\n"; SaveAnalyticData(fileName, data); } } previousHistoricRate = rate; RelativeStrengthIndexSettings.HistoricChartCurrentPeriodCountQuarterly++; } startingDateTime = previousHistoricRate.DateAndTime.AddMinutes(15); if (previousHistoricRate != null) { RelativeStrengthIndexSettings.HistoricChartPreviousHistoricRateCloseQuarterly = previousHistoricRate.Close; RelativeStrengthIndexSettings.HistoricChartPreviousHistoricRateOpenQuarterly = previousHistoricRate.Open; RelativeStrengthIndexSettings.HistoricChartPreviousHistoricRateLowQuarterly = previousHistoricRate.Low; RelativeStrengthIndexSettings.HistoricChartPreviousHistoricRateHighQuarterly = previousHistoricRate.High; RelativeStrengthIndexSettings.HistoricChartPreviousHistoricRateVolumeQuarterly = previousHistoricRate.Volume; RelativeStrengthIndexSettings.HistoricChartPreviousHistoricDateTimeQuarterly = previousHistoricRate.DateAndTime.ToString(); Dictionary <string, string> indicatorInformation = new Dictionary <string, string> { ["RSI-15MIN"] = RelativeStrengthIndexSettings.RelativeIndexQuarterly.ToString(CultureInfo .InvariantCulture), ["RSI-1HOUR"] = RelativeStrengthIndexSettings.RelativeIndexHourly .ToString(CultureInfo.InvariantCulture), ["RSI-1DAY"] = RelativeStrengthIndexSettings.RelativeIndexDaily.ToString(CultureInfo.InvariantCulture), ["OPEN-15MIN"] = RelativeStrengthIndexSettings.HistoricChartPreviousHistoricRateOpenQuarterly.ToString( CultureInfo.InvariantCulture), ["OPEN-1HOUR"] = RelativeStrengthIndexSettings.HistoricChartPreviousHistoricRateOpenHourly.ToString( CultureInfo.InvariantCulture), ["OPEN-1DAY"] = RelativeStrengthIndexSettings.HistoricChartPreviousHistoricRateOpen.ToString(CultureInfo .InvariantCulture) }; TechnicalIndicatorInformationBroadcast?.Invoke(indicatorInformation); Save(); } } } catch (Exception ex) { ProcessLogBroadcast?.Invoke(MessageType.Error, $"Method: ProcessHistoryHourlyChartDownload\r\nException Stack Trace: {ex.StackTrace}"); } finally { _processHistorySemaphoreSlim.Release(); } }
public virtual Task <List <HistoricRate> > UpdateProductHistoricCandlesAsync( HistoricCandlesSearch historicCandlesSearch) { throw new NotImplementedException(); }