Vision Class: Currency

Currency Overview

The Currency class is used to track exchange rate information between currencies. Instances of the class currency represent the currencies in which monetary transactions are performed such as "US Dollars" or "British Pounds".

The Currency class is a direct subclass of Entity:

  Object
     |
  Entity
     |
  Currency

Basic Access

Your Vision system has a number of currencies pre-defined using the ISO standard identifiers and names. To display the code and name for each defined currency use:

  Currency masterList
     sortUp: [ name ] .
  do: [ code print: 15 ; name printNL ] ;

The time series usExchange tracks daily exchange rates to convert a specific currency into US Dollars. Exchange rates are stored as the number of foreign currency units that are equivalent to one US Dollar. This time series is usually updated daily as part of the production processing. To set the exchange rate for a specific currency as of a date, just update the time series directly. For example, the expression:

  Named Currency CAD :usExchange asOf: 9512 put: 1.32 ;

Since usExchange is a time series property, you can use any of the standard TimeSeries messages with it. For example:

  Named Currency CAD :usExchange asOf: 9512 
and
   9512 evaluate: [ Named Currency CAD usExchange ] 
return the value of the Canadian exchange rate as of December 1995 (i.e., 1.32) and the expression:
  Named Currency CAD :usExchange 
     from: 950101 to: 951231 .
     displayAll 
displays all the Canadian exchange rate values stored for 1995.

The message exchangeTo: targetCurr relativeTo: date is used to access the exchange rate between the recipient and a target currency as of a specific date. The result is returned in units of target currency to source currency so it can be used to multiply values in the source currency to convert to results in the target currency. For example:

  Named Currency USD
     exchangeTo: Named Currency CAD relativeTo: 9512 
returns the exchange rate in units of Canadian dollars to US dollars (i.e., 1.32). You can multiply a value expressed in US dollars by this exchange rate to create an equivalent amount in Canadian dollars. The expression:
  Named Currency CAD
     exchangeTo: Named Currency USD relativeTo: 9512 .
returns the exchange rate in units of US dollars to Canadian dollars (i.e., .76). You can multiply a value expressed in Canadian dollars by this exchange rate to create an equivalent amount in US dollars.


Monetary values are sometimes expressed in a variation of a currency. For example, you may have some data expressed in pence instead of pounds, but your exchange rate data is only available in pounds. You can establish the relationship between pence and pounds as illustrated below:

  Currency createInstance: "UKPound" ; 

  Currency createInstance: "UKPence" .
    setUnderlyingCurrencyTo: Named Currency UKPound 
               withExchange: 100 ; 
These expressions create two new currency instances. The "true" currency is the UKPound currency. You will maintain the usExchange time series for this currency. The UKPence currency is converted to UKPound values by dividing the result by 100. You do not maintain the usExchange time series for the UKPence currency. The exchangeTo:relativeTo: message will automatically perform the extra conversion when the source or target currency is a "non-true" currency such as UKPence.

The message isTrueCurrency can be used to find the "true" currency instances. The properties underlyingCurrency and underlyingExchange are used to track the related currency and conversion units for "non-true" currencies. For example, the expression:

  Currency masterList select: [ isTrueCurrency not ] .
  do: [ code print: 10 ;
        underlyingCurrency code print: 10 ; 
        underlyingExchange printNL ;
      ] ;
displays the underlying currency and exchange rate for all currencies that are not "real".


Dynamic Currency Support

The fixed property baseCurrency has been defined at Object and is used to indicate the actual currency in which data values for a particular instance are stored and accessed by default. Its value should be set to an instance of the class Currency. Objects whose values are stated in a currency can use this property to facilitate the process of restating values in alternative currencies.

To set the value for the baseCurrency property, use the message setBaseCurrencyTo:. The parameter to this message can be a currency instance or a string that refers to a currency instance. For example:

  Named Company GM setBaseCurrencyTo: Named Currency USD ;
or
  Named Company GM setBaseCurrencyTo: "USD" ;
Normally, you do not change the base currency of an instance once it has been defined.

By default, the base currency of an object is used to display all monetary values. Several messages have been defined that allow you to override this default. The currency message at Object is defined to check to see if an override has been set. If the override is NA, then the baseCurrency is used; otherwise, the override is used. In other words, the message baseCurrency will always return the actual currency of an instance; the message currency will return the override if it exists, the base currency otherwise.

The evaluate: message is defined at the class Currency to evaluate all expressions in the supplied block using the recipient currency. This message redefines the currency override for the duration of the block's execution. Expressions within the block can redefine the currency again, if desired. For example, to display GM's data in Canadian dollars use:

  Named Currency CAD evaluate: [
    Named Security GM
    do: [ price printNL ;
          "Base Currency: " print ; baseCurrency printNL ;
          "Currency Used: " print ; currency printNL ;
        ]
  ] ; 
Note that the baseCurrency will continue to be US but the currency will be the Canadian currency inside the block. To display the price in both currencies, you could use the expression:
  Named Currency CAD evaluate: [
    Named Security GM
    do: [ price print ; 
          baseCurrency evaluate: [ price print ] ;
          "Base Currency: " print ; baseCurrency printNL ;
          "Currency Used: " print ; currency printNL ;
        ]
  ] ; 
The first price will be displayed in Canadian dollars; the second will be displayed in the base currency.

The message asCurrency can be sent to a string to convert it into a currency instance. The previous example could be rewritten as:

  "CAD" asCurrency evaluate: [
    Named Security GM
    do: [ price print ; 
          baseCurrency evaluate: [ price print ] ;
          "Base Currency: " print ; baseCurrency printNL ;
          "Currency Used: " print ; currency printNL ;
        ]
  ] ; 

The message: inCurrency:do: provides an alternative technique that is sometimes more readable. The currency parameter can be either a string or an actual currency. The previous example could be rewritten as:

   Named Security GM
     inCurrency: "CAD"
    do: [ price print ; 
          baseCurrency evaluate: [ price print ] ;
          "Base Currency: " print ; baseCurrency printNL ;
          "Currency Used: " print ; currency printNL ;
        ] ;
The message setAsDefault is defined at Currency and is used to change the currency override for all subsequent executions in your session. The new value is in effect until changed to a different value or cleared. You can override this default using the Currency evaluate: and inCurrency:do: messages described above. For example, if you execute:
  Named Currency CAD setAsDefault 
in your session, then the expression:
    Named Security GM
    do: [ price print ; 
          "Base Currency: " print ; baseCurrency printNL ;
          "Currency Used: " print ; currency printNL ;
        ] ;
will automatically execute using Canadian dollars. The expression:
   Named Currency USD evaluate: [
    Named Security GM
    do: [ price print ; 
          "Base Currency: " print ; baseCurrency printNL ;
          "Currency Used: " print ; currency printNL ;
        ] ;
  ] ; 
will execute using US dollars even if the global override has been set. The message clearDefault is defined at the Currency class and is used to clear the currency override value. It is sent to the class itself using:
  Currency clearDefault ;
If the global override for Currency has been cleared, the baseCurrency is used by default. The displayGlobalOverride message defined for Currency can be used to display the current override:
  Currency displayGlobalOverride


Writing Currency-Adjusted Methods

By convention, message names that begin with the character '_' represent properties containing unadjusted data values in its initial units. For example, the property _totalMarketValue defined at Account would return the total market value of the account in its base currency. The message totalMarketValue returns the value in the current currency (i.e., the override value if it exists, the base currency otherwise).

The property and method could be defined as illustrated below:

  #--  Define actual value for time series in base currency
  Account define: '_totalMarketValue' ;

  #--  Define access method in current currency
  Account
  defineMethod:
  [ | totalMarketValue |
    _totalMarketValue *
    ( baseCurrency exchangeTo: currency relativeTo: ^date)
  ] ;
The method accesses the exchange rate between the base currency (i.e., the currency in which the value is stored) and the "active" currency (i.e., the current override value for the currency) as of the current evaluate date. Note that the exchange rate will be 1 if no currency override is in effect. The unadjusted market value number is multiplied by this exchange rate to restate it in the current currency. The expression:
  Named Account XYZ totalMarketValue
returns the value in the base currency, and the expression:
  "CAD" asCurrency
      evaluate: [ Named Account XYZ totalMarketValue ]
accesses the value in the Canadian currency.

You can change the currency and evaluation date using a number of variations including:

  9511 evaluate: 
    [ "CAD" asCurrency 
      evaluate: 
        [ Named Account XYZ totalMarketValue 
        ]
    ]
