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);
}