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

94
backend/seed_demo_data.py Normal file
View File

@@ -0,0 +1,94 @@
"""
Demo data seeder script.
Creates a sample account and imports the provided CSV file.
"""
import sys
from pathlib import Path
# Add parent directory to path
sys.path.insert(0, str(Path(__file__).parent))
from sqlalchemy.orm import Session
from app.database import SessionLocal, engine, Base
from app.models import Account
from app.services import ImportService
from app.services.position_tracker import PositionTracker
def seed_demo_data():
"""Seed demo account and transactions."""
print("🌱 Seeding demo data...")
# Create tables
Base.metadata.create_all(bind=engine)
# Create database session
db = SessionLocal()
try:
# Check if demo account already exists
existing = (
db.query(Account)
.filter(Account.account_number == "DEMO123456")
.first()
)
if existing:
print("✅ Demo account already exists")
demo_account = existing
else:
# Create demo account
demo_account = Account(
account_number="DEMO123456",
account_name="Demo Trading Account",
account_type="margin",
)
db.add(demo_account)
db.commit()
db.refresh(demo_account)
print(f"✅ Created demo account (ID: {demo_account.id})")
# Check for CSV file
csv_path = Path("/app/imports/History_for_Account_X38661988.csv")
if not csv_path.exists():
# Try alternative path (development)
csv_path = Path(__file__).parent.parent / "History_for_Account_X38661988.csv"
if not csv_path.exists():
print("⚠️ Sample CSV file not found. Skipping import.")
print(" Place the CSV file in /app/imports/ to seed demo data.")
return
# Import transactions
print(f"📊 Importing transactions from {csv_path.name}...")
import_service = ImportService(db)
result = import_service.import_from_file(csv_path, demo_account.id)
print(f"✅ Imported {result.imported} transactions")
print(f" Skipped {result.skipped} duplicates")
if result.errors:
print(f" ⚠️ {len(result.errors)} errors occurred")
# Build positions
if result.imported > 0:
print("📈 Building positions...")
position_tracker = PositionTracker(db)
positions_created = position_tracker.rebuild_positions(demo_account.id)
print(f"✅ Created {positions_created} positions")
print("\n🎉 Demo data seeded successfully!")
print(f"\n📝 Demo Account Details:")
print(f" Account Number: {demo_account.account_number}")
print(f" Account Name: {demo_account.account_name}")
print(f" Account ID: {demo_account.id}")
except Exception as e:
print(f"❌ Error seeding demo data: {e}")
db.rollback()
raise
finally:
db.close()
if __name__ == "__main__":
seed_demo_data()