diff --git a/invest-applet/data/prefs-dialog.ui b/invest-applet/data/prefs-dialog.ui
index db12c24..0beee9a 100644
--- a/invest-applet/data/prefs-dialog.ui
+++ b/invest-applet/data/prefs-dialog.ui
@@ -58,6 +58,7 @@
                 <child>
                   <object class="GtkAlignment" id="alignment16">
                     <property name="visible">True</property>
+                    <property name="bottom_padding">18</property>
                     <property name="left_padding">18</property>
                     <child>
                       <object class="GtkVBox" id="vbox156">
@@ -140,6 +141,40 @@
                     <property name="position">2</property>
                   </packing>
                 </child>
+                <child>
+                  <object class="GtkLabel" id="currencylabel">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">Currency</property>
+                    <property name="use_underline">True</property>
+                    <property name="justify">center</property>
+                    <attributes>
+                      <attribute name="weight" value="bold"/>
+                    </attributes>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">3</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkAlignment" id="alignment1">
+                    <property name="visible">True</property>
+                    <property name="left_padding">18</property>
+                    <child>
+                      <object class="GtkEntry" id="currency">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="invisible_char">&#x25CF;</property>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="position">4</property>
+                  </packing>
+                </child>
               </object>
               <packing>
                 <property name="padding">6</property>
diff --git a/invest-applet/invest/Makefile.am b/invest-applet/invest/Makefile.am
index 308149c..ede7a61 100644
--- a/invest-applet/invest/Makefile.am
+++ b/invest-applet/invest/Makefile.am
@@ -11,6 +11,7 @@ invest_PYTHON = \
 	about.py \
 	applet.py \
 	chart.py \
+	currencies.py \
 	widgets.py \
 	quotes.py \
 	networkmanager.py \
diff --git a/invest-applet/invest/__init__.py b/invest-applet/invest/__init__.py
index 63cc9dd..a02bd33 100644
--- a/invest-applet/invest/__init__.py
+++ b/invest-applet/invest/__init__.py
@@ -67,8 +67,8 @@ GCONF_DIR = "/apps/invest"
 # Preload gconf directories
 #GCONF_CLIENT.add_dir(GCONF_DIR, gconf.CLIENT_PRELOAD_RECURSIVE)
 
-# tests whether the given stocks are in the old format
-def old_stock_format(stocks):
+# tests whether the given stocks are in the old labelless format
+def labelless_stock_format(stocks):
 	if len(stocks) == 0:
 		return False
 
@@ -79,8 +79,8 @@ def old_stock_format(stocks):
 	# there is no list, so it is already the new stock file format
 	return False
 
-# converts the given stocks from the old format into the new one
-def update_stock_format(stocks):
+# converts the given stocks from the labelless format into the one with labels
+def update_to_labeled_stock_format(stocks):
 	new = {}
 
 	for k, l in stocks.items():
@@ -89,15 +89,43 @@ def update_stock_format(stocks):
 
 	return new
 
+# tests whether the given stocks are in the format without exchange information
+def exchangeless_stock_format(stocks):
+	if len(stocks) == 0:
+		return False
+
+	# take the first element of the dict and check if its value is a list
+	for symbol, data in stocks.items():
+		purchases = stocks[symbol]["purchases"]
+		if len(purchases) > 0:
+			purchase = purchases[0]
+			if not purchase.has_key("exchange"):
+				return True
+
+	return False
+
+# converts the given stocks into format with exchange information
+def update_to_exchange_stock_format(stocks):
+	for symbol, data in stocks.items():
+		purchases = data["purchases"]
+		for purchase in purchases:
+			purchase["exchange"] = 0
+
+	return stocks
+
 STOCKS_FILE = join(USER_INVEST_DIR, "stocks.pickle")
 
 try:
 	STOCKS = cPickle.load(file(STOCKS_FILE))
 
-	# if the stocks file is in the old stocks format,
-	# then we need to convert it into the new format
-	if old_stock_format(STOCKS):
-		STOCKS = update_stock_format(STOCKS);
+	# if the stocks file is in the stocks format without labels,
+	# then we need to convert it into the new labeled format
+	if labelless_stock_format(STOCKS):
+		STOCKS = update_to_labeled_stock_format(STOCKS);
+
+	# if the stocks file does not contain exchange rates, add them
+	if exchangeless_stock_format(STOCKS):
+		STOCKS = update_to_exchange_stock_format(STOCKS);
 except Exception, msg:
 	error("Could not load the stocks from %s: %s" % (STOCKS_FILE, msg) )
 	STOCKS = {}
