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,14 @@
"""Pydantic schemas for API request/response validation."""
from app.schemas.account import AccountCreate, AccountUpdate, AccountResponse
from app.schemas.transaction import TransactionCreate, TransactionResponse
from app.schemas.position import PositionResponse, PositionStats
__all__ = [
"AccountCreate",
"AccountUpdate",
"AccountResponse",
"TransactionCreate",
"TransactionResponse",
"PositionResponse",
"PositionStats",
]

View File

@@ -0,0 +1,34 @@
"""Pydantic schemas for account-related API operations."""
from pydantic import BaseModel, Field
from datetime import datetime
from typing import Optional
from app.models.account import AccountType
class AccountBase(BaseModel):
"""Base schema for account data."""
account_number: str = Field(..., description="Unique account identifier")
account_name: str = Field(..., description="Human-readable account name")
account_type: AccountType = Field(default=AccountType.CASH, description="Account type")
class AccountCreate(AccountBase):
"""Schema for creating a new account."""
pass
class AccountUpdate(BaseModel):
"""Schema for updating an existing account."""
account_name: Optional[str] = Field(None, description="Updated account name")
account_type: Optional[AccountType] = Field(None, description="Updated account type")
class AccountResponse(AccountBase):
"""Schema for account API responses."""
id: int
created_at: datetime
updated_at: datetime
class Config:
from_attributes = True

View File

@@ -0,0 +1,45 @@
"""Pydantic schemas for position-related API operations."""
from pydantic import BaseModel, Field
from datetime import date, datetime
from typing import Optional
from decimal import Decimal
from app.models.position import PositionType, PositionStatus
class PositionBase(BaseModel):
"""Base schema for position data."""
symbol: str
option_symbol: Optional[str] = None
position_type: PositionType
status: PositionStatus
open_date: date
close_date: Optional[date] = None
total_quantity: Decimal
avg_entry_price: Optional[Decimal] = None
avg_exit_price: Optional[Decimal] = None
realized_pnl: Optional[Decimal] = None
unrealized_pnl: Optional[Decimal] = None
class PositionResponse(PositionBase):
"""Schema for position API responses."""
id: int
account_id: int
created_at: datetime
updated_at: datetime
class Config:
from_attributes = True
class PositionStats(BaseModel):
"""Schema for aggregate position statistics."""
total_positions: int = Field(..., description="Total number of positions")
open_positions: int = Field(..., description="Number of open positions")
closed_positions: int = Field(..., description="Number of closed positions")
total_realized_pnl: Decimal = Field(..., description="Total realized P&L")
total_unrealized_pnl: Decimal = Field(..., description="Total unrealized P&L")
win_rate: float = Field(..., description="Percentage of profitable trades")
avg_win: Decimal = Field(..., description="Average profit on winning trades")
avg_loss: Decimal = Field(..., description="Average loss on losing trades")

View File

@@ -0,0 +1,44 @@
"""Pydantic schemas for transaction-related API operations."""
from pydantic import BaseModel, Field
from datetime import date, datetime
from typing import Optional
from decimal import Decimal
class TransactionBase(BaseModel):
"""Base schema for transaction data."""
run_date: date
action: str
symbol: Optional[str] = None
description: Optional[str] = None
transaction_type: Optional[str] = None
exchange_quantity: Optional[Decimal] = None
exchange_currency: Optional[str] = None
currency: Optional[str] = None
price: Optional[Decimal] = None
quantity: Optional[Decimal] = None
exchange_rate: Optional[Decimal] = None
commission: Optional[Decimal] = None
fees: Optional[Decimal] = None
accrued_interest: Optional[Decimal] = None
amount: Optional[Decimal] = None
cash_balance: Optional[Decimal] = None
settlement_date: Optional[date] = None
class TransactionCreate(TransactionBase):
"""Schema for creating a new transaction."""
account_id: int
unique_hash: str
class TransactionResponse(TransactionBase):
"""Schema for transaction API responses."""
id: int
account_id: int
unique_hash: str
created_at: datetime
updated_at: datetime
class Config:
from_attributes = True