Lately I have spent time on a pet project, which requires access to historical financial data. Mads Kristensen has a nice post where he shows how to read stock quotes from Yahoo finance using C#, which was very helpful to get started. I figured it would be interesting to try out a conversion to F# and see what the result looked like.
Mads focus is on getting quasi real-time updates of a quote; my interest is in an easier problem: retrieving historical data. Fortunately, Yahoo provides a free service for that, too. Given a quote symbol and two dates, it returns a comma-separated file list of all the values for the quote between these 2 dates.
So what do we need to do? Given a valid symbol and 2 dates, we want to create the WebRequest to send to Yahoo, retrieve the response, break it into lines, and parse each line into a quote, which will be added to a list. The core of the resulting program will be the ReadQuotes function, which will look like this:
let ReadQuotes symbol date1 date2 =
CreateRequest symbol date1 date2
|> GetResponse
|> BreakIntoLines
|> CreateQuotes symbol
Creating the WebRequest
The web request required to obtain historical data from Yahoo follows this pattern:
http://ichart.finance.yahoo.com/table.csv?s=S&a=A&b=B&c=C&d=D&e=E&f=F&g=d&ignore=.csv
where:
- S is the symbol (ex: MSFT)
- A, B, C are the start month, day and year, the month being coded in base 0 (i.e. January is 0)
- D, E, F are the end month, day and year, the month being coded in base 0 (i.e. January is 0)
For instance, replacing S with MSFT, A with 0, B with 1, C with 2010, D with 1, E with 15, F with 2010, will return all the available quotes for Microsoft between January 1 and February 15, 2010.
Let’s start by creating a Console application, by selecting new F# project > F# Application, and typing in the following code:
open System;
open System.Net
open System.IO
open System.Text
let RetrieveDateInfo (date:DateTime) =
(date.Day, date.Month-1, date.Year)
let CreateRequest symbol startDate endDate =
let startDay, startMonth, startYear = RetrieveDateInfo startDate
let endDay, endMonth, endYear = RetrieveDateInfo endDate
let query = String.Format("&a={0}&b={1}&c={2}&d={3}&e={4}&f={5}&g=d&ignore=.csv", startMonth, startDay, startYear, endMonth, endDay, endYear)
let url = "http://ichart.finance.yahoo.com/table.csv?s=" + symbol + query
WebRequest.Create(url)
More...