FinFolio | Portfolio Management Software Blog

Multi-currency Portfolio Management Software

Written by Matt Abar | Jul 11, 2008 8:19:00 PM

FinFolio has multicurrency built in at a core level. In Example #5 we create some currencies and FX rates and demonstrate valuing accounts in different currencies. With a real FinFolio database, the currencies would already exist and would be loaded into memory when the environment is initialized.

Initialize the environment, deleting the existing database and recreating it from scratch.

// Initialize the FinFolio enviroment
Console.WriteLine("Example05_MultiCurrency: Initializing...");
ContextAutomation.InitializeConfiguration(
"Standard", false, false);

Now we create two currencies and link them together. In future releases, all the currency types and the CurrencyExchange links will be prepopulated.

// Set up the currencies
Currency usd = new Currency { CurrencyCode = CurrencyCode.USD };
Currency jpy =
new Currency { CurrencyCode = CurrencyCode.JPY };
// Create a link between two currencies, so we can hook exchange rates 
// to the currency

CurrencyExchange fxJpyUsd = new CurrencyExchange {
SourceCurrency = jpy, DestinationCurrency = usd};

Add FX rates to the CurrencyExchange link. For the example, we only add one, but in the real world, there would be a different FX rate for every day.

// Add FX rates
ExchangeRate fxRateJPY = new ExchangeRate {
CurrencyExchange = fxJpyUsd,
EffectiveDate = DateTime.Parse(
"1/1/2008"),
FxRate = 0.00943M };
FXConverter.AddFXRate(fxRateJPY);

We add Microsoft, a US security. We could set the LocalCurrency property to USD but we don't have to because USD is the default. All prices for the security must be in the currency of the security.

// Create a US security
Equity MSFT = new Equity { DisplayName="Microsoft" }; // Defaults to USA
MSFT.Prices.Add( new Price {
EffectiveDate = DateTime.Parse(
"1/1/2008"),
Close = 27.63M });

Also add Honda, a Japanese company. In retrospect, this was a confusing choice for the example, since Honda is traded on multiple exchanges. But let's assume we're talking about the Nikkei version of Honda. We set the Currency Code to JPY, and the price we use is in Yen, not dollars.

// Create a foreign security
Equity HONDA = new Equity {
DisplayName =
"Honda",
LocalCurrency = CurrencyCode.JPY };
HONDA.Prices.Add(
new Price {
EffectiveDate = DateTime.Parse(
"1/1/2008"),
Close = 3650M });

Now we can create an account that purchases Microsoft and Honda, each in their local currency. We set the reporting currency of the account to USD so, by default, any market values will be in dollars.

// Create an account with a position in each security
TaxableAccount account = new TaxableAccount {
ReportingCurrency = CurrencyCode.USD };
Position MSFTPosition =
new Position {
Owner = account,
Asset = MSFT };
MSFTPosition.Activities.Add(
new Buy {
TradeDate = DateTime.Parse(
"1/1/2008"),
Units = 100,
Amount = 2755,
Price = 27.75M });
Position HONDAPosition =
new Position {
Owner = account,
Asset = HONDA };
HONDAPosition.Activities.Add(
new Buy {
TradeDate = DateTime.Parse(
"1/1/2008"),
Units = 100,
Amount = 361000,
Price = 3610M });

Roll the account up. This will not be required in later releases.

// Rollup
account.Rollup();

Now all of our data is set up and we can value the positions in different currencies. FinFolio never directly returns a value, instead returning a MarketValue object. The MarketValue object knows many things about itself, one of which is the valuation currency. By default, it uses the local currency of the position.

We use the CurrencyFormat function to properly format the TotalValue string in the asset's currency. Microsoft will display formatted as dollars, and Honda will display formatted as Yen.

// Display positions in their local currencies
Console.WriteLine("\r\nLocal Currency:");
foreach (IPosition p in account.Assets)
{
Console.WriteLine(p.Asset.DisplayName +
": "
+ p.MarketValue(DateTime.Parse(
"2/1/2008")).TotalValue.CurrencyFormat(
p.Asset.LocalCurrency ) );
}

Now let's tell MarketValue to display the assets in USD. This time, we pass USD in as a parameter to the MarketValue function, which converts the TotalValue to USD. And CurrencyFormat give us a USD string format.

// Display positions in the account's reporting currency
Console.WriteLine("\r\nIn USD:");
foreach (IPosition p in account.Assets)
{
Console.WriteLine(p.Asset.DisplayName +
": " +
p.MarketValue(CurrencyCode.USD,
DateTime.Parse(
"2/1/2008")).TotalValue.CurrencyFormat(
CurrencyCode.USD ) );
}

Setting up currencies and CurrencyExchange links will not be necessary in future releases. They will be set up (as will many other items) when the database is initialized. But the fundamental multi-currency capabilities will remain the same.