Files
portfolio-tracker/docs/CURRENCY_CONVERSION.md
T
Matthias Hinrichs 9b7bdcbc53 first commit
2025-07-05 03:10:41 +02:00

7.3 KiB

Currency Conversion Feature

Overview

The Portfolio Tracker now supports automatic currency conversion for transactions that are in different currencies than the portfolio's base currency. This feature allows users to have a unified view of their investments across multiple currencies.

How It Works

Automatic Detection

  • When a transaction is added, the system automatically detects the stock's currency from Yahoo Finance
  • If the transaction currency differs from the portfolio's base currency, conversion rates are fetched
  • Converted values are displayed alongside original values for transparency

Display Format

The transaction table now includes additional columns when multi-currency transactions are present:

Original Column New Column Description
Preis Preis (BASE_CURRENCY) Shows converted price in portfolio base currency
Gesamt Gesamt (BASE_CURRENCY) Shows converted total in portfolio base currency

Example Display

Original: 150.00 USD
Converted: 135.50 EUR (when EUR is portfolio base currency)

Features

1. Real-time Currency Conversion

  • Exchange rates are fetched from exchangerate-api.io
  • Rates are cached for 1 hour to improve performance
  • Supports all major world currencies

2. Smart Display Logic

  • If transaction currency = portfolio currency: shows "-" in conversion columns
  • If currencies differ: shows converted amount
  • If conversion fails: shows "Conv. Error"

3. Portfolio Summary

  • Total invested amount is automatically converted to portfolio base currency
  • Summary shows "(converted)" indicator when multi-currency transactions exist

4. Currency Information Panel

A new information panel explains:

  • That transactions in other currencies are automatically converted
  • Exchange rates are updated hourly
  • Conversion is for display purposes only

Technical Implementation

Currency Conversion Utility (internal/util/currency.go)

Key Functions:

// Get exchange rate between two currencies
GetExchangeRate(fromCurrency, toCurrency string) (float64, error)

// Convert amount from one currency to another
ConvertCurrency(amount float64, fromCurrency, toCurrency string) (float64, error)

// Format currency with appropriate symbol
FormatCurrencyWithSymbol(amount float64, currency string) string

// Batch convert multiple amounts efficiently
BatchConvertCurrency(amounts []float64, fromCurrency, toCurrency string) ([]float64, error)

Caching System:

  • Cache Duration: 1 hour per exchange rate
  • Cache Key Format: FROM_TO (e.g., "USD_EUR")
  • Memory Usage: Minimal - only stores rate and timestamp
  • Thread Safe: Uses RWMutex for concurrent access

Template Helper Functions (internal/web/templates/helpers.go)

Key Helper Functions:

// Get converted price for display
getConvertedPrice(activity model.Activity, portfolioBaseCurrency string) string

// Get converted total for display  
getConvertedTotal(activity model.Activity, portfolioBaseCurrency string) string

// Calculate total invested in base currency
calculateTotalInvestedInBaseCurrency(activities []model.Activity, baseCurrency string) float64

// Format total with conversion indicator
formatTotalInvestedWithConversion(activities []model.Activity, baseCurrency string) string

Supported Currencies

The system supports all currencies provided by the exchange rate API, including:

Currency Code Symbol
US Dollar USD $
Euro EUR
British Pound GBP £
Japanese Yen JPY ¥
Swiss Franc CHF CHF
Canadian Dollar CAD C$
Australian Dollar AUD A$
And many more...

Error Handling

API Failures

  • If exchange rate API is unavailable: shows "Conv. Error"
  • Original transaction data is always preserved
  • System continues to function normally

Invalid Currencies

  • Unknown currency codes are handled gracefully
  • System falls back to displaying original amounts
  • No data loss occurs

Network Issues

  • Cached rates are used when possible
  • Graceful degradation to original currency display
  • User is informed via "Conv. Error" message

Performance Considerations

Caching Strategy

  • Hit Rate: High due to 1-hour cache duration
  • API Calls: Minimized through intelligent caching
  • Memory Usage: Low - only active currency pairs cached
  • Cleanup: Automatic cache expiration

Batch Operations

  • Multiple conversions use single API call when possible
  • Efficient for portfolios with many same-currency transactions
  • Reduces API rate limit consumption

Configuration

API Limits

  • Free Tier: 1,500 requests per month
  • Rate Limiting: Built-in request throttling
  • Fallback: Graceful degradation when limits exceeded

Cache Management

// Clear cache manually (for testing/debugging)
util.ClearCache()

// Get cache statistics
cacheInfo := util.GetCacheInfo()

Usage Examples

Adding Multi-Currency Transaction

  1. User adds transaction for Apple (AAPL) in USD to EUR portfolio
  2. System detects USD currency from Yahoo Finance
  3. Fetches USD/EUR exchange rate
  4. Displays both original (USD) and converted (EUR) amounts
  5. Caches exchange rate for future use

Portfolio Summary

Portfolio: "My Investments" (EUR)
Total Invested: 15,430.50 EUR (converted)

Recent Transactions:
- AAPL: 150.00 USD (~135.50 EUR)
- BMW.DE: 85.30 EUR (-)
- NESN.SW: 110.20 CHF (~102.15 EUR)

Testing

Unit Tests

  • All currency utilities have comprehensive test coverage
  • Tests include edge cases and error conditions
  • Performance benchmarks included

Integration Tests

  • Test with real transaction data
  • Verify UI display logic
  • Cache behavior validation

Future Enhancements

Planned Features

  1. Historical Rates: Use transaction date for accurate historical conversion
  2. Multiple Rate Providers: Fallback to alternative APIs
  3. Custom Rate Override: Allow manual exchange rate input
  4. Currency Trends: Show exchange rate history
  5. Base Currency Change: Convert entire portfolio to new base currency

API Improvements

  1. Rate Provider Selection: Choose between multiple APIs
  2. Custom Update Intervals: Configurable cache duration
  3. Offline Mode: Store rates locally for offline use

Troubleshooting

Common Issues

"Conv. Error" Displayed

  • Cause: Exchange rate API unavailable or rate limit exceeded
  • Solution: Wait and refresh, or check internet connection
  • Impact: Original data still visible and functional

Slow Loading

  • Cause: First-time rate fetching or cache expiration
  • Solution: Subsequent loads will be faster due to caching
  • Mitigation: Consider pre-warming cache for common currencies

Incorrect Rates

  • Cause: API data delay or temporary inconsistency
  • Solution: Rates update automatically within 1 hour
  • Manual Fix: Clear cache to force immediate refresh

Debug Commands

# Clear currency cache
curl -X POST http://localhost:8080/api/admin/clear-currency-cache

# Get cache status
curl http://localhost:8080/api/admin/currency-cache-info

Security Considerations

  • No API Keys Required: Uses free public API
  • Rate Limiting: Built-in protection against abuse
  • Data Privacy: No sensitive data sent to external APIs
  • Fallback Security: System functions without external dependencies