Skip to content
This repository was archived by the owner on Jan 14, 2026. It is now read-only.

Assignment 8

Choose a tag to compare

@jasonfyw jasonfyw released this 13 Nov 02:49
· 7 commits to master since this release
2c6b9e4

What's Changed

Full Changelog: 0.6.0...v0.6.0

Progress

Direct Links to Submitted Files

Backend API Files

Frontend Web Files

Roadmap Update

Our team has made significant progress on CUJ 1: Investment Portfolio Tracking, successfully implementing the core portfolio management functionality. This release delivers a complete end-to-end portfolio tracking system that allows users to add positions, view their holdings, and analyze portfolio performance through interactive charts and analytics. We've built a robust backend API using FastAPI and SQLAlchemy that handles position management, pricing based on real data from Yahoo Finance, currency conversion, and historical portfolio valuation snapshots. The frontend implements the mockups and provides an intuitive interface with dark mode support and responsive charts. Key technical achievements include implementing a snapshot system for historical portfolio valuations and creating reusable chart components for portfolio visualization. This milestone establishes the foundation for our financial education platform and demonstrates our ability to integrate complex financial data with a modern web application.

Issues Summary

This release closes the following issues: #6 #7 #12 #16 #17 #18

In doing so, our team has addressed several technical challenges and improvements:

  • Database Error Fixes: Resolved issues with portfolio snapshot generation and database query optimization
  • Chart Loading Improvements: Enhanced chart components with proper loading states and skeleton screens to improve perceived performance

Roadmap, Architecture, and Use Cases Changes

Architecture Changes

We have formalized our database and ORM decision through ADR 009: Database, Authentication, and ORM – Supabase and SQLAlchemy. This decision establishes Supabase as our authentication and database platform, with SQLAlchemy as our Python-native ORM. This simplifies our architecture by leveraging Supabase's built-in authentication and database capabilities while maintaining flexibility with SQLAlchemy for complex queries and data modeling.

The portfolio tracking feature introduces several new architectural components:

  • Portfolio Service Layer: Handles position computation using average cost method, portfolio analytics, and allocation calculations
  • Snapshots System: Implements a time-series database pattern for storing historical portfolio valuations at different granularities (hourly, 6-hourly, daily, weekly)
  • Historical Price Service: Integrates with yfinance to fetch historical prices for accurate portfolio valuation at any point in time
  • FX Conversion Service: Handles multi-currency portfolios with historical and real-time foreign exchange rate conversion

Use Cases

No changes to use cases were made in this release. CUJ 1 remains as specified: users can add positions from the dashboard or portfolio page, enter ticker symbols with quantity and average cost, and view updated portfolio analytics with real-time price data.

Roadmap Change Details

Architecture

New Components Introduced:

  1. Portfolio Valuation Snapshot System: A time-series storage system that captures portfolio valuations at regular intervals. This system supports multiple granularities (hourly, 6-hourly, daily, weekly) and automatically generates missing snapshots when requested. The implementation uses historical price data to calculate accurate portfolio values at any point in time.

  2. Position Management Service: A service layer that computes positions from transactions using the average cost method. This handles buy/sell transactions, maintains average cost basis, and calculates unrealized P/L and daily P/L for each position.

  3. Historical Price Integration: Integration with yfinance API to fetch historical prices for accurate portfolio valuation snapshots. The system falls back to latest prices when historical data is unavailable.

Database Schema Extensions:

  • PortfolioValuationSnapshot model for storing time-series portfolio valuations
  • Enhanced Transaction model with FX rate tracking
  • Instrument model with currency and sector information

UI/UX

New Pages and Components:

  1. Portfolio Page (/portfolio): A comprehensive portfolio view featuring:

    • Interactive portfolio value chart with time range selection (1D, 1W, 1M, YTD, 1Y)
    • Asset allocation pie chart showing distribution by instrument type
    • Summary cards displaying total value, total gain/loss, and daily change
    • Detailed holdings table with position-level analytics
    • Add position button with modal dialog
  2. Dashboard Page (/dashboard): A simplified dashboard view showing:

    • Portfolio value chart with overlay displaying current value and daily percentage change
    • Clean, focused interface for quick portfolio overview
  3. Add Position Dialog: A modal form for adding new positions with:

    • Ticker symbol input with validation
    • Quantity and average cost inputs
    • Optional execution date/time field
    • Inline error handling and loading states
  4. Value Chart Component: A reusable chart component featuring:

    • Responsive line chart using Recharts
    • Time range selector (1D, 1W, 1M, YTD, 1Y)
    • Refresh button for manual snapshot generation
    • Optional overlay for displaying current value and percentage change
    • Dark mode support with theme-aware styling
    • Skeleton loading states for better perceived performance
  5. Allocation Chart Component: A reusable pie chart component showing:

    • Asset allocation by type (equity, ETF, crypto)
    • Custom color scheme with legend
    • Responsive design