@@ -120,6 +148,12 @@ except Exception, msg:
 #	},
 #}
 
+CONFIG_FILE = join(USER_INVEST_DIR, "config.pickle")
+try:
+	CONFIG = cPickle.load(file(CONFIG_FILE))
+except Exception, msg:
+	CONFIG = {}       # default configuration
+
 client = gconf.client_get_default()
 
 # borrowed from Ross Burton
diff --git a/invest-applet/invest/currencies.py b/invest-applet/invest/currencies.py
new file mode 100644
index 0000000..0eaa075
--- /dev/null
+++ b/invest-applet/invest/currencies.py
@@ -0,0 +1,145 @@
+class Currencies:
+	currencies = {
+		"BZD" : "Belize Dollar",
+		"NLG" : "Dutch Guilder",
+		"SLL" : "Sierra Leone Leone",
+		"FRF" : "French Franc",
+		"NGN" : "Nigerian Naira",
+		"CRC" : "Costa Rican Colon",
+		"LAK" : "Laos Kip",
+		"CLP" : "Chilean Peso",
+		"DZD" : "Algerian Dinar",
+		"SZL" : "Swaziland Lilangeni",
+		"MUR" : "Mauritius Rupee",
+		"WST" : "Western Samoa Tala",
+		"MMK" : "Myanmar Kyat",
+		"IDR" : "Indonesian Rupiah",
+		"GTQ" : "Guatemala Quetzal",
+		"CAD" : "Canadian Dollar",
+		"AWG" : "Aruban Florin",
+		"TTD" : "Trinidad Dollar",
+		"PKR" : "Pakistani Rupee",
+		"XCD" : "East Caribbean Dollar",
+		"VUV" : "Vanuatu Vatu",
+		"XOF" : "CFA Franc (BCEAO)",
+		"ROL" : "Romanian Leu",
+		"KMF" : "Comoros Franc",
+		"SIT" : "Slovenian Tolar",
+		"VEB" : "Venezuelan Bolivar",
+		"ANG" : "Netherlands Antilles Guilder",
+		"MNT" : "Mongolian Tugrik",
+		"LBP" : "Lebanese Pound",
+		"KES" : "Kenyan Shilling",
+		"BTN" : "Bhutan Ngultrum",
+		"GBP" : "British Pound",
+		"SEK" : "Swedish Krona",
+		"ZMK" : "Zambia Kwacha",
+		"SKK" : "Slovak Koruna",
+		"DKK" : "Danish Krone",
+		"AFA" : "Afganistan Afghani",
+		"CYP" : "Cypriot Pound",
+		"SCR" : "Seychelles Rupee",
+		"FJD" : "Fiji Dollar",
+		"SRG" : "Surinam Guilder",
+		"SHP" : "St. Helena Pound",
+		"ALL" : "Albanian Lek",
+		"TOP" : "Tonga Isl Pa'anga",
+		"UGX" : "Ugandan Shilling",
+		"OMR" : "Oman Rial",
+		"DJF" : "Djibouti Franc",
+		"BND" : "Brunei Dollar",
+		"TND" : "Tunisian Dinar",
+		"PTE" : "Portuguese Escudo",
+		"IEP" : "Irish Punt",
+		"SBD" : "Salomon Islands Dollar",
+		"GNF" : "Guinea Franc",
+		"BOB" : "Bolivian Boliviano",
+		"CVE" : "Cape Verde Escudo",
+		"ARS" : "Argentinian Peso",
+		"GMD" : "Gambia Dalasi",
+		"ZWD" : "Zimbabwean Dollar",
+		"MWK" : "Malawi Kwacha",
+		"BDT" : "Bangladesh Taka",
+		"GRD" : "Greek Drachma",
+		"KWD" : "Kuwaiti Dinar",
+		"EUR" : "Euro",
+		"TRL" : "Turkish Lira",
+		"CHF" : "Swiss Franc",
+		"DOP" : "Dominican Peso",
+		"PEN" : "Peruvian Sol",
+		"SVC" : "El Salvador Colon",
+		"SGD" : "Singapore Dollar",
+		"TWD" : "Taiwan New Dollar",
+		"USD" : "US Dollar",
+		"BGN" : "Bulgarian Lev",
+		"MAD" : "Moroccan Dirham",
+		"SAR" : "Saudi Arabian Riyal",
+		"AUD" : "Australian Dollar",
+		"KYD" : "Cayman Islands Dollar",
+		"GHC" : "Ghanaian Cedi",
+		"KRW" : "South Korean Won",
+		"GIP" : "Gibraltar Pound",
+		"NAD" : "Namibian Dollar",
+		"CZK" : "Czech Koruna",
+		"JMD" : "Jamaican Dollar",
+		"MXN" : "Mexican Peso",
+		"BWP" : "Botswana Pula",
+		"GYD" : "Guyana Dollar",
+		"EGP" : "Egyptian Pound",
+		"THB" : "Thai Baht",
+		"AED" : "United Arab Emirates Dirham",
+		"JPY" : "Japanese Yen",
+		"JOD" : "Jordanian Dinar",
+		"HRK" : "Croatian Kuna",
+		"ZAR" : "South African Rand",
+		"CUP" : "Cuban Peso",
+		"BBD" : "Barbados Dollar",
+		"PGK" : "Papua New Guinea Kina",
+		"LKR" : "Sri Lanka Rupee",
+		"BEF" : "Belgian Franc",
+		"PLN" : "Polish Zloty",
+		"MYR" : "Malaysian Ringgit",
+		"FIM" : "Finnish Markka",
+		"CNY" : "Renmimbi Yuan",
+		"SDD" : "Sudanese Dinar",
+		"LVL" : "Latvian Lats",
+		"ITL" : "Italian Lira",
+		"INR" : "Indian Rupee",
+		"NIO" : "Nicaraguan Cordoba",
+		"PHP" : "Philippines Peso",
+		"HNL" : "Honduras Lempira",
+		"HKD" : "Hong Kong Dollar",
+		"NZD" : "New Zealand Dollar",
+		"BRL" : "Brazilian Real",
+		"MTL" : "Maltese Pound",
+		"ATS" : "Austrian Schilling",
+		"EEK" : "Estonian Kroon",
+		"NOK" : "Norwegian Krone",
+		"ISK" : "Iceland Krona",
+		"ILS" : "Israeli Shekel",
+		"LSL" : "Lesotho Loti",
+		"HUF" : "Hungarian Forint",
+		"ESP" : "Spanish Peseta",
+		"UAH" : "Ukraine Hryvnia",
+		"RUB" : "Russian Ruble",
+		"BMD" : "Bermuda Dollar",
+		"MVR" : "Maldives Rufiyan",
+		"QAR" : "Qatari Rial",
+		"VND" : "Vietnam Dong",
+		"MRO" : "Mauritania Ouguiya",
+		"MZM" : "Mozambique Metical",
+		"NPR" : "Nepal Rupee",
+		"COP" : "Colombian Peso",
+		"TZS" : "Tanzanian Shilling",
+		"MGF" : "Malagasy Franc",
+		"KHR" : "Cambodian Riel",
+		"SYP" : "Syria Pound",
+		"HTG" : "Haitian Gourde",
+		"DEM" : "German Mark",
+		"BHD" : "Bahraini Dinar",
+		"XAF" : "CFA Franc(BEAC)",
+		"STD" : "Sao Tome & Principe Dobra",
+		"LTL" : "Lithuanian Litas",
+		"ETB" : "Ethiopian Birr",
+		"XPF" : "CFP Franc",
+}
diff --git a/invest-applet/invest/preferences.py b/invest-applet/invest/preferences.py
index 65d83dc..9401590 100644
--- a/invest-applet/invest/preferences.py
+++ b/invest-applet/invest/preferences.py
@@ -2,6 +2,7 @@ from gettext import gettext as _
 from os.path import join
 import gtk, gobject, gconf
 import invest
