Vision and the Euro Conversion

Overview

On January 1, 1999, eleven countries are scheduled to begin using the euro as their currency. Daily exchange rates from the euro currency into US dollars will be available from that date forward. Fixed conversion rates for the eleven countries will be established to aid in restating historical data for analysis purposes.

The standard methods included with all Vision installations are well-suited to handle the introduction of the euro, which will behave like any other currency in the future. Some minor modifications to the existing methods are needed to support historical analysis. There is no absolute correct way to accomplish this. The remainder of this document describes the issues and poses some basic solutions which are simple to implement and will provide consistent views of the data. These changes can be installed as is or can serve as a guide to designing your own solution.


Defining the Euro Currency

The euro is simply another instance of currency. It will normally be created as part of your standard currency or exchange rate processing with the ISO code of EUR. 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. Many Vision installations initialize the time series to return 1.0. If this is the case, you should either delete this value or reset the initial value to NA. 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.

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 exchangeTo:relativeTo: method at Currency requires modification to use this rate when converting to the EUR currency on a date prior to daily exchange rate availability.

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.

Implementation changes needed to support these approaches are described later in this document.


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 this new currency 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.

If desired, a new currency, LEGACY, can be introduced to support 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. A minor change to the currency method will be needed to support this. These changes are described later in this document.


Monetary Data Stored at Entity

If you decide to reassign the baseCurrency to EUR for securities and companies in participating countries and you store monetary data in properties directly for these entities, one final issue will need to be addressed. For these entity classes, the baseCurrency value has been performing two distinct roles:

  1. the default currency in which to access and display any data associated with the entity
  2. the currency in which data stored directly with the entity has been reported.
Monetary data is usually stored in DataRecord or DataSet instances in which a distinct currency can be recorded. When you store monetary data in properties defined at Security, you are assuming that the baseCurrency will not change and always reflects the reported currency.

One tempting approach is to just change baseCurrency to a time series property for the Entity class, storing the legacy currency as of 1/1/1 and the euro as of 1/1/99. This would enable you to easily determine the correct reported currency; however, it would cause inconsistent default behavior when using data over time. By default, data accessed prior to 1/1/99 would be in the legacy currency and data accessed after this data would be in euros.

A better solution is to decouple the two uses of baseCurrency for the Entity class. The baseCurrency should continue to serve as the default currency in which to display monetary data for the entity. A minor modification to the currencyFactor method will enable it to select the correct reported currency based on the evaluation date. These changes are described later in this document.


Suggested Vision Modifications

This section supplies the suggested Vision code patches to address the introduction of the euro:

Summary of changes

  1. Introduce EUR currency
  2. Reset initial exchange rate to NA (for euro or all)
  3. Add support for fixed rate conversion prior to euro daily exchange rate
  4. Flag participating countries with euro start date
  5. Add and populate legacy currency at Entity
  6. Add support for Named Currency LEGACY
  7. Add reported currency for monetary data stored directly at Entity
  8. Add synthetic euro currencies

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

Vision Code

The following patch should serve as a guide for making these changes:

##################################################
#  Vision Changes in support of Euro processing
##################################################

####################
#  1. Introduce EUR currency
#
#  Create the Euro if it does not exist.  Add a cover method
#     to make it easier to identify.  
####################

Named Currency at: "EUR" . isNA
   ifTrue: [ Currency createInstance: "EUR" . setNameTo: "EURO" ] ;
Currency defineMethod: [ | isEuro | code = "EUR" ] ;

####################
#  2. Reset initial exchange rate to NA (for euro or all)
#
#  Modify behavior of all currencies that do not have exchange rates
#    prior to a certain date.  Currently, if no rate is available, the
#    exchange rate is returned as 1.0 which implies that the monetary
#    value will be displayed in its default (base) currency.   NA is
#    probably the better result so that there is no assumption that
#    the currency exchange has happened. 
#
#  For installations not wishing to change current behavior, the
#    value for the euro currency (EUR) should be set to NA as of 1/1/1:
#
#-->  uncomment the next line if initialize method is not changed
#-->  Named Currency EUR :usExchange asOf: 10101 put: NA :
#
####################

#--  reset all initial exchange rates to NA
Currency instanceList 
   do: [ :usExchange asOf: earliestPossibleDate put: NA ] ;

#--  initialize US with 1.0 since this one is never updated
Named Currency USD :usExchange <- 1.0 ;

#--  fix initialization method to no longer set initial rate to 1.0
Currency defineMethod: [ | initialize | 
  ^super initialize ; 
  ^self :underlyingCurrency <- ^self ; 
  ^self :underlyingExchange <- 1.0 ;
#--  ^self :usExchange <- 1.0 ;   #-- let it stay at NA
  ^self
] ;

####################
#  3. Add support for fixed rate conversion prior to euro daily exchange rate
#
#  Add property to support fixed rate conversion for selected currencies;
#  Add class constant to flag whether fixed rate conversion should be used;
#  Modify exchange calculation to use this fixed rate when appropriate
#
#  Usage:
#     Named Currency IEP :fixedRateToEuro <- .80 ;
#     Currency enableFixedEuroRate ;  Currency disableFixedEuroRate ;
#
####################

#--- create the property
Currency defineFixedProperty: 'fixedRateToEuro' ;   #- in legacy to euro

