package templates import ( "fmt" "portfolio-tracker/internal/model" "portfolio-tracker/internal/web/templates/components" ) templ PortfolioDetailContent(portfolio model.Portfolio, positions []model.Position, positionSummary model.PositionSummary) {

Positionen

if len(positions) > 0 { for _, position := range positions { if position.IsOpen() { } } } else { }
Wertpapier Anzahl Ø Einkaufspreis Aktueller Wert +/- Gesamt
{ position.Stock }
{ position.Currency }
{ position.FormatShares() } { position.FormatCurrency(position.AverageCostPrice) }
{ position.FormatCurrency(position.CurrentPrice) }
{ position.FormatCurrency(position.CurrentValue) }
{ position.FormatCurrency(position.UnrealizedPL) }
{ position.FormatPercentage() }
Details
Keine Positionen vorhanden. Fügen Sie Ihre erste Transaktion hinzu.

Letzte Transaktionen

if len(portfolio.Activities) > 0 { for i, activity := range portfolio.Activities { if i < 10 { } } } else { }
Datum Typ Wertpapier Anzahl Preis Preis ({ portfolio.BaseCurrency }) Gesamt Gesamt ({ portfolio.BaseCurrency })
{ activity.Date.Format("02.01.2006") } if activity.Type == "BUY" { Kauf } else if activity.Type == "SELL" { Verkauf } else if activity.Type == "DIVIDEND" { Dividende } else { { string(activity.Type) } } { activity.Stock } { fmt.Sprintf("%.3f", activity.Amount) } { fmt.Sprintf("%.2f %s", activity.Price, activity.Currency) } if activity.Currency != portfolio.BaseCurrency { { getConvertedPrice(activity, portfolio.BaseCurrency) } } else { - } { fmt.Sprintf("%.2f %s", activity.Amount * activity.Price, activity.Currency) } if activity.Currency != portfolio.BaseCurrency { { getConvertedTotalWithFallbackInfo(activity, portfolio.BaseCurrency) } } else { - }
Keine Transaktionen vorhanden
Historische Währungsumrechnung
Transaktionen werden mit den historischen Wechselkursen vom Transaktionsdatum in { portfolio.BaseCurrency } umgerechnet. Bei nicht verfügbaren historischen Kursen werden aktuelle Kurse verwendet (markiert mit *).

Portfolio-Zusammenfassung

@PortfolioSummary(positionSummary, len(portfolio.Activities))

Allokation

Allokations-Chart wird hier implementiert

} // Separate component for portfolio summary templ PortfolioSummary(summary model.PositionSummary, transactionCount int) {
Anzahl Transaktionen
{ fmt.Sprintf("%d", transactionCount) }
Aktueller Portfoliowert
{ formatCurrency(summary.TotalValue, summary.Currency) }
Gesamtwert investiert
{ formatCurrency(summary.TotalCostBasis, summary.Currency) }
Unrealisierte Gewinne/Verluste
{ formatCurrency(summary.TotalUnrealizedPL, summary.Currency) } if summary.TotalCostBasis > 0 { ({ formatPercentage(summary.TotalUnrealizedPL / summary.TotalCostBasis * 100) }) }
Dividenden erhalten
{ formatCurrency(summary.TotalDividends, summary.Currency) }
Gesamtrendite
{ formatCurrency(summary.TotalReturn, summary.Currency) } if summary.TotalCostBasis > 0 { ({ formatPercentage(summary.TotalReturnPct) }) }
} // Helper functions for formatting func formatCurrency(value float64, currency string) string { switch currency { case "EUR": return fmt.Sprintf("€%.2f", value) case "USD": return fmt.Sprintf("$%.2f", value) case "GBP": return fmt.Sprintf("£%.2f", value) case "CHF": return fmt.Sprintf("%.2f CHF", value) default: return fmt.Sprintf("%.2f %s", value, currency) } } func formatPercentage(value float64) string { if value > 0 { return fmt.Sprintf("+%.2f%%", value) } return fmt.Sprintf("%.2f%%", value) } func getColorClass(value float64) string { if value > 0 { return "text-success" } else if value < 0 { return "text-danger" } return "text-muted" } templ PortfolioDetail(authenticated bool, username string, portfolio model.Portfolio, portfolios []model.Portfolio, positions []model.Position, positionSummary model.PositionSummary) { @components.PageLayout(authenticated, username, portfolio.Name, PortfolioDetailContent(portfolio, positions, positionSummary), portfolios) }