+import currencies
 from gettext import gettext as _
 
 import cPickle
@@ -13,59 +14,60 @@ class PrefsDialog:
 
 		self.dialog = self.ui.get_object("preferences")
 		self.treeview = self.ui.get_object("stocks")
+		self.currency = self.ui.get_object("currency")
+		self.currency_code = None
+		self.currencies = currencies.Currencies.currencies
 
 		self.ui.get_object("add").connect('clicked', self.on_add_stock)
 		self.ui.get_object("add").connect('activate', self.on_add_stock)
 		self.ui.get_object("remove").connect('clicked', self.on_remove_stock)
 		self.ui.get_object("remove").connect('activate', self.on_remove_stock)
 		self.treeview.connect('key-press-event', self.on_tree_keypress)
+		self.currency.connect('key-press-event', self.on_entry_keypress)
+		self.currency.connect('activate', self.on_activate_entry)
+		self.currency.connect('focus-out-event', self.on_focus_out_entry)
 
-		self.typs = (str, str, float, float, float)
-		self.names = (_("Symbol"), _("Label"), _("Amount"), _("Price"), _("Commission"))
+		self.typs = (str, str, float, float, float, float)
+		self.names = (_("Symbol"), _("Label"), _("Amount"), _("Price"), _("Commission"), _("Currency Rate"))
 		store = gtk.ListStore(*self.typs)
 		store.set_sort_column_id(0, gtk.SORT_ASCENDING)
 		self.treeview.set_model(store)
 		self.model = store
 
-		def on_cell_edited(cell, path, new_text, col, typ):
-			try:
-				if col == 0:    # stock symbols must be uppercase
-					new_text = str.upper(new_text)
-				store[path][col] = typ(new_text)
-			except:
-				pass
-
-		def get_cell_data(column, cell, model, iter, data):
-			typ, col = data
-			if typ == int:
-				cell.set_property('text', "%d" % typ(model[iter][col]))
-			elif typ == float:
-				cell.set_property('text', "%.2f" % typ(model[iter][col]))
-			else:
-				cell.set_property('text', typ(model[iter][col]))
-
-		def create_cell (view, column, name, typ):
-			cell_description = gtk.CellRendererText ()
-			cell_description.set_property("editable", True)
-			cell_description.connect("edited", on_cell_edited, column, typ)
-			column_description = gtk.TreeViewColumn (name, cell_description)
-			if typ == str:
-				column_description.set_attributes (cell_description, text=column)
-				column_description.set_sort_column_id(column)
-			if typ == float:
-				column_description.set_cell_data_func(cell_description, get_cell_data, (float, column))
-			view.append_column(column_description)
+		completion = gtk.EntryCompletion()
+		self.currency.set_completion(completion)
+		liststore = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
+		completion.set_model(liststore)
+		completion.set_text_column(0)
+		for code, label in self.currencies.items():
+			liststore.append([self.format_currency(label, code), code])
 
+		completion.set_match_func(self.match_func, 0)
+		completion.connect("match-selected", self.on_completion_selection, 1)
+
+		if invest.CONFIG.has_key("currency"):
+			code = invest.CONFIG["currency"];
+			if self.currencies.has_key(code):
+				self.currency_code = code;
+				currency = self.format_currency(self.currencies[self.currency_code], self.currency_code)
+				self.currency.set_text(currency)
 
 		for n in xrange (0, 5):
-			create_cell (self.treeview, n, self.names[n], self.typs[n])		
+			self.create_cell (self.treeview, n, self.names[n], self.typs[n])
+		if self.currency_code != None:
+			self.add_exchange_column()
+
 		stock_items = invest.STOCKS.items ()
 		stock_items.sort ()
 		for key, data in stock_items:
 			label = data["label"]
 			purchases = data["purchases"]
 			for purchase in purchases:
-				store.append([key, label, purchase["amount"], purchase["bought"], purchase["comission"]])
+				if purchase.has_key("exchange"):
+					exchange =  purchase["exchange"]
+				else:
+					exchange = 0.0
+				store.append([key, label, purchase["amount"], purchase["bought"], purchase["comission"], exchange])
 
 		try:
 			pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(join(invest.ART_DATA_DIR, "invest-16.png"), -1,-1)
@@ -76,6 +78,42 @@ class PrefsDialog:
 
 		self.sync_ui()
 