or
 "CAD" asCurrency evaluate:
    [ 9511 evaluate:
        [ Named Account XYZ totalMarketValue 
        ]
    ] 
The message currencyFactor has been defined at Object to return the exchange rate between the base currency for an object and the override currency as of the current evaluate date. The totalMarketValue method could therefore be rewritten as:
  Account
  defineMethod:
  [ | totalMarketValue |
    _totalMarketValue * currencyFactor
  ] ;


The Euro Currency

The euro is simply another instance of Currency. It will normally be included as part of your standard currency or exchange rate processing with the ISO code of EUR. This instance is created as part of all Vision installations starting with release 6.1.2.

As of January 1, 1999, daily exchange rates between the euro and the US dollar should be supplied as part of your daily exchange rate feed. Just like any other currency, this value will be stored in the time series usExchange for the EUR currency instance.

Historical Analysis

Most of the issues involved with using the euro relate to viewing data that existed prior to its introduction. Since there will be no "official" exchange rate history for the euro prior to 1/1/99, what is the "correct" way to present this information if the user asks to see the data in currency EUR? Four possibilities exist:

  1. return NA indicating that the data cannot be expressed in currency EUR
  2. return the data in its reported currency
  3. apply the fixed euro conversion rate for the country
  4. apply a floating synthetic rate

The first two of these cases can be handled by setting the appropriate initial value in the usExchange time series for currency EUR. If you want to return the value NA prior to 1/1/99, make sure you have no value (or the value NA) stored prior to this date. If you want to return the value in its reported currency, the value of 1.0 should be stored in this time series as of the initial date. This will result in the reported value (in its reported currency) being multiplied by a currency factor of 1.0, which is the equivalent of returning the reported value in its reported currency for dates prior to the introduction of the euro exchange rate.

Note: Starting with release 6.1.2, the initial value is set to NA. However, older Vision installations initialized the time series to return 1.0.

Alternative 3, applying a fixed conversion rate for pre-euro data, involves defining an additional property, fixedRateToEuro at the Currency class to store the fixed euro conversion rate for each participating country. A second property, fixedEuroRateEnabled can be enabled or disabled to control whether you want this rate applied by default or on demand. The fixed euro rate is enabled by default, beginning with release 6.1.2.

The final option, using a daily synthetic rate, can be implemented by creating an additional Currency instance and populating its usExchange time series with a daily synthetic rate, both historically and into the future.

Using the Legacy Currency

Many Vision installations want to change the default currency for securities and companies in participating countries to the euro so that data is accessed and displayed in euros by default. This can be accomplished by setting the baseCurrency property for these entities to the currency EUR. By default, data stored in DataRecord and DataSet instances associated with these entities will automatically be converted from the reported currency and displayed in euros. For example, assume the following:

    • GermanSec has a price of 100 DEM on 12/31/98
    • GermanSec's base currency is set to EUR
    • The fixed conversion rate from DEM to EUR is 2

The Vision expression:

     981231 evaluate: [ Named Security GermanSec price]
will return the value of 50 euros, since price data is automatically converted from reported currency to the security's base currency.

Prior to changing the base currency to EUR, you will probably want to keep a reference to the legacy currency. We recommend adding a new property, _legacyCurrency to store this value for entities that are being changed to the euro. The cover method legacyCurrency returns this currency if set, the base currency otherwise. The setBaseCurrencyTo: method at Entity has been modified in release 6.1.2 to automatically set the _legacyCurrency when you change the base currency to EUR.

To display data in the LEGACY currency, use the Vision expression:

     Named Currency LEGACY evaluate:
       [ securityList do: [ ] ;
       ] ;
This usage instructs Vision to display the data for each security in the list using its legacy currency.

Monetary Data Stored at Entity

Note: This approach assumes that you continue to update the legacy currency exchange rates after 1/1/99. These rates will continue to provide the Legacy to US exchange rate. If your currency source does not provide these values, they can be computed and stored daily using the calculation:

    legacy fixed rate to EUR * daily EUR to US rate
    
The ExchangeRateFeed data feed computes these legacy rates automatically.

Vision Installations that predate release 6.1.2 may wish to review the Euro document for more information.

Related Topics