Wednesday, November 7, 2012

Yahoo Data Download

Stock data can be downloaded from http://finance.yahoo.com/d/quotes.csv?s=[stock symbol string]&f=[special tags]. Some tags are listed in the table at the end of the post, but that's not the point. I'll be using a static url for a code example, such as http://download.finance.yahoo.com/d/quotes.csv?s=GOOG+AAPL+MSFT+YHOO&f=snd1l1t1vb3b2hg which will return values for Symbol, Name, Last trade date, Last trade (price only), Last trade time, Volume, Bid (real-time), Ask (real-time), Day's High and Day's Low.

The plan is to have a list of symbols (configurable), to get the data from yahoo and dynamically load the data into the WebGrid control. Therefore, I started with the basic ViewModel that has two sets of entities - one for the symbols and one for the data itself. Eventually the list of symbols will be made configurable.

//ViewModel
public class YahooViewModel
{
 public List<YahooData> Datas { get; set; }
 public List<YahooSymbol> Symbols { get; set; }
 public YahooSymbol Symbol { get; set; }
 public int YahooSymbolID { get; set; }

 public YahooViewModel(int symbolid, YahooSymbol symbol, List<YahooSymbol> symbols, List<YahooData> datas)
 {
  Symbol = symbol;
  YahooSymbolID = symbolid;
  Symbols = symbols;
  Datas = datas;
 }
}

The controller requests and populates the data, and later the automatic authentication may be added as described in the previous post.

//Controller
public ActionResult Index()
{
 List<YahooData> datas = GetData();
 List<YahooSymbol> symbols = db.YahooSymbols.ToList();
 YahooSymbol symbol = symbols.First();
 int id = symbol.YahooSymbolID;
 return View(new YahooViewModel(id, symbol, symbols, datas));
}

public List<YahooData> GetData()
{
 List<YahooData> datas = new List<YahooData>();

 HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://download.finance.yahoo.com/d/quotes.csv?s=GOOG+AAPL+MSFT+YHOO&f=snd1l1t1vb3b2hg");
 HttpWebResponse resp = (HttpWebResponse)req.GetResponse();

 using (StreamReader streamReader = new StreamReader(resp.GetResponseStream()))
 {
  string t = streamReader.ReadToEnd();
  string[] strings = t.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
  datas = InsertData(strings);
 }
 return datas;
}

private List<YahooData> InsertData(string[] lines)
{
 List<YahooData> datas = new List<YahooData>();

 foreach (string line in lines)
 {
  if (!String.IsNullOrEmpty(line))
  {
   YahooData datum = GetDatum(line);
   datas.Add(datum);
  }
 }
 return datas;
}

private YahooData GetDatum(string line)
{
 var datum = new YahooData();
 string[] splitLine = line.Split(',');
 datum = new YahooData()
 {
  DataName = splitLine[1].Replace("\"", ""),
  Date = DateTime.ParseExact(splitLine[2].Replace("\"", ""), "MM/d/yyyy", CultureInfo.InvariantCulture),
  LTP = decimal.Parse(splitLine[3]),
  Time = DateTime.Parse(splitLine[4].Replace("\"", "")),
  Volume = decimal.Parse(splitLine[5]),
  Ask = decimal.Parse(splitLine[6]),
  Bid = decimal.Parse(splitLine[7]),
  High = decimal.Parse(splitLine[8]),
  Low = decimal.Parse(splitLine[9])
 };
 return datum;
}

The symbols are seeded initially, and may be later made configurable.

//Seeding database with initial values
public class SampleData : DropCreateDatabaseIfModelChanges<RecipesEntities>
{
 protected override void Seed(RecipesEntities context)
 {
  AddSymbols(context);
 }
}

public static void AddSymbols(RecipesEntities context)
{
 List<YahooSymbol> symbols = new List<YahooSymbol>
 {
  new YahooSymbol {YahooSymbolID = 1, YahooSymbolName = "GOOG"},
  new YahooSymbol {YahooSymbolID = 2, YahooSymbolName = "AAPL"},
  new YahooSymbol {YahooSymbolID = 3, YahooSymbolName = "MSFT"},
  new YahooSymbol {YahooSymbolID = 4, YahooSymbolName = "YHOO"}
 };

 symbols.ForEach(p => context.YahooSymbols.Add(p));
 context.SaveChanges();
}

Finally, the table of tags and their meanings - just for the interest.

a Ask a2 Average Daily Volume a5 Ask Size
b Bid b2 Ask (Real-time) b3 Bid (Real-time)
b4 Book Value b6 Bid Size c Change & Percent Change
c1 Change c3 Commission c6 Change (Real-time)
c8 After Hours Change (Real-time) d Dividend/Share d1 Last Trade Date
d2 Trade Date e Earnings/Share e1 Error Indication (returned for symbol changed / invalid)
e7 EPS Estimate Current Year e8 EPS Estimate Next Year e9 EPS Estimate Next Quarter
f6 Float Shares g Day's Low h Day's High
j 52-week Low k 52-week High g1 Holdings Gain Percent
g3 Annualized Gain g4 Holdings Gain g5 Holdings Gain Percent (Real-time)
g6 Holdings Gain (Real-time) i More Info i5 Order Book (Real-time)
j1 Market Capitalization j3 Market Cap (Real-time) j4 EBITDA
j5 Change From 52-week Low j6 Percent Change From 52-week Low k1 Last Trade (Real-time) With Time
k2 Change Percent (Real-time) k3 Last Trade Size k4 Change From 52-week High
k5 Percebt Change From 52-week High l Last Trade (With Time) l1 Last Trade (Price Only)
l2 High Limit l3 Low Limit m Day's Range
m2 Day's Range (Real-time) m3 50-day Moving Average m4 200-day Moving Average
m5 Change From 200-day Moving Average m6 Percent Change From 200-day Moving Average m7 Change From 50-day Moving Average
m8 Percent Change From 50-day Moving Average n Name n4 Notes
o Open p Previous Close p1 Price Paid
p2 Change in Percent p5 Price/Sales p6 Price/Book
q Ex-Dividend Date r P/E Ratio r1 Dividend Pay Date
r2 P/E Ratio (Real-time) r5 PEG Ratio r6 Price/EPS Estimate Current Year
r7 Price/EPS Estimate Next Year s Symbol s1 Shares Owned
s7 Short Ratio t1 Last Trade Time t6 Trade Links
t7 Ticker Trend t8 1 yr Target Price v Volume
v1 Holdings Value v7 Holdings Value (Real-time) w 52-week Range
w1 Day's Value Change w4 Day's Value Change (Real-time) x Stock Exchange
y Dividend Yield
by . Also posted on my website

1 comment:

dudette said...

Great code - what is the trade date format? how do you specify d2.

Thanks!!