+	def on_cell_edited(self, cell, path, new_text, col, typ):
+		try:
+			if col == 0:    # stock symbols must be uppercase
+				new_text = str.upper(new_text)
+			self.model[path][col] = typ(new_text)
+		except:
+			pass
+
+	def get_cell_data(self, column, cell, model, iter, data):
+		typ, col = data
+		if typ == int:
+			cell.set_property('text', "%d" % typ(model[iter][col]))
+		elif typ == float:
+			cell.set_property('text', "%.2f" % typ(model[iter][col]))
+		else:
+			cell.set_property('text', typ(model[iter][col]))
+
+	def create_cell (self, view, column, name, typ):
+		cell_description = gtk.CellRendererText ()
+		cell_description.set_property("editable", True)
+		cell_description.connect("edited", self.on_cell_edited, column, typ)
+		column_description = gtk.TreeViewColumn (name, cell_description)
+		if typ == str:
+			column_description.set_attributes (cell_description, text=column)
+			column_description.set_sort_column_id(column)
+		if typ == float:
+			column_description.set_cell_data_func(cell_description, self.get_cell_data, (float, column))
+		view.append_column(column_description)
+
+	def add_exchange_column(self):
+		self.create_cell (self.treeview, 5, self.names[5], self.typs[5])
+
+	def remove_exchange_column(self):
+		column = self.treeview.get_column(5)
+		self.treeview.remove_column(column)
+
 	def show_run_hide(self, explanation = ""):
 		expl = self.ui.get_object("explanation")
 		expl.set_markup(explanation)
@@ -98,6 +136,7 @@ class PrefsDialog:
 				"amount": float(model[iter][2]),
 				"bought": float(model[iter][3]),
 				"comission": float(model[iter][4]),
+				"exchange": float(model[iter][5])
 			})
 		self.model.foreach(save_symbol)
 		try:
@@ -106,12 +145,20 @@ class PrefsDialog:
 		except Exception, msg:
 			invest.error('Could not save stocks file: %s' % msg)
 
+		invest.CONFIG = {}
+		if self.currency_code != None and len(self.currency_code) == 3:
+			invest.CONFIG['currency'] = self.currency_code
+		try:
+			cPickle.dump(invest.CONFIG, file(invest.CONFIG_FILE, 'w'))
+			invest.debug('Configuration written to file')
+		except Exception, msg:
+			invest.debug('Could not save configuration file: %s' % msg)
 
 	def sync_ui(self):
 		pass
 
 	def on_add_stock(self, w):
-		iter = self.model.append(["GOOG", "Google Inc.", 0, 0, 0])
+		iter = self.model.append(["GOOG", "Google Inc.", 0, 0, 0, 0])
 		path = self.model.get_path(iter)
 		self.treeview.set_cursor(path, self.treeview.get_column(0), True)
 
@@ -126,5 +173,97 @@ class PrefsDialog:
 
 		return False
 
+	def format_currency(self, label, code):
+		if code == None:
+			return label
+		return label + " (" + code + ")"
+
+	def on_entry_keypress(self, w, event):
+		# enter key was pressed
+		if event.keyval == 65293:
+			self.match_currency()
+		return False
+
+	# entry was activated (Enter)
+	def on_activate_entry(self, entry):
+		self.match_currency()
+
+	# entry left focus
+	def on_focus_out_entry(self, w, event):
+		self.match_currency()
+		return False
+
+	# tries to find a currency for the text in the currency entry
+	def match_currency(self):
+		# get the text
+		text = self.currency.get_text().upper()
+
+		# if there is none, finish
+		if len(text) == 0:
+			self.currency_code = None
+			self.pick_currency(None)
+			return
+
+		# if it is a currency code, take that one
+		if len(text) == 3:
+			# try to find the string as code
+			if self.currencies.has_key(text):
+				self.pick_currency(text)
+				return
+		else:
+			# try to find the code for the string
+			for code, label in self.currencies.items():
+				# if the entry equals to the full label,
+				# or the entry equals to the label+code concat
+				if label.upper() == text or self.format_currency(label.upper(), code) == text:
+					# then we take that code
+					self.pick_currency(code)
+					return
+
+		# the entry is not valid, reuse the old one
+		self.pick_currency(self.currency_code)
+
+	# pick this currency, stores it and sets the entry text
+	def pick_currency(self, code):
+		if code == None:
+			label = ""
+			if len(self.treeview.get_columns()) == 6:
+				self.remove_exchange_column()
+		else:
+			label = self.currencies[code]
+			if len(self.treeview.get_columns()) == 5:
+				self.add_exchange_column()
+		self.currency.set_text(self.format_currency(label, code))
+		self.currency_code = code
+
+	# finds matches by testing candidate strings to have tokens starting with the entered text's tokens
+	def match_func(self, completion, key, iter, column):
+		keys = key.split()
+		model = completion.get_model()
+		text = model.get_value(iter, column).lower()
+		tokens = text.split()
+
+		# each key must have a match
+		for key in keys:
+			found_key = False
+			# check any token of the completions start with the key
+			for token in tokens:
+				# remove the ( from the currency code
+				if token.startswith("("):
+					token = token[1:]
+				if token.startswith(key):
+					found_key = True
+					break
+			# this key does not have a match, this is not a completion
+			if not found_key:
+				return False
+		# all keys matched, this is a completion
+		return True
+
+	# stores the selected currency code
+	def on_completion_selection(self, completion, model, iter, column):
+		self.pick_currency(model.get_value(iter, column))
+
+
 def show_preferences(applet, explanation = ""):
 	PrefsDialog(applet).show_run_hide(explanation)
