-
Notifications
You must be signed in to change notification settings - Fork 59
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Working on #9, completed query with search string
- Loading branch information
Karl Wan
committed
Sep 20, 2017
1 parent
ca69506
commit 72b94ae
Showing
7 changed files
with
183 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
|
||
namespace YahooFinanceApi.Lookup | ||
{ | ||
public class LookupSymbol | ||
{ | ||
public string Symbol { get; } | ||
public string CompanyName { get; } | ||
//public decimal LastValue { get; } | ||
//public decimal Change { get; } | ||
//public decimal ChangePercent { get; } | ||
public string IndustryName { get; } | ||
public string IndustryLink { get; } | ||
public string Type { get; } | ||
public string Exchange { get; } | ||
|
||
public LookupSymbol(string symbol, string companyName, /*decimal lastValue, decimal change, decimal changePercent, */ | ||
string industryName, string industryLink, string type, string exchange) | ||
{ | ||
Exchange = exchange; | ||
Type = type; | ||
IndustryLink = industryLink; | ||
IndustryName = industryName; | ||
//ChangePercent = changePercent; | ||
//Change = change; | ||
//LastValue = lastValue; | ||
CompanyName = companyName; | ||
Symbol = symbol; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
using System; | ||
using System.Runtime.Serialization; | ||
|
||
namespace YahooFinanceApi.Lookup | ||
{ | ||
public enum LookupType | ||
{ | ||
[EnumMember(Value = "A")] | ||
All, | ||
[EnumMember(Value = "S")] | ||
Stocks, | ||
[EnumMember(Value = "M")] | ||
MutualFunds, | ||
[EnumMember(Value = "E")] | ||
ETFs, | ||
[EnumMember(Value = "I")] | ||
Indices, | ||
[EnumMember(Value = "F")] | ||
Futures, | ||
[EnumMember(Value = "C")] | ||
Currencies | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
using System; | ||
using System.Runtime.Serialization; | ||
|
||
namespace YahooFinanceApi.Lookup | ||
{ | ||
public enum MarketType | ||
{ | ||
[EnumMember(Value = "ALL")] | ||
All, | ||
[EnumMember(Value = "US")] | ||
US_Canada | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Flurl.Http; | ||
using Newtonsoft.Json; | ||
using Newtonsoft.Json.Linq; | ||
|
||
namespace YahooFinanceApi.Lookup | ||
{ | ||
public static class YahooLookup | ||
{ | ||
const string LookupUrl = "https://finance.yahoo.com/_finance_doubledown/api/resource/finance.yfinlist.symbol_lookup"; | ||
const string SearchTag = "s"; | ||
const string LookupTypeTag = "t"; | ||
const string MarketTag = "m"; | ||
const string OffsetTag = "b"; | ||
const string IsIncludeSimilarTag = "p"; | ||
|
||
public static async Task<IEnumerable<LookupSymbol>> GetLookupSymbolsAsync(string search, LookupType lookupType, MarketType marketType, CancellationToken token = default(CancellationToken)) | ||
{ | ||
Func<string, int, Task<Stream>> responseFunc = (s, i) => GetSymbolListResponseStreamAsync(s, lookupType, marketType, i, token); | ||
var childSearches = await GetLookupSearchesAsync(search, lookupType, marketType, token); | ||
|
||
var list = new List<LookupSymbol>(); | ||
foreach (var childSearch in childSearches) | ||
{ | ||
int offset = 0; | ||
while (true) | ||
{ | ||
using (var s = await responseFunc(childSearch, offset)) | ||
using (var sr = new StreamReader(s)) | ||
{ | ||
var o = JObject.Parse(sr.ReadToEnd()); | ||
var symbols = o["result"].ToArray(); | ||
list.AddRange(symbols.Select(sym => JsonConvert.DeserializeObject<LookupSymbol>(sym.ToString()))); | ||
|
||
var nav = o["navLink"]; | ||
var navAsDict = (IDictionary<string, JToken>)nav; | ||
if (!navAsDict.ContainsKey("nextPage") || !navAsDict.ContainsKey("lastPage")) | ||
break; | ||
|
||
offset = nav["nextPage"]["start"].Value<int>(); | ||
} | ||
} | ||
} | ||
|
||
return list; | ||
} | ||
|
||
public static async Task<IEnumerable<string>> GetLookupSearchesAsync(string search, LookupType lookupType, MarketType marketType, CancellationToken token = default(CancellationToken)) | ||
{ | ||
Func<int, Task<Stream>> responseFunc = i => GetSymbolListResponseStreamAsync(search, lookupType, marketType, i, token); | ||
var list = new List<string>(); | ||
|
||
if (await IsLookupSizeTooLargeAsync()) | ||
{ | ||
foreach (var subSearch in search.AddSuffixes()) | ||
list.AddRange(await GetLookupSearchesAsync(subSearch, lookupType, marketType, token)); | ||
return list; | ||
} | ||
|
||
return new string[] { search }; | ||
|
||
async Task<bool> IsLookupSizeTooLargeAsync() | ||
{ | ||
const int LookupSizeLimit = 2000; | ||
|
||
using (var s = await responseFunc(0)) | ||
using (var sr = new StreamReader(s)) | ||
{ | ||
var o = JObject.Parse(sr.ReadToEnd()); | ||
var nav = o["navLink"]; | ||
var navAsDict = (IDictionary<string, JToken>)nav; | ||
if (!navAsDict.ContainsKey("lastPage")) | ||
return false; | ||
|
||
return nav["lastPage"]["start"].Value<int>() >= LookupSizeLimit; | ||
} | ||
} | ||
} | ||
|
||
public static async Task<Stream> GetSymbolListResponseStreamAsync(string search, LookupType lookupType, MarketType marketType, int offset, CancellationToken token = default(CancellationToken)) | ||
=> await new StringBuilder() | ||
.Append(LookupUrl) | ||
.Append($";{SearchTag}={search}") | ||
.Append($";{LookupTypeTag}={lookupType.Name()}") | ||
.Append($";{MarketTag}={marketType.Name()}") | ||
.Append($";{OffsetTag}={offset}") | ||
.Append($";{IsIncludeSimilarTag}=1") | ||
.ToString() | ||
.GetStreamAsync(token); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters