QuantLib: Currencies

Currency Basics

In order to represent an amount of money one could, in principle, just store the amount in a variable of type Real. This is OK as long as you are dealing with just a single currency and you know all the conventions associated with that currency. But what happens when you are dealing with different currencies and you want to convert between them, or you just want to print currency amounts in human readable form.

The class Currency is the base class for defining currencies and providing the relevant information. It is defined in the file currency.hpp. Currency is designed to have value semantics. This means you can assign an instance of a derived class to an instance of Currency (not a pointer or reference to Currency) without losing information.

Currency currency;
USDCurrency usd;
currency = usd;

In this example the currency object will hold all the information provided by the USDCurrency class.


The following methods are provided by Currency.

const std::string& name() const;

The name method returns a string containing the name of the currency in human readable form. This could be “U. S. Dollar” or “Euro”.

const std::string& code() const;

Returns the ISO4217 three letter currency code in a string. This could be “USD” or “EUR”.

Integer numericCode() const;

Returns the ISO4217 numeric currency code in a string. This could be “USD” or “EUR”.

const std::string& symbol() const;

Returns the currency symbol if available. This could be “$” or “£”. Support for this feature is not consistent and many currency symbols remain undefined such as the “€” symbol for EURCurrency.

const std::string& fractionSymbol() const;

Returns the symbol of the fractionary part of the currency, if available. This could be “¢” or “p”. As with the symbol() method, support is not consistent and, for example the simple ‘c’ for Euro cent is not provided.

Integer fractionsPerUnit() const;

Returns the number of fractionary parts of the currency in the base unit of the currency. This returns 100 for most currencies.

Rounding rounding() const;

Returns the rounding convention for this currency. Rounding will be talked about in another article.

const std::string& format() const;

Returns a format string that can be used in a … statement. The format string contains three positional parameters for value, code, and symbol in that order.

bool empty() const;

This is a method that returns false if the object holds valid information on a currency and true otherwise. Currency objects which are initialised only through the constructor of the base class Currency and which have not been assigned a valid currency are empty and hold no information.

Currency c1;
GBPCurrency c2;
Currency c3 = USDCurrency();
Currency c4 = c2;
bool e1, e2, e3, e4;
e1 = c1.empty();
e2 = c2.empty();
e3 = c3.empty();
e4 = c4.empty();

In this example e1 is false while e2, e3 and e4 are true.

const Currency& triangulationCurrency() const;

This method returns a currency that is used for triangulated exchange. A valid currency is only returned when required. Not every currency returns a valid currency. Currency exchange will be handled in a later article.

In addition to the methods defined within the Currency class, currencies can also be compared with == and != which is equivalent to a comparison of the three letter ISO4217 currency codes.

Predefined Currencies

QuantLib defines a large number of currencies in the headers contained in the currencies directory. The table below lists all the currencies defined in this way. The class name of each currency is constructed by appending “Currency” to the three letter ISO4217 code. Thus, for example, the class for South-African rand is ZARCurrency.