diff --git a/invest-applet/invest/quotes.py b/invest-applet/invest/quotes.py
index 3f1a096..6ce578d 100644
--- a/invest-applet/invest/quotes.py
+++ b/invest-applet/invest/quotes.py
@@ -11,10 +11,10 @@ import invest, invest.about, invest.chart
 CHUNK_SIZE = 512*1024 # 512 kB
 AUTOREFRESH_TIMEOUT = 15*60*1000 # 15 minutes
 
-QUOTES_URL="http://finance.yahoo.com/d/quotes.csv?s=%(s)s&f=sl1d1t1c1ohgv&e=.csv"
+QUOTES_URL="http://finance.yahoo.com/d/quotes.csv?s=%(s)s&f=snc4l1d1t1c1ohgv&e=.csv"
 
-# Sample (25/4/2008): UCG.MI,"4,86",09:37:00,2008/04/25,"0,07","4,82","4,87","4,82",11192336
-QUOTES_CSV_FIELDS=["ticker", ("trade", float), "time", "date", ("variation", float), ("open", float)]
+# Sample (09/2/2010): "UCG.MI","UNICREDIT","EUR","UCG.MI",1.9410,"2/9/2010","6:10am",+0.0210,1.9080,1.9810,1.8920,166691232
+QUOTES_CSV_FIELDS=["ticker", "label", "currency", ("trade", float), "date", "time", ("variation", float), ("open", float), ("high", float), ("low", float), ("volume", int)]
 
 # based on http://www.johnstowers.co.nz/blog/index.php/2007/03/12/threading-and-pygtk/
 class _IdleObject(gobject.GObject):
@@ -48,6 +48,7 @@ class QuotesRetriever(Thread, _IdleObject):
 		self.tickers = tickers
 		self.retrieved = False
 		self.data = []
+		self.currencies = []
 
 	def run(self):
 		quotes_url = QUOTES_URL % {"s": self.tickers}
@@ -67,9 +68,9 @@ class QuoteUpdater(gtk.ListStore):
 	last_updated = None
 	quotes_valid = False
 	timeout_id = None
-	SYMBOL, LABEL, TICKER_ONLY, BALANCE, BALANCE_PCT, VALUE, VARIATION_PCT, PB = range(8)
+	SYMBOL, LABEL, CURRENCY, TICKER_ONLY, BALANCE, BALANCE_PCT, VALUE, VARIATION_PCT, PB = range(9)
 	def __init__ (self, change_icon_callback, set_tooltip_callback):
-		gtk.ListStore.__init__ (self, gobject.TYPE_STRING, gobject.TYPE_STRING, bool, float, float, float, float, gtk.gdk.Pixbuf)
+		gtk.ListStore.__init__ (self, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, bool, float, float, float, float, gtk.gdk.Pixbuf)
 		self.set_update_interval(AUTOREFRESH_TIMEOUT)
 		self.change_icon_callback = change_icon_callback
 		self.set_tooltip_callback = set_tooltip_callback
@@ -135,6 +136,11 @@ class QuoteUpdater(gtk.ListStore):
 			tooltip.append(_('Updated at %s') % self.last_updated.strftime("%H:%M"))
 			self.set_tooltip_callback('\n'.join(tooltip))
 
+	def on_currency_retriever_completed(self, retriever):
+		if retriever.retrieved == False:
+			invest.error("Failed to retrieve currency rates!")
+		else:
+			self.convert_currencies(self.parse_yahoo_csv(csv.reader(retriever.data)))
 
 
 	def parse_yahoo_csv(self, csvreader):