Additional Technical Decisions:

  1. Average Cost Method for Position Tracking: Chose average cost method over FIFO/LIFO for its simplicity and beginner-friendliness. This method calculates the average purchase price of all shares, making it easier for users to understand their cost basis.

  2. Snapshot-Based Historical Valuations: Decided to store discrete snapshots rather than recalculating on-demand. This approach provides faster query performance and allows for accurate historical analysis, though it requires more storage.

  3. Granularity-Based Snapshot Filtering: Implemented client-side filtering of snapshots by granularity rather than generating separate snapshots for each granularity level. This reduces storage requirements while maintaining flexibility.

  4. Dark Mode as First-Class Feature: Implemented dark mode support from the start rather than as an afterthought. This ensures consistent theming across all components and better user experience.

Milestone Update

CUJ 1: Investment Portfolio Tracking - COMPLETED

All functional requirements for CUJ 1 have been successfully implemented:

  • ✅ FR1.1: User can open "Add Position" form from the Dashboard or Portfolio page
  • ✅ FR1.2: Form includes fields for Ticker, Quantity, and Average Cost with inline validation
  • ✅ FR1.3: On submission, the portfolio view updates immediately with the new position
  • ✅ FR1.4: If form errors occur, clear error messages appear inline
  • ✅ FR1.5: Portfolio page shows updated table of positions
  • ✅ FR1.6: Analytics section displays portfolio totals, breakdowns, and trend chart

Non-Functional Requirements:

  • ✅ Portfolio page loads efficiently with proper loading states
  • ✅ Table and charts are responsive for desktop and mobile
  • ✅ Consistent typography/colors with design system (Mantine)

Next Steps:

  • Begin work on CUJs 2, 3, and 4
  • Implement full user onboarding quiz functionality
  • Design learning module structure and content delivery system

Jobs to be Done (JTBD)

JTBD 1: "As a beginner investor, I want to add my holdings and see real-time portfolio analytics, so that I can understand my overall performance and diversification."

Status: ✅ COMPLETED

This job is fully addressed by CUJ 1. Users can now:

  • Add positions through an intuitive dialog form
  • View their complete portfolio holdings in a detailed table
  • See real-time portfolio analytics including:
    • Total portfolio value
    • Total gain/loss (unrealized P/L)
    • Daily change with percentage
    • Asset allocation breakdown by type
    • Position-level analytics (market price, value, daily P/L, unrealized P/L)
  • Visualize portfolio performance over time with interactive charts
  • View historical portfolio valuations with multiple time range options

User Value Delivered:

  • Immediate feedback when adding positions
  • Clear visualization of portfolio composition
  • Real-time price updates and performance metrics
  • Historical context through time-series charts
  • Multi-currency support for international portfolios

Remaining JTBDs:

  • JTBD 2: Personalized Learning Pathway (Next milestone)
  • JTBD 3: Quiz-based Learning (Planned)
  • JTBD 4: AI-powered Learning Suggestions (Planned)
  • JTBD 5: Gamification and Streaks (Planned

User testing

Goal: As a beginner investor, I want to add my holdings and see real-time portfolio analytics, so that I can understand my overall performance and diversification.

Tools used: Google Chrome and FinQuest

Persona description: UofT student studying history and economics, age 23, new FinQuest user with a low level of investing experience and moderate financial literacy

Summary of findings: The only instruction given to the user was to navigate to the website, create an account, and add a holding to their profile. The user was easily able to sign up for an account using Google. They were then prompted with the onboarding form, which they completed after a few minutes. Because the form did not redirect to the dashboard when submitted, intervention was required to navigate to the dashboard page. Then, the user navigated to the portfolio page and, after scrolling around the page, opened the add position form using the "Add Position" button. The user was able to successfully fill out the form and completed the task by successfully adding a new position.

The user commented that the signup process was straightforward and convenient. They stated that the onboarding form was good for the most part but lacked polish because of the missing redirect. They noted that the portfolio looked professional and had good visuals, but noted that the holdings table included a lot of data at first glance. Moreover, they noted that the new holdings form lacked a ticker search functionality, instead requiring the user to know the ticker symbol beforehand.

Recommendations:

  • ensure the onbording form redirects to the dashboard page on completion
  • make the holdings table in the portfolio page more minimal and readable
  • add ticker search function in the new holdings form, with semantic search such as searching by company name