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 |
1 comment:
Great code - what is the trade date format? how do you specify d2.
Thanks!!
Post a Comment