@@ -159,12 +165,47 @@ class QuoteUpdater(gtk.ListStore):
 				result[fields[0]]['variation_pct'] = 0
 		return result
 
+	# Computes the balance of the given purchases using a certain current value
+	# and optionally a current exchange rate.
+	def balance(self, purchases, value, currentrate=None):
+		current = 0
+		paid = 0
+
+		for purchase in purchases:
+			if purchase["amount"] != 0:
+				buyrate = purchase["exchange"]
+				# if the buy rate is invalid, use 1.0
+				if buyrate <= 0:
+					buyrate = 1.0
+
+				# if no current rate is given, ignore buy rate
+				if currentrate == None:
+					buyrate = 1.0
+					rate = 1.0
+				else:
+					# otherwise, take use buy rate and current rate to compute the balance
+					rate = currentrate
+
+				# current value is the current rate * amount * value
+				current += rate * purchase["amount"] * value
+				# paid is buy rate * ( amount * price + commission )
+				paid += buyrate * (purchase["amount"] * purchase["bought"] + purchase["comission"])
+
+		balance = current - paid
+		if paid != 0:
+			change = 100*balance/paid
+		else:
+			change = 100 # Not technically correct, but it will look more intuitive than the real result of infinity.
+
+		return (balance, change)
+
 	def populate(self, quotes):
 		if (len(quotes) == 0):
 			return
 
 		self.clear()
-		
+		self.currencies = []
+
 		try:
 			quote_items = quotes.items ()
 			quote_items.sort ()
@@ -180,7 +221,23 @@ class QuoteUpdater(gtk.ListStore):
 				# get the label of this stock for later reuse
 				label = invest.STOCKS[ticker]["label"]
 				if len(label) == 0:
-					label = ticker
+					if len(val["label"]) != 0:
+						label = val["label"]
+					else:
+						label = ticker
+
+				# the currency of currency conversion rates like EURUSD=X is wrong in csv
+				# this can be fixed easily by reusing the latter currency in the symbol
+				if len(ticker) == 8 and ticker.endswith("=X"):
+					val["currency"] = ticker[3:6]
+
+				# indices should not have a currency, though yahoo says so
+				if ticker.startswith("^"):
+					val["currency"] = ""
+
+				# if this is a currency not yet seen and different from the target currency, memorize it
+				if val["currency"] not in self.currencies and len(val["currency"]) > 0:
+					self.currencies.append(val["currency"])
 
 				# Check whether the symbol is a simple quote, or a portfolio value
 				is_simple_quote = True
@@ -191,18 +248,12 @@ class QuoteUpdater(gtk.ListStore):
 
 				if is_simple_quote:
 					self.simple_quotes_count += 1
-					row = self.insert(0, [ticker, label, True, 0, 0, val["trade"], val["variation_pct"], pb])
+					row = self.insert(0, [ticker, label, val["currency"], True, 0, 0, val["trade"], val["variation_pct"], pb])
 					simple_quotes_change += val['variation_pct']
 				else:
 					self.positions_count += 1
-					current = sum([purchase["amount"]*val["trade"] for purchase in invest.STOCKS[ticker]["purchases"] if purchase["amount"] != 0])
-					paid = sum([purchase["amount"]*purchase["bought"] + purchase["comission"] for purchase in invest.STOCKS[ticker]["purchases"] if purchase["amount"] != 0])
-					balance = current - paid
-					if paid != 0:
-						change = 100*balance/paid
-					else:
-						change = 100 # Not technically correct, but it will look more intuitive than the real result of infinity.
-					row = self.insert(0, [ticker, label, False, balance, change, val["trade"], val["variation_pct"], pb])
+					(balance, change) = self.balance(invest.STOCKS[ticker]["purchases"], val["trade"])
+					row = self.insert(0, [ticker, label, val["currency"], False, balance, change, val["trade"], val["variation_pct"], pb])
 					self.positions_balance += balance
 
 				if len(ticker.split('.')) == 2:
@@ -239,6 +290,67 @@ class QuoteUpdater(gtk.ListStore):
 			invest.debug(quotes)
 			self.quotes_valid = False
 