South-African rand ZAR 710 R 100 %3% %1$.2f africa.hpp
Argentinian peso ARS 32 100 %2% %1$.2f america.hpp
Brazilian real BRL 986 R$ 100 %3% %1$.2f america.hpp
Canadian dollar CAD 124 Can$ 100 %3% %1$.2f america.hpp
Chilean peso CLP 152 Ch$ 100 %3% %1$.0f america.hpp
Colombian peso COP 170 Col$ 100 %3% %1$.2f america.hpp
Mexican peso MXN 484 Mex$ 100 %3% %1$.2f america.hpp
Peruvian sol PEH 999 S./ 100 %3% %1$.2f america.hpp
Peruvian inti PEI 998 I/. 100 %3% %1$.2f america.hpp
Peruvian nuevo sol PEN 604 S/. 100 %3% %1$.2f america.hpp
Trinidad & Tobago dollar TTD 780 TT$ 100 %3% %1$.2f america.hpp
U.S. dollar USD 840 $ ¢ 100 %3% %1$.2f america.hpp
Venezuelan bolivar VEB 862 Bs 100 %3% %1$.2f america.hpp
Bangladesh taka BDT 50 Bt 100 %3% %1$.2f asia.hpp
Chinese yuan CNY 156 Y 100 %3% %1$.2f asia.hpp
Honk Kong dollar HKD 344 HK$ 100 %3% %1$.2f asia.hpp
Israeli shekel ILS 376 NIS 100 %1$.2f %3% asia.hpp
Indian rupee INR 356 Rs 100 %3% %1$.2f asia.hpp
Iraqi dinar IQD 368 ID 1000 %2% %1$.3f asia.hpp
Iranian rial IRR 364 Rls 1 %3% %1$.2f asia.hpp
Japanese yen JPY 392 ¥ 100 %3% %1$.0f asia.hpp
South-Korean won KRW 410 W 100 %3% %1$.0f asia.hpp
Kuwaiti dinar KWD 414 KD 1000 %3% %1$.3f asia.hpp
Nepal rupee NPR 524 NRs 100 %3% %1$.2f asia.hpp
Pakistani rupee PKR 586 Rs 100 %3% %1$.2f asia.hpp
Saudi riyal SAR 682 SRls 100 %3% %1$.2f asia.hpp
Singapore dollar SGD 702 S$ 100 %3% %1$.2f asia.hpp
Thai baht THB 764 Bht 100 %1$.2f %3% asia.hpp
Taiwan dollar TWD 901 NT$ 100 %3% %1$.2f asia.hpp
Austrian shilling ATS 40 100 %2% %1$.2f europe.hpp
Belgian franc BEF 56 1 %2% %1$.0f europe.hpp
Bulgarian lev BGL 100 lv 100 %1$.2f %3% europe.hpp
Belarussian ruble BYR 974 BR 1 %2% %1$.0f europe.hpp
Swiss franc CHF 756 SwF 100 %3% %1$.2f europe.hpp
Cyprus pound CYP 196 £C 100 %3% %1$.2f europe.hpp
Czech koruna CZK 203 Kc 100 %1$.2f %3% europe.hpp
Deutsche mark DEM 276 DM 100 %1$.2f %3% europe.hpp
Danish krone DKK 208 Dkr 100 %3% %1$.2f europe.hpp
Estonian kroon EEK 233 KR 100 %1$.2f %2% europe.hpp
Spanish peseta ESP 724 Pta 100 %1$.0f %3% europe.hpp
European Euro EUR 978 100 %2% %1$.2f europe.hpp
Finnish markka FIM 246 mk 100 %1$.2f %3% europe.hpp
French franc FRF 250 100 %1$.2f %2% europe.hpp
British pound sterling GBP 826 £ p 100 %3% %1$.2f europe.hpp
Greek drachma GRD 300 100 %1$.2f %2% europe.hpp
Hungarian forint HUF 348 Ft 1 %1$.0f %3% europe.hpp
Irish punt IEP 372 100 %2% %1$.2f europe.hpp
Iceland krona ISK 352 IKr 100 %1$.2f %3% europe.hpp
Italian lira ITL 380 L 1 %3% %1$.0f europe.hpp
Lithuanian litas LTL 440 Lt 100 %1$.2f %3% europe.hpp
Luxembourg franc LUF 442 F 100 %1$.0f %3% europe.hpp
Latvian lat LVL 428 Ls 100 %3% %1$.2f europe.hpp
Maltese lira MTL 470 Lm 100 %3% %1$.2f europe.hpp
Dutch guilder NLG 528 f 100 %3% %1$.2f europe.hpp
Norwegian krone NOK 578 NKr 100 %3% %1$.2f europe.hpp
Polish zloty PLN 985 zl 100 %1$.2f %3% europe.hpp
Portuguese escudo PTE 620 Esc 100 %1$.0f %3% europe.hpp
Romanian leu ROL 642 L 100 %1$.2f %3% europe.hpp
Romanian new leu RON 946 L 100 %1$.2f %3% europe.hpp
Swedish krona SEK 752 kr 100 %1$.2f %3% europe.hpp
Slovenian tolar SIT 705 SlT 100 %1$.2f %3% europe.hpp
Slovak koruna SKK 703 Sk 100 %1$.2f %3% europe.hpp
Turkish lira TRL 792 TL 100 %1$.0f %3% europe.hpp
New Turkish lira TRY 949 YTL 100 %1$.2f %3% europe.hpp
Australian dollar AUD 36 A$ 100 %3% %1$.2f oceania.hpp
New Zealand dollar NZD 554 NZ$ 100 %3% %1$.2f oceania.hpp

Creating New Currencies

In order to achieve the value semantics of currency objects, the Currency class does not rely on virtual methods, as one could have expected. Instead the data is stored as class member. However, storing all the relevant data for each object would waste memory and also result in slow copy operations. For this reason, each Currency object holds a boost::shared_ptr to an internal data object of type Currency::Data. This makes the class lightweight and copying is fast. The constructor of this object takes all the relevant information

  const std::string& name,
  const std::string& code,
  Integer numericCode,
  const std::string& symbol,
  const std::string& fractionSymbol,
  Integer fractionsPerUnit,
  const Rounding& rounding,
  const std::string& formatString,
  const Currency& triangulationCurrency = Currency());

The arguments passed to the constructor are stored in public members of the Data object and are retrieved and returned by the methods of Currency.

To make construction also a fast operation, the constructors of derived classes will not create a new data object. Instead they define a static pointer in the constructor and assign that to the internal data pointer. As an example we present the definition of a new class ZWLCurrency defining the Zimbabwe dollar.

class ZWLCurrency : public Currency {
  ZWLCurrency() {
    static boost::shared_ptr zwlData(
      new Data("Zimbabwe dollar", "ZWL", 932,
               "Z$", "", 100,
               "%2% %1$.2f"));
    data_ = zwlData;