etf-trade-tracker/index.html
kris 31a02a69ac Add comprehensive Capital Gains Tax (CGT) calculation feature
Features:
- Configurable CGT rates by holding period (1M, 6M, 1Y, 2Y, 2Y+)
- Annual CGT exemption allowance support
- Real-time CGT calculations based on holding periods
- FIFO (First In, First Out) method for calculating gains
- Interactive CGT settings page with visual rate preview
- Integration with gains/losses page showing:
  - Total CGT liability estimation
  - After-tax gains calculation
  - Effective tax rate display
  - Holdings breakdown by tax period
- Database schema for per-user CGT settings
- Comprehensive API endpoints for CGT management
- Responsive design with professional styling

CGT calculation methodology:
- Uses trade purchase dates to determine holding periods
- Applies different rates based on time held (short vs long term)
- Factors in annual exemption allowance
- Shows estimated tax liability for planning purposes

Default rates (configurable):
- 0-1 Month: 40%
- 1-6 Months: 35%
- 6M-1 Year: 30%
- 1-2 Years: 20%
- 2+ Years: 10%
- Annual exemption: €1,270

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-28 18:20:36 +00:00

432 lines
24 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ETF Trade Tracker</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="app-container">
<nav class="sidebar">
<div class="sidebar-header">
<h2>ETF Tracker</h2>
</div>
<ul class="sidebar-menu">
<li class="menu-item active" data-page="dashboard">
<span class="menu-icon">📊</span>
<span class="menu-text">Dashboard</span>
</li>
<li class="menu-item" data-page="portfolio">
<span class="menu-icon">💼</span>
<span class="menu-text">Portfolio</span>
</li>
<li class="menu-item" data-page="trade-history">
<span class="menu-icon">📋</span>
<span class="menu-text">Trade History</span>
</li>
<li class="menu-item" data-page="gains-losses">
<span class="menu-icon">📈</span>
<span class="menu-text">Gains/Losses</span>
</li>
<li class="menu-item menu-separator" data-page="add-trade">
<span class="menu-icon"></span>
<span class="menu-text">Add Trade</span>
</li>
<li class="menu-item" data-page="cgt-settings">
<span class="menu-icon">🧮</span>
<span class="menu-text">CGT Settings</span>
</li>
<li class="menu-item admin-only" data-page="admin" style="display: none;">
<span class="menu-icon">👥</span>
<span class="menu-text">Admin Panel</span>
</li>
</ul>
<div class="sidebar-footer">
<div class="user-info" id="user-info" style="display: none;">
<span id="current-user">Not logged in</span>
<button id="logout-btn" class="logout-btn">Logout</button>
</div>
</div>
</nav>
<div class="main-content">
<header class="top-header">
<button class="sidebar-toggle"></button>
<h1 id="page-title">Dashboard</h1>
</header>
<main class="content-area">
<!-- Login Page -->
<div id="login-page" class="page active">
<div class="login-container">
<h2>Login to ETF Tracker</h2>
<form id="login-form" class="login-form">
<div class="form-group">
<label for="login-username">Username</label>
<input type="text" id="login-username" required placeholder="Enter your username">
</div>
<div class="form-group">
<label for="login-password">Password</label>
<input type="password" id="login-password" required placeholder="Enter your password">
</div>
<button type="submit" class="login-btn">Login</button>
</form>
<div class="login-info">
<p>Default admin credentials:</p>
<p><strong>Username:</strong> admin</p>
<p><strong>Password:</strong> admin123</p>
</div>
</div>
</div>
<!-- Dashboard Page -->
<div id="dashboard-page" class="page">
<div class="dashboard-grid">
<div class="dashboard-card total-value">
<h3>Current Portfolio Value</h3>
<div class="metric-value" id="dashboard-current-value">€0.00</div>
<div class="metric-detail" id="dashboard-last-updated">Using cost basis</div>
</div>
<div class="dashboard-card total-gains">
<h3>Total Gains/Losses</h3>
<div class="metric-value" id="dashboard-total-gains">€0.00</div>
<div class="metric-change" id="dashboard-gains-percentage">0.0%</div>
</div>
<div class="dashboard-card monthly-investment">
<h3>Monthly Investment</h3>
<div class="metric-value" id="monthly-investment">€0.00</div>
<div class="metric-detail" id="monthly-trades">0 trades</div>
</div>
<div class="dashboard-card yearly-investment">
<h3>Yearly Investment</h3>
<div class="metric-value" id="yearly-investment">€0.00</div>
<div class="metric-detail" id="yearly-trades">0 trades</div>
</div>
<div class="dashboard-card total-shares">
<h3>Total Shares</h3>
<div class="metric-value" id="total-shares">0</div>
<div class="metric-detail" id="unique-etfs">0 ETFs</div>
</div>
<div class="dashboard-card cost-basis">
<h3>Total Investment</h3>
<div class="metric-value" id="dashboard-cost-basis">€0.00</div>
<div class="metric-detail" id="dashboard-avg-return">Avg return: 0.0%</div>
</div>
</div>
<div class="etf-breakdown">
<h3>ETF Breakdown</h3>
<div id="etf-breakdown-list" class="breakdown-list">
<p class="no-data">No ETF positions yet</p>
</div>
</div>
</div>
<!-- Add Trade Page -->
<div id="add-trade-page" class="page">
<div class="trade-form-container">
<h2>Add New Trade</h2>
<form id="trade-form" class="trade-form">
<div class="form-group">
<label for="etf-symbol">ETF Symbol</label>
<input type="text" id="etf-symbol" required placeholder="e.g., VWCE, SPY, QQQ">
</div>
<div class="form-group">
<label for="trade-type">Trade Type</label>
<select id="trade-type" required>
<option value="">Select trade type</option>
<option value="buy">Buy</option>
<option value="sell">Sell</option>
</select>
</div>
<div class="form-group">
<label for="shares">Number of Shares</label>
<input type="number" id="shares" step="0.001" min="0" required placeholder="0.000">
</div>
<div class="form-group">
<label for="price">Price per Share</label>
<input type="number" id="price" step="0.01" min="0" required placeholder="0.00">
</div>
<div class="form-group">
<label for="currency">Currency</label>
<select id="currency" required>
<option value="">Select currency</option>
<option value="EUR">Euro (€)</option>
<option value="USD">US Dollar ($)</option>
</select>
</div>
<div class="form-group">
<label for="trade-date">Trade Date</label>
<input type="date" id="trade-date" required>
</div>
<div class="form-group">
<label for="trade-time">Trade Time (24h format)</label>
<input type="time" id="trade-time" required step="1">
</div>
<div class="form-group">
<label for="fees">Fees (optional)</label>
<input type="number" id="fees" step="0.01" min="0" placeholder="0.00">
</div>
<div class="form-group">
<label for="notes">Notes (optional)</label>
<textarea id="notes" rows="3" placeholder="Additional notes about this trade..."></textarea>
</div>
<button type="submit" class="submit-btn">Add Trade</button>
</form>
</div>
</div>
<!-- Trade History Page -->
<div id="trade-history-page" class="page">
<div class="trade-history-container">
<h2>Trade History</h2>
<div class="trades-controls">
<button id="clear-trades" class="clear-btn">Clear All Trades</button>
<button id="export-trades" class="export-btn">Export to JSON</button>
</div>
<div id="trades-list" class="trades-list">
<p class="no-trades">No trades recorded yet. Add your first trade above!</p>
</div>
</div>
</div>
<!-- Portfolio Page -->
<div id="portfolio-page" class="page">
<div class="portfolio-container">
<h2>Portfolio Summary</h2>
<div id="portfolio-summary" class="portfolio-summary">
<p class="no-data">No portfolio data yet</p>
</div>
</div>
</div>
<!-- Admin Panel Page -->
<div id="admin-page" class="page">
<div class="admin-container">
<h2>Admin Panel - User Management</h2>
<div class="admin-actions">
<h3>Create New User</h3>
<form id="create-user-form" class="create-user-form">
<div class="form-row">
<div class="form-group">
<label for="new-username">Username</label>
<input type="text" id="new-username" required placeholder="Enter username">
</div>
<div class="form-group">
<label for="new-password">Password</label>
<input type="password" id="new-password" required placeholder="Enter password">
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="new-email">Email (optional)</label>
<input type="email" id="new-email" placeholder="Enter email">
</div>
<div class="form-group">
<label class="checkbox-label">
<input type="checkbox" id="new-is-admin"> Admin User
</label>
</div>
</div>
<button type="submit" class="create-user-btn">Create User</button>
</form>
</div>
<div class="users-list-section">
<h3>Existing Users</h3>
<div id="users-list" class="users-list">
<p class="no-data">Loading users...</p>
</div>
</div>
</div>
</div>
<!-- Gains/Losses Page -->
<div id="gains-losses-page" class="page">
<div class="gains-losses-container">
<h2>Gains & Losses</h2>
<div class="performance-summary">
<div class="performance-grid">
<div class="performance-card total-gains">
<h3>Total Gains/Losses</h3>
<div class="performance-value" id="total-performance">€0.00</div>
<div class="performance-percentage" id="total-percentage">0.0%</div>
</div>
<div class="performance-card unrealized-gains">
<h3>Unrealized P&L</h3>
<div class="performance-value" id="unrealized-performance">€0.00</div>
<div class="performance-percentage" id="unrealized-percentage">0.0%</div>
</div>
<div class="performance-card current-value">
<h3>Current Portfolio Value</h3>
<div class="performance-value" id="current-portfolio-value">€0.00</div>
<div class="performance-detail" id="last-updated">Not updated</div>
</div>
</div>
<div class="cgt-summary" id="cgt-summary" style="display: none;">
<h3>Capital Gains Tax Summary</h3>
<div class="cgt-grid">
<div class="cgt-card total-cgt">
<h4>Estimated CGT Liability</h4>
<div class="cgt-value" id="total-cgt-liability">€0.00</div>
<div class="cgt-detail" id="cgt-effective-rate">Effective rate: 0.0%</div>
</div>
<div class="cgt-card after-tax">
<h4>After-Tax Gains</h4>
<div class="cgt-value" id="after-tax-gains">€0.00</div>
<div class="cgt-detail" id="exemption-used">Exemption: €0 used</div>
</div>
<div class="cgt-card holding-summary">
<h4>Holdings by Tax Rate</h4>
<div class="holding-periods" id="holding-periods-summary">
<div class="period-item">
<span class="period-label">Short-term:</span>
<span class="period-value">€0.00</span>
</div>
<div class="period-item">
<span class="period-label">Long-term:</span>
<span class="period-value">€0.00</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="price-updates-section">
<h3>Update Current Prices</h3>
<div class="price-update-controls">
<button id="update-all-prices" class="update-all-btn">Update All Prices</button>
<span class="update-info">Enter current market prices to calculate gains/losses</span>
</div>
<div id="price-update-list" class="price-update-list">
<p class="no-data">No ETF positions to update</p>
</div>
</div>
<div class="gains-breakdown-section">
<h3>Individual Performance</h3>
<div id="gains-breakdown-list" class="gains-breakdown-list">
<p class="no-data">Update prices to see performance breakdown</p>
</div>
</div>
</div>
</div>
<!-- CGT Settings Page -->
<div id="cgt-settings-page" class="page">
<div class="cgt-settings-container">
<h2>Capital Gains Tax Settings</h2>
<div class="cgt-explanation">
<p>Configure your Capital Gains Tax rates based on holding periods. These rates will be used to calculate estimated tax liability on your realized and unrealized gains.</p>
</div>
<form id="cgt-settings-form" class="cgt-settings-form">
<h3>CGT Rate by Holding Period</h3>
<div class="cgt-rates-grid">
<div class="cgt-rate-item">
<label for="cgt-1month">0-1 Month (%)</label>
<input type="number" id="cgt-1month" min="0" max="100" step="0.1" value="40" class="cgt-rate-input">
</div>
<div class="cgt-rate-item">
<label for="cgt-6months">1-6 Months (%)</label>
<input type="number" id="cgt-6months" min="0" max="100" step="0.1" value="35" class="cgt-rate-input">
</div>
<div class="cgt-rate-item">
<label for="cgt-1year">6 Months-1 Year (%)</label>
<input type="number" id="cgt-1year" min="0" max="100" step="0.1" value="30" class="cgt-rate-input">
</div>
<div class="cgt-rate-item">
<label for="cgt-2years">1-2 Years (%)</label>
<input type="number" id="cgt-2years" min="0" max="100" step="0.1" value="20" class="cgt-rate-input">
</div>
<div class="cgt-rate-item">
<label for="cgt-longterm">2+ Years (%)</label>
<input type="number" id="cgt-longterm" min="0" max="100" step="0.1" value="10" class="cgt-rate-input">
</div>
</div>
<div class="cgt-options">
<h3>Additional Settings</h3>
<div class="form-group">
<label for="cgt-annual-exemption">Annual CGT Exemption (€)</label>
<input type="number" id="cgt-annual-exemption" min="0" step="1" value="1270" placeholder="0">
<small>Annual tax-free allowance for capital gains</small>
</div>
<div class="form-group">
<label class="checkbox-label">
<input type="checkbox" id="cgt-enabled" checked> Enable CGT calculations
</label>
</div>
</div>
<div class="cgt-actions">
<button type="submit" class="save-cgt-btn">Save CGT Settings</button>
<button type="button" id="reset-cgt-defaults" class="reset-cgt-btn">Reset to Defaults</button>
</div>
</form>
<div class="cgt-preview">
<h3>CGT Rate Preview</h3>
<div id="cgt-preview-chart" class="cgt-preview-chart">
<div class="rate-bar" data-period="1month">
<span class="period-label">0-1M</span>
<div class="rate-value">40%</div>
</div>
<div class="rate-bar" data-period="6months">
<span class="period-label">1-6M</span>
<div class="rate-value">35%</div>
</div>
<div class="rate-bar" data-period="1year">
<span class="period-label">6M-1Y</span>
<div class="rate-value">30%</div>
</div>
<div class="rate-bar" data-period="2years">
<span class="period-label">1-2Y</span>
<div class="rate-value">20%</div>
</div>
<div class="rate-bar" data-period="longterm">
<span class="period-label">2Y+</span>
<div class="rate-value">10%</div>
</div>
</div>
</div>
</div>
</div>
</main>
</div>
</div>
<script src="script.js"></script>
</body>
</html>