Skip to content

Commit

Permalink
Fixes #12, added leaveZeroIfInvalidRow parameter for retrieving inval…
Browse files Browse the repository at this point in the history
…id rows
  • Loading branch information
Karl Wan committed Sep 20, 2017
1 parent fd97337 commit ca69506
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 13 deletions.
12 changes: 5 additions & 7 deletions YahooFinanceApi.Tests/UnitTest1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ public void PeriodTest()
var dict = new Dictionary<Period, decimal>
{
{Period.Daily, 115.800003m},
{Period.Weekly, 117.949997m},
{Period.Monthly, 127.029999m}
{Period.Weekly, 115.800003m},
{Period.Monthly, 115.800003m}
};
periods.ToList().ForEach(p =>
{
Expand All @@ -51,11 +51,9 @@ public void HistoricalTest()
var hist = Yahoo.GetHistoricalAsync(aaplTag, new DateTime(2017, 1, 3), new DateTime(2017, 1, 4), Period.Daily, true).Result.First();
Assert.Equal(115.800003m, hist.Open);
Assert.Equal(116.330002m, hist.High);
Assert.Equal(114.760002m, hist.Low);
// Bug: Yahoo has recently switched the close & adjusted close column in their csv,
// Don't know why they are doing so, the test case is temporailiy commented
//Assert.Equal(116.150002m, hist.Close);
//Assert.Equal(115.173210m, hist.AdjustedClose);
Assert.Equal(114.760002m, hist.Low);
Assert.Equal(116.150002m, hist.Close);
Assert.Equal(114.722694m, hist.AdjustedClose);
Assert.Equal(28_781_900, hist.Volume);
}

Expand Down
2 changes: 1 addition & 1 deletion YahooFinanceApi.Tests/YahooFinanceApi.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp1.1</TargetFramework>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
Expand Down
9 changes: 9 additions & 0 deletions YahooFinanceApi/RowExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,22 @@ public static Candle ToCandle(this string[] row)
Convert.ToInt64(row[6], CultureInfo.InvariantCulture),
Convert.ToDecimal(row[5], CultureInfo.InvariantCulture));

public static Candle ToFallbackCandle(this string[] row)
=> new Candle(Convert.ToDateTime(row[0], CultureInfo.InvariantCulture), 0, 0, 0, 0, 0, 0);

public static DividendTick ToDividendTick(this string[] row)
=> new DividendTick(Convert.ToDateTime(row[0], CultureInfo.InvariantCulture),
Convert.ToDecimal(row[1], CultureInfo.InvariantCulture));

public static DividendTick ToFallbackDividendTick(this string[] row)
=> new DividendTick(Convert.ToDateTime(row[0], CultureInfo.InvariantCulture), 0);

public static SplitTick ToSplitTick(this string[] row)
=> new SplitTick(Convert.ToDateTime(row[0], CultureInfo.InvariantCulture),
Convert.ToInt32(row[1].Split('/')[0], CultureInfo.InvariantCulture),
Convert.ToInt32(row[1].Split('/')[1], CultureInfo.InvariantCulture));

public static SplitTick ToFallbackSplitTick(this string[] row)
=> new SplitTick(Convert.ToDateTime(row[0], CultureInfo.InvariantCulture), 0, 0);
}
}
27 changes: 23 additions & 4 deletions YahooFinanceApi/Yahoo - Historical.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Threading;
using System.Threading.Tasks;
using System.Net;
using System.Globalization;

