From 4bee590990cf397b6f9c95a52240db063168034c Mon Sep 17 00:00:00 2001 From: Karl Wan Date: Sun, 2 Jul 2017 19:14:55 +0800 Subject: [PATCH] #4, Complete integrating Nuba.Finance.Google into Trady.Importer --- Trady.Importer/GoogleFinanceImporter.cs | 43 +++++++++++++++++++++++++ Trady.Importer/Trady.Importer.csproj | 7 ++-- Trady.Test/ImporterTest.cs | 12 +++++++ 3 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 Trady.Importer/GoogleFinanceImporter.cs diff --git a/Trady.Importer/GoogleFinanceImporter.cs b/Trady.Importer/GoogleFinanceImporter.cs new file mode 100644 index 0000000..80469da --- /dev/null +++ b/Trady.Importer/GoogleFinanceImporter.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Trady.Core.Period; +using Nuba.Finance.Google; +using System.Linq; + +namespace Trady.Importer +{ + public class GoogleFinanceImporter: IImporter + { + LatestQuotesService _lqs; + + public GoogleFinanceImporter() + { + _lqs = new LatestQuotesService(); + } + + const char SymbolSeparator = '/'; + + static readonly IDictionary PeriodMap = new Dictionary + { + {PeriodOption.PerSecond, Frequency.EverySecond}, + {PeriodOption.PerMinute, Frequency.EveryMinute}, + {PeriodOption.Hourly, Frequency.EveryHour}, + {PeriodOption.Daily, Frequency.EveryDay} + }; + + public async Task> ImportAsync(string symbol, DateTime? startTime = default(DateTime?), DateTime? endTime = default(DateTime?), PeriodOption period = PeriodOption.Daily, CancellationToken token = default(CancellationToken)) + { + if (!PeriodMap.TryGetValue(period, out int frequency)) + throw new ArgumentException("This importer only supports second, minute, hourly & daily data"); + + if (!symbol.Contains(SymbolSeparator.ToString())) + throw new ArgumentException("The input symbol should be in the form of \'{Market}/{Symbol}\'"); + + string[] syms = symbol.Split(SymbolSeparator); + var candles = await Task.Run(() => _lqs.GetValues(syms[0].ToUpper(), syms[1], PeriodMap[period], startTime, endTime)); + return candles.Select(c => new Core.Candle(c.Date, c.Open, c.High, c.Low, c.Close, c.Volume)).OrderBy(c => c.DateTime).ToList(); + } + } +} diff --git a/Trady.Importer/Trady.Importer.csproj b/Trady.Importer/Trady.Importer.csproj index 1e08d62..b6042f2 100644 --- a/Trady.Importer/Trady.Importer.csproj +++ b/Trady.Importer/Trady.Importer.csproj @@ -1,4 +1,4 @@ - + netstandard1.4 @@ -48,8 +48,9 @@ All --> - - + + + diff --git a/Trady.Test/ImporterTest.cs b/Trady.Test/ImporterTest.cs index 8eead11..6f8c941 100644 --- a/Trady.Test/ImporterTest.cs +++ b/Trady.Test/ImporterTest.cs @@ -15,6 +15,18 @@ public ImporterTest() CultureInfo.CurrentCulture = new CultureInfo("nl-nl"); } + [TestMethod] + public void ImportByGoogleFinance() + { + var importer = new GoogleFinanceImporter(); + var candle = importer.ImportAsync("NASDAQ/AAPL", new DateTime(2017, 1, 3), new DateTime(2017, 1, 3)).Result.First(); + Assert.AreEqual(candle.Open, 115.8m); + Assert.AreEqual(candle.High, 116.33m); + Assert.AreEqual(candle.Low, 114.76m); + Assert.AreEqual(candle.Close, 116.15m); + Assert.AreEqual(candle.Volume, 28_781_865); + } + [TestMethod] public void ImportByQuandlYahoo() {