+		# start retrieving currency conversion rates
+		if invest.CONFIG.has_key("currency"):
+			target_currency = invest.CONFIG["currency"]
+			symbols = []
+
+			invest.debug("These currencies occur: %s" % self.currencies)
+			for currency in self.currencies:
+				if currency == target_currency:
+					continue
+
+				invest.debug("%s will be converted to %s" % ( currency, target_currency ))
+				symbol = currency + target_currency + "=X"
+				symbols.append(symbol)
+
+			if len(symbols) > 0:
+				tickers = '+'.join(symbols)
+				quotes_retriever = QuotesRetriever(tickers)
+				quotes_retriever.connect("completed", self.on_currency_retriever_completed)
+				quotes_retriever.start()
+
+	def convert_currencies(self, quotes):
+		# if there is no target currency, this method should never have been called
+		if not invest.CONFIG.has_key("currency"):
+			return
+
+		# collect the rates for the currencies
+		rates = {}
+		for symbol, data in quotes.items():
+			currency = symbol[0:3]
+			rate = data["trade"]
+			rates[currency] = rate
+
+		# convert all non target currencies
+		target_currency = invest.CONFIG["currency"]
+		iter = self.get_iter_first()
+		while iter != None:
+			currency = self.get_value(iter, self.CURRENCY)
+			symbol = self.get_value(iter, self.SYMBOL)
+			# ignore stocks that are currency conversions
+			# and only convert stocks that are not in the target currency
+			# and if we have a conversion rate
+			if not ( len(symbol) == 8 and symbol[6:8] == "=X" ) and \
+			   currency != target_currency and rates.has_key(currency):
+				# first convert the balance, it needs the original value
+				if not self.get_value(iter, self.TICKER_ONLY):
+					ticker = self.get_value(iter, self.SYMBOL)
+					value = self.get_value(iter, self.VALUE)
+					(balance, change) = self.balance(invest.STOCKS[ticker]["purchases"], value, rates[currency])
+					self.set(iter, self.BALANCE, balance)
+					self.set(iter, self.BALANCE_PCT, change)
+
+				# now, convert the value
+				value = self.get_value(iter, self.VALUE)
+				value *= rates[currency]
+				self.set(iter, self.VALUE, value)
+				self.set(iter, self.CURRENCY, target_currency)
+
+
+			iter = self.iter_next(iter)
+
+
 	def set_pb_callback(self, retriever, row):
 		self.set_value(row, self.PB, retriever.image.get_pixbuf())
 
diff --git a/invest-applet/invest/widgets.py b/invest-applet/invest/widgets.py
index ef1017b..851823f 100644
--- a/invest-applet/invest/widgets.py
+++ b/invest-applet/invest/widgets.py
@@ -57,6 +57,8 @@ class InvestWidget(gtk.TreeView):
 		for i, col_name in enumerate(col_names):
 			if i < 3:
 				cell = gtk.CellRendererText()
+				if i > 0:
+					cell.set_property("xalign", 1.0)
 				column = gtk.TreeViewColumn (col_name, cell)
 				if i == 0:
 					column.set_sort_column_id(quotes_updater.LABEL)
@@ -72,6 +74,7 @@ class InvestWidget(gtk.TreeView):
 				# add the last two column only if we have any positions
 				if simple_quotes_only == False:
 					cell = gtk.CellRendererText()
+					cell.set_property("xalign", 1.0)
 					column = gtk.TreeViewColumn (col_name, cell)
 					if i == 4:
 						column.set_sort_column_id(quotes_updater.BALANCE)
@@ -90,7 +93,7 @@ class InvestWidget(gtk.TreeView):
 		cell.set_property('text', model[iter][model.LABEL])
 
 	def _getcelldata_value(self, column, cell, model, iter):
-		cell.set_property('text', "%.5g" % model[iter][model.VALUE])
+		cell.set_property('text', "%.5g %s" % ( model[iter][model.VALUE], model[iter][model.CURRENCY] ))
 
 	def _getcelldata_variation(self, column, cell, model, iter):
 		color = GREEN
@@ -108,8 +111,8 @@ class InvestWidget(gtk.TreeView):
 			cell.set_property('text', '')
 		else:
 					cell.set_property('markup',
-			"<span foreground='%s'>%+.2f</span>" %
-			(color, model[iter][model.BALANCE]))
+			"<span foreground='%s'>%+.2f %s</span>" %
+			(color, model[iter][model.BALANCE], model[iter][model.CURRENCY]))
 
 	def _getcelldata_balancepct(self, column, cell, model, iter):
 		is_ticker_only = model[iter][model.TICKER_ONLY]
