Initial release v1.1.0

- Complete MVP for tracking Fidelity brokerage account performance
- Transaction import from CSV with deduplication
- Automatic FIFO position tracking with options support
- Real-time P&L calculations with market data caching
- Dashboard with timeframe filtering (30/90/180 days, 1 year, YTD, all time)
- Docker-based deployment with PostgreSQL backend
- React/TypeScript frontend with TailwindCSS
- FastAPI backend with SQLAlchemy ORM

Features:
- Multi-account support
- Import via CSV upload or filesystem
- Open and closed position tracking
- Balance history charting
- Performance analytics and metrics
- Top trades analysis
- Responsive UI design

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Chris
2026-01-22 14:27:43 -05:00
commit eea4469095
90 changed files with 14513 additions and 0 deletions

View File

@@ -0,0 +1,41 @@
"""Account model representing a brokerage account."""
from sqlalchemy import Column, Integer, String, DateTime, Enum
from sqlalchemy.orm import relationship
from sqlalchemy.sql import func
import enum
from app.database import Base
class AccountType(str, enum.Enum):
"""Enumeration of account types."""
CASH = "cash"
MARGIN = "margin"
class Account(Base):
"""
Represents a brokerage account.
Attributes:
id: Primary key
account_number: Unique account identifier
account_name: Human-readable account name
account_type: Type of account (cash or margin)
created_at: Timestamp of account creation
updated_at: Timestamp of last update
transactions: Related transactions
positions: Related positions
"""
__tablename__ = "accounts"
id = Column(Integer, primary_key=True, index=True)
account_number = Column(String(50), unique=True, nullable=False, index=True)
account_name = Column(String(200), nullable=False)
account_type = Column(Enum(AccountType), nullable=False, default=AccountType.CASH)
created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
updated_at = Column(DateTime(timezone=True), onupdate=func.now(), server_default=func.now(), nullable=False)
# Relationships
transactions = relationship("Transaction", back_populates="account", cascade="all, delete-orphan")
positions = relationship("Position", back_populates="account", cascade="all, delete-orphan")