#---  set the known rates

#---  create mechanism to enable or disable ; save database with
#---  preferred default behavior; this script disables fixed rate 
Currency defineMethod: [ | enableFixedEuroRate |
  ^self define: 'fixedEuroRateEnabled' toBe: TRUE ;
  ^self
] ;

Currency defineMethod: [ | disableFixedEuroRate |
  ^self define: 'fixedEuroRateEnabled' toBe: FALSE ;
  ^self
] ;

Currency disableFixedEuroRate ;       #-- disable by default

#---  modify the method to use fixed rate if appropriate

Currency defineMethod: [ | exchangeTo: targetCurr relativeTo: date |

#--  Assumes usExchange returns values in units of foreign currency per US$
#--  Result is returned in units of target currency / source currency
#--     so it can be used to multiply values in source currency to
#--     convert to results in target currency
#--  If fixedRateEuroEnabled isTrue, use it to convert to or from euro
#--    when exchange rate isNA

  !rate <- 1.0 ;
  ^self underlyingCurrency != targetCurr asSelf
   ifTrue: 
     [ date evaluate:  #--  convert as of supplied date 
         [ !preEuro <- 
              (targetCurr isEuro && targetCurr usExchange isNA)
                 || [ underlyingCurrency isEuro && underlyingCurrency usExchange isNA ] ;
           preEuro
           ifTrue:
             [ :rate <- fixedEuroRateEnabled
               ifTrue: 
                 [ targetCurr isEuro
                     ifTrue: [ 1 / underlyingCurrency fixedRateToEuro ]
                   ifFalse: [ targetCurr fixedRateToEuro ] 
                 ] 
               ifFalse: [ NA ] ;
             ]
           ifFalse:
             [ !sourceToUs <- ^self underlyingCurrency usExchange ;
               !targetToUs <- targetCurr 
                   send: [ ^self underlyingCurrency usExchange * 
                           ^self underlyingExchange
                         ] ;
               :rate <- targetToUs / sourceToUs ; 
            ] ;
         ] ;
     ] ;
  rate / ^self underlyingExchange
] ;

####################
#  4.  Flag participating countries with euro start date
####################

Currency defineFixedProperty: 'euroStartDate' ;
Currency defineMethod: [ | inEMU | euroStartDate isDate ] ;

Named Currency
    send: [ ATS, BEF, FIM, FRF, DEM, IEP, ITL, LUF, NLG, PTE, ESP ] .
do: [ :euroStartDate <- 990101 asDate ] ;

####################
#  5. Add and populate legacy currency at Entity ; store date
#     that the entity was changed to euro
####################

#--  define property and cover that reverts to baseCurrency
Entity defineFixedProperty: '_legacyCurrency' ;
Entity defineMethod: [ | legacyCurrency | 
   _legacyCurrency else: baseCurrency
] ;

#--  define property to store euroStartDate
Entity defineFixedProperty: 'euroStartDate' ;

#---  define a method that switches base to EUR, copying the legacy first
Entity defineMethod: [ | setBaseCurrencyToEuro |
  baseCurrency isEuro not
     ifTrue: [ :_legacyCurrency <- baseCurrency ;
               :baseCurrency <- ^global Named Currency EUR ;
               :euroStartDate <- ^date ;
             ] ;
  ^self
] ;

#--  reset applicable securities and companies to Euro
#--  For example, to change all security and company instances
#-->     Security masterList select: [ baseCurrency inEMU ] .
#-->        do: [ setBaseCurrencyToEuro ] ;
#-->     Company masterList select: [ baseCurrency inEMU ] .
#-->        do: [ setBaseCurrencyToEuro ] ;

####################
#  6. Add support for Named Currency LEGACY
#
#  Provide a mechanism to evaluate a mixed security list in "Legacy" currency:
#     Named Currency LEGACY evaluate: [ ] ;
####################

#---  Create currency and cover
Currency createInstance: "LEGACY" ;
Currency defineMethod: [ | isLegacy | code = "LEGACY" ] ;

#----  Redefine currency method to use entity legacy 
Entity defineMethod: [ | currency |
  ^local currency isntNA 
  ifTrue:                                     #-- inside an evaluate: [ ] 
    [ ^local currency isLegacy 
        ifTrue: [ ^self legacyCurrency ]      #-- LEGACY evaluate: []
       ifFalse: [ ^local currency ]           #-- other currency evaluate: []
    ]   
 ifFalse: [^self baseCurrency ]               #-- not in an evaluate  
] ;

####################
#  7. Add reported currency for monetary data stored directly at Entity
#
####################

Entity defineMethod: [ | reportedCurrency |
  !currencyToUse <- ^self baseCurrency ;
  ^self euroStartDate isDate && [ ^self euroStartDate >= ^date ]
       ifTrue: [ :currencyToUse <- ^self legacyCurrency ] ;
  currencyToUse
] ;

Entity defineMethod: [ | currencyFactor |
  ^self reportedCurrency exchangeTo: ^self currency relativeTo: ^date
] ;

####################
#  8. Add synthetic euro currencies
#
#  Support for ECU synthetic euro history
#    Create another currency ; update with synthetic history pre-euro;
#    update with EUR values post-euro
####################

Currency createInstance: "ECU" . setNameTo: "EURO (SYNTHETIC)" ;

Related Topics