Exchange Rate data
As part of our ongoing efforts at making sense of the Tenders Electronic Daily procurement contracts, I had to get hold of historical exchange rates to convert the values of all the contracts into a comparable form. Professor Werner Antweiler at The University of British Columbia maintains a very impressive, free database of exactly this data. He doesn’t let you export it in (great) bulk unfortunately. I wrote a small script to get the monthly data for the currencies I wanted, the important parts (in C#) are included below. Note that the site may throttle you. Also, please don’t use this to try to scrape all the data and republish it, or in other ways make a fool of yourself.
string url = "http://fx.sauder.ubc.ca/cgi/fxdata"; // this uses Euros as the base currency string requeststring = string.Format( "b=EUR&c={0}&rd=&fd=1&fm=1&fy=2003&ld=31&lm=12&ly=2008&y=monthly&q=volume&f=csv&o=", "YOURCURRENCY"); HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); req.ContentType = "application/x-www-form-urlencoded"; req.Expect = null; req.Method = "Post"; byte[] reqData = Encoding.UTF8.GetBytes(requeststring); req.ContentLength = reqData.Length; Stream reqStream = req.GetRequestStream(); reqStream.Write(reqData, 0, reqData.Length); reqStream.Close(); HttpWebResponse WebResp = (HttpWebResponse)req.GetResponse(); var resp = WebResp.GetResponseStream(); StreamReader answer = new StreamReader(resp); string res = answer.ReadToEnd(); if (res.Contains("Error")) { throw new Exception(string.Format("Bad currency: {0}", curr)); } if (res.Contains("Access")) { // You're being throttled } var lines = res.Split(new char[] { '\n' }); // ignore the first two lines and the last two ones for (int i = 2; i < lines.Length - 2 ; i++) { var line = lines[i]; var vals = line.Split(new char[] { ',' }); // parse the vals var month = GetMonth(vals[0]); var year = GetYear(vals[0]); var rate = decimal.Parse(vals[1], CultureInfo.InvariantCulture); } // Util Methods private static int GetMonth(string s) { var month = s.Substring(1, 3); switch (month) { case "Jan": return 1; case "Feb": return 2; case "Mar": return 3; case "Apr": return 4; case "May": return 5; case "Jun": return 6; case "Jul": return 7; case "Aug": return 8; case "Sep": return 9; case "Oct": return 10; case "Nov": return 11; case "Dec": return 12; default: throw new Exception("crap"); } } private static int GetYear(string s) { var year = s.Substring(5, 4); return int.Parse(year); }