# 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: ```go // 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: ```go // 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 ```go // 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 ```bash # 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