namespace YahooFinanceApi
{
Expand All @@ -23,34 +24,40 @@ public static partial class Yahoo
const string EventsTag = "events";
const string CrumbTag = "crumb";

public static async Task<IList<Candle>> GetHistoricalAsync(string symbol, DateTime? startTime = default(DateTime?), DateTime? endTime = default(DateTime?), Period period = Period.Daily, bool ascending = false, CancellationToken token = default(CancellationToken))
public static async Task<IList<Candle>> GetHistoricalAsync(string symbol, DateTime? startTime = default(DateTime?), DateTime? endTime = default(DateTime?), Period period = Period.Daily, bool ascending = false, bool leaveZeroIfInvalidRow = false, CancellationToken token = default(CancellationToken))
=> await GetTicksAsync(symbol,
startTime,
endTime,
period,
ShowOption.History,
r => r.ToCandle(),
r => r.ToFallbackCandle(),
ascending,
leaveZeroIfInvalidRow,
token);

public static async Task<IList<DividendTick>> GetDividendsAsync(string symbol, DateTime? startTime = default(DateTime?), DateTime? endTime = default(DateTime?), bool ascending = false, CancellationToken token = default(CancellationToken))
public static async Task<IList<DividendTick>> GetDividendsAsync(string symbol, DateTime? startTime = default(DateTime?), DateTime? endTime = default(DateTime?), bool ascending = false, bool leaveZeroIfInvalidRow = false, CancellationToken token = default(CancellationToken))
=> await GetTicksAsync(symbol,
startTime,
endTime,
Period.Daily,
ShowOption.Dividend,
r => r.ToDividendTick(),
r => r.ToFallbackDividendTick(),
ascending,
leaveZeroIfInvalidRow,
token);

public static async Task<IList<SplitTick>> GetSplitsAsync(string symbol, DateTime? startTime = default(DateTime?), DateTime? endTime = default(DateTime?), bool ascending = false, CancellationToken token = default(CancellationToken))
public static async Task<IList<SplitTick>> GetSplitsAsync(string symbol, DateTime? startTime = default(DateTime?), DateTime? endTime = default(DateTime?), bool ascending = false, bool leaveZeroIfInvalidRow = false, CancellationToken token = default(CancellationToken))
=> await GetTicksAsync(symbol,
startTime,
endTime,
Period.Daily,
ShowOption.Split,
r => r.ToSplitTick(),
r => r.ToFallbackSplitTick(),
ascending,
leaveZeroIfInvalidRow,
token);

static async Task<IList<T>> GetTicksAsync<T>(
Expand All @@ -60,7 +67,9 @@ static async Task<IList<T>> GetTicksAsync<T>(
Period period,
ShowOption showOption,
Func<string[], T> instanceFunction,
Func<string[], T> fallbackFunction,
bool ascending,
bool leaveZeroIfInvalidRow,
CancellationToken token
) where T: ITick
{
Expand All @@ -75,7 +84,17 @@ CancellationToken token
while (csvReader.Read())
{
string[] row = csvReader.CurrentRecord;
try { ticks.Add(instanceFunction(row)); } catch { /* Intentionally blank, ignore all record with invalid format */ }
DateTime? dateTime = null;
try
{
dateTime = Convert.ToDateTime(row[0], CultureInfo.InvariantCulture);
ticks.Add(instanceFunction(row));
}
catch
{
if (dateTime.HasValue && leaveZeroIfInvalidRow)
ticks.Add(fallbackFunction(row));
}
}

return ticks.OrderBy(c => c.DateTime, new DateTimeComparer(ascending)).ToList();
Expand Down
2 changes: 1 addition & 1 deletion YahooFinanceApi/YahooFinanceApi.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<PackageId>YahooFinanceApi</PackageId>
<PackageTags>Yahoo;Finance;Stock;Quote;Eod;Dividend;Split</PackageTags>
<PackageReleaseNotes>
[20/09/2017] Added .NET Standard 2.0 support
[20/09/2017] Added .NET Standard 2.0 support, added leaveZeroIfInvalidRow parameter for historical methods
[15/07/2017] Better error message if yahoo returns 404(Not Found) exception.
[14/07/2017] Added retry/re-establish mechanism if yahoo returns 401(Unauthorized) exception, optimized the locking mechanism
[06/07/2017] Fix parsing for different culture
Expand Down

0 comments on commit ca69506

Please sign in to comment.