Mission: Create a web page that displays current stock data in an interesting way. This page will be displayed in my wife's classroom using a Raspberry Pi computer.
Which stocks to display?
Rather than a static list of S&P or DOW companies, the list of stocks should ideally be dynamic based on what is happening on any given day. There are a handful of free stock APIs available at the time of this blog post, but a listing of market movers seemed to be mostly a paid product feature.
Shout out to iexcloud.io for providing a free tier to their API. If you take a look at their docs and you'll see a very extensive product with a ton of great features. At this point however, the only data I need is a list of most active tickers. https://iexcloud.io/docs/api/#list
Given that the IEX Cloud free tier has a monthly message limit, the next challenge is to come up with a way to update price data frequently without exceeding said message limit. For this market data, I selected a C# wrapper for Yahoo Finance (see github project).
Mash it up!
Step 1: Get the list of tickers from IEX Cloud, but only every X hours.
Step 2: Update price data each request, using the Yahoo Finance wrapper.
[OutputCache(Duration = 10 * 60, Location = System.Web.UI.OutputCacheLocation.Server)]
public ActionResult Quote()
{
//get most active tickers from IEX, but only pull when needed (every 2 hrs max)
List<Quote> quotes = FetchQuotesFromIEX(cacheHours:2);
//update price data every request
UpdateQuotesFromYahoo(quotes);
return Json(quotes, JsonRequestBehavior.AllowGet);
}
FetchQuotesFromIEX:
private static List<Quote> FetchQuotesFromIEX(int cacheHours=2)
{
if (_iexQuotes == null || _iexQuotes.CacheUntil < DateTime.Now)
{
List<Quote> quotes = new List<Quote>();
var mostActive = @"https://cloud.iexapis.com/stable/stock/market/list/mostactive?token=[get your own API token]&listLimit=100&displayPercent=true";
var result = new WebClient().DownloadString(mostActive);
JArray data = JArray.Parse(result);
foreach (var q in data)
{
quotes.Add(new Models.Quote()
{
Ticker = q["symbol"].ToString(),
Price = string.Format("{0:C}", q["latestPrice"]),
Name = q["companyName"].ToString(),
Change = Convert.ToDouble(q["change"]),
ChangePercent = Math.Round(Convert.ToDouble(q["changePercent"]), 2)
});
}
_iexQuotes = new QuoteCache() { CacheUntil = DateTime.Now.AddHours(cacheHours), Quotes = quotes };
}
return _iexQuotes.Quotes;
}
UpdateQuotesFromYahoo:
private static void UpdateQuotesFromYahoo(List<Quote> quotes)
{
var ydata = YahooFinanceApi.Yahoo.Symbols(quotes.Select(q => q.Ticker).ToArray());
var ySymbols = ydata.QueryAsync().Result;
foreach (YahooFinanceApi.Security s in ySymbols.Values)
{
try
{
var q = quotes.FirstOrDefault(t => t.Ticker == s.Symbol);
if (q != null)
{
q.Price = string.Format("{0:C}", s.RegularMarketPrice);
q.Change = Math.Round(s.RegularMarketChange, 2);
q.ChangePercent = Math.Round(s.RegularMarketChangePercent, 2);
}
}
catch
{
//don't update this symbol
}
}
}
Display it!
Using CSS only animations, I came up with a couple different iterations of displaying these stock tickers. Horizontal scrolling (link) and a full page vertical scroller.
The option I think will work best for use in a classroom is the full page vertical with charts (link).
As you can see from the page, I have added a stock chart to make the UI more interesting for the students. The images used in my page are ones offered by finviz.com. Finviz is an awesome resource I use for screening stocks.
I plan on doing a follow-up post on how to get the Raspberry Pi to boot up and display this page automatically.