Many years, especially during international trips, I have used the Yahoo! Finance portal to get fresh foreign exchange rates for my expense reports. I found this site quite useful, especially because the information is free, even though a little bit delayed, but good enough for such goals. Unfortunately, the Yahoo! site doesn't have a version formatted to fit the small screens of mobile devices. That's why I decided to create .NET components that are reusable in WinForms, ASP.NET, and the Compact Framework to cover all my needs. Parsing HTML code is not a trivial task because it doesn't have a strong formatting as XML does. Again, fortunately, Yahoo! duplicates results as a comma-delimited file which is more easy to parse. So, let's look at the code closely.
Walk through the classes
There are two classes -
CurrencyList, and a structure
CurrencyData. All of them are packed into the
This structure represents a pair of currency codes and data coming from the Web Service:
string): get/set three-characters of the base currency code, for example: USD for United States Dollar, EUR for Euro etc.
string): get/set the target currency code, by the same rules as
double): last trade price of Base Currency, specified in the
BaseCode property, calculated in currency units, specified in the
double): they look like Ask and Bid, but values are different between the HTML version on the site and the comma-delimited file I mentioned above; unfortunately, there is no detailed explanation, that's why I named them "Min" and "Max" to avoid confusion with the real "Bid" and "Ask" values.
System.DateTime): last trade Date/Time.
This structure has one constructor:
public CurrencyData(string baseCode, string targetCode)
to create a new structure and set the currency codes.
This is the main class which accesses the Yahoo! service and gets the data through several overloads of the
public CurrencyData GetCurrencyData(string source, string target)
This is the simplest method: just supply the currency codes and get the result in the returned
CurrencyData structure. For example:
CurrencyData cd = myCurrencyConverter.GetCurrencyData("USD", "EUR");
This version gets the currency pair in the supplied
CurrencyData and packs the results back into there:
public void GetCurrencyData(ref CurrencyData data)
Gets the currency pair in the
CurrencyData structure and sets the data properties (
TradeDate) by the given results. Example:
CurrencyData cd = new CurrencyData("EUR", "RUB");
This method is useful to get data for more than one currency pair at the same time:
public void GetCurrencyData(ref IList<CurrencyData> listData);
IList<CurrencyData> currencyList = new List<CurrencyData>();
currencyList.Add(new CurrencyData("USD", "EUR"));
currencyList.Add(new CurrencyData("EUR", "RUR"));
foreach(CurrencyData cd in currencyList)
But before calling these functions, don't forget to set some important properties:
This class contains only static methods, so doesn't need to be created manually before using it. Use this class to get all the supported currencies: get the three-characters codes from the static read only property
public static ReadOnlyCollection Codes and their names from
public static ReadOnlyCollection Descriptions.
Also, it is possible to get the exact code and/or description by its position:
public static string GetCode(int index): return a currency code, for example "USD".
public static string GetDescription(int index): return a currency description (name), for example "U.S. Dollar".
and opposite functions:
public static int GetCodeIndex(string code)
public static int GetDescriptionIndex(string description)
Since both codes and descriptions are unique, it's possible to get a currency code by its description and vice versa:
public static string GetCode(string description)
public static string GetDescription(string code)
Using the code
Finally, a couple of words about using the source code.
Probably the best way to show all the supported currencies either in a WinForms app or an ASP.NET app is
ComboBox objects. As I said above, this list could be taken from the static
CurrencyList class. This task could be done in two different ways:
string currencyDescriptions = new string[CurrencyList.Count];
for(int i = 0; i < CurrencyList.Count; i++)
DropDownListCurrency.Items[i].Value = CurrencyList.Codes[i];
CurrencyConverter cc = new CurrencyConverter();
CurrencyData cd = cc.GetCurrencyData(DropDownListFrom.SelectedValue,
Don't forget to set the
CurrencyData.AdjustToLocalTime property to
true if you want to make adjustments automatically. If your network is behind a proxy, don't forget to create and assign a proxy object before you call
cc.Proxy = new System.Net.WebProxy(proxyAddress, proxyPort);
CurrencyConverter class has several versions of the
GetCurrencyData method, and
GetCurrencyData(ref IList<CurrencyData>) is one of them, you can pass more than one
CurrencyData structure and get data for several currency pairs at the same time. Although this method has no restrictions on the number of currencies you can pass, please remember that some old network routers have a limitation on URL length and can trim everything to below 256 characters.
Here is the demo app screenshot (source code is included with this article):
As a developer, I don't impose any restrictions on using this code, but please remember that Yahoo! services could be under different types of licensing and commercial use could be restricted. So please follow Yahoo! instructions.
Although I said at the beginning that I created these classes to fit to any .NET target, I didn't test this code on the Compact Framework at all, but I promise to return to this article in a couple of weeks and hope will get your opinions during this time to make this code more useful.
- March 7, 2007 - Initial release.