first commit

This commit is contained in:
Matthias Hinrichs
2025-07-05 03:10:41 +02:00
commit 9b7bdcbc53
39 changed files with 5109 additions and 0 deletions
+232
View File
@@ -0,0 +1,232 @@
# 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