app is now using historical exchange rates for transactions
This commit is contained in:
+33
-19
@@ -2,14 +2,15 @@
|
||||
|
||||
## 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.
|
||||
The Portfolio Tracker now supports automatic currency conversion with **historical exchange rates** for transactions that are in different currencies than the portfolio's base currency. This feature uses the actual exchange rates from the transaction date, providing accurate historical conversion and allowing users to have a unified view of their investments across multiple currencies.
|
||||
|
||||
## How It Works
|
||||
|
||||
### Automatic Detection
|
||||
### Automatic Historical 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
|
||||
- If the transaction currency differs from the portfolio's base currency, **historical conversion rates from the transaction date** are fetched
|
||||
- Converted values using historical rates are displayed alongside original values for transparency
|
||||
- Falls back to current rates if historical rates are unavailable (marked with *)
|
||||
|
||||
### Display Format
|
||||
The transaction table now includes additional columns when multi-currency transactions are present:
|
||||
@@ -27,25 +28,29 @@ 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
|
||||
### 1. Historical Currency Conversion
|
||||
- **Historical exchange rates** are fetched from `exchangerate-api.com` and `frankfurter.app` for accurate transaction-date conversion
|
||||
- Historical rates are cached for 24 hours, current rates for 1 hour to improve performance
|
||||
- Falls back to current rates when historical rates are unavailable
|
||||
- Supports all major world currencies with date-specific accuracy
|
||||
|
||||
### 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"
|
||||
- If historical rate unavailable: shows converted amount with "*" indicator (using current rate)
|
||||
|
||||
### 3. Portfolio Summary
|
||||
- Total invested amount is automatically converted to portfolio base currency
|
||||
- Summary shows "(converted)" indicator when multi-currency transactions exist
|
||||
- Total invested amount is automatically converted to portfolio base currency using historical rates
|
||||
- Summary shows "(historical rates)" or "(converted)" indicator when multi-currency transactions exist
|
||||
- Provides most accurate historical portfolio valuation
|
||||
|
||||
### 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
|
||||
- That transactions in other currencies are automatically converted using **historical exchange rates**
|
||||
- Historical rates are fetched for the actual transaction date
|
||||
- Falls back to current rates when historical data is unavailable (marked with *)
|
||||
- Conversion provides accurate historical portfolio tracking
|
||||
|
||||
## Technical Implementation
|
||||
|
||||
@@ -53,12 +58,18 @@ A new information panel explains:
|
||||
|
||||
#### Key Functions:
|
||||
```go
|
||||
// Get exchange rate between two currencies
|
||||
// Get current exchange rate between two currencies
|
||||
GetExchangeRate(fromCurrency, toCurrency string) (float64, error)
|
||||
|
||||
// Convert amount from one currency to another
|
||||
// Get historical exchange rate for a specific date
|
||||
GetHistoricalExchangeRate(fromCurrency, toCurrency string, date time.Time) (float64, error)
|
||||
|
||||
// Convert amount from one currency to another using current rates
|
||||
ConvertCurrency(amount float64, fromCurrency, toCurrency string) (float64, error)
|
||||
|
||||
// Convert amount using historical exchange rate for a specific date
|
||||
ConvertCurrencyHistorical(amount float64, fromCurrency, toCurrency string, date time.Time) (float64, error)
|
||||
|
||||
// Format currency with appropriate symbol
|
||||
FormatCurrencyWithSymbol(amount float64, currency string) string
|
||||
|
||||
@@ -76,16 +87,19 @@ BatchConvertCurrency(amounts []float64, fromCurrency, toCurrency string) ([]floa
|
||||
|
||||
#### Key Helper Functions:
|
||||
```go
|
||||
// Get converted price for display
|
||||
// Get converted price for display using historical rates
|
||||
getConvertedPrice(activity model.Activity, portfolioBaseCurrency string) string
|
||||
|
||||
// Get converted total for display
|
||||
// Get converted total for display using historical rates
|
||||
getConvertedTotal(activity model.Activity, portfolioBaseCurrency string) string
|
||||
|
||||
// Calculate total invested in base currency
|
||||
// Get converted total with fallback information
|
||||
getConvertedTotalWithFallbackInfo(activity model.Activity, portfolioBaseCurrency string) string
|
||||
|
||||
// Calculate total invested in base currency using historical rates
|
||||
calculateTotalInvestedInBaseCurrency(activities []model.Activity, baseCurrency string) float64
|
||||
|
||||
// Format total with conversion indicator
|
||||
// Format total with historical conversion indicator
|
||||
formatTotalInvestedWithConversion(activities []model.Activity, baseCurrency string) string
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user