MyMidas/backend/app/schemas/investment.py
megaproxy 61a7884ee5 Initial commit: MyMidas personal finance tracker
Full-stack self-hosted finance app with FastAPI backend and React frontend.

Features:
- Accounts, transactions, budgets, investments with GBP base currency
- CSV import with auto-detection for 10 UK bank formats
- ML predictions: spending forecast, net worth projection, Monte Carlo
- 7 selectable themes (Obsidian, Arctic, Midnight, Vault, Terminal, Synthwave, Ledger)
- Receipt/document attachments on transactions (JPEG, PNG, WebP, PDF)
- AES-256-GCM field encryption, RS256 JWT, TOTP 2FA, RLS, audit log
- Encrypted nightly backups + key rotation script
- Mobile-responsive layout with bottom nav

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 11:56:10 +00:00

103 lines
2.4 KiB
Python

import uuid
from datetime import date as DateType, datetime
from decimal import Decimal
from typing import Literal
from pydantic import BaseModel, Field
InvestmentTxnType = Literal["buy", "sell", "dividend", "split", "fee", "transfer_in", "transfer_out"]
class AssetSearch(BaseModel):
id: uuid.UUID
symbol: str
name: str
type: str
currency: str
exchange: str | None
last_price: Decimal | None
price_change_24h: Decimal | None
data_source: str
model_config = {"from_attributes": True}
class AssetPricePoint(BaseModel):
date: DateType
open: Decimal | None
high: Decimal | None
low: Decimal | None
close: Decimal
volume: Decimal | None
model_config = {"from_attributes": True}
class HoldingCreate(BaseModel):
account_id: uuid.UUID
asset_id: uuid.UUID
quantity: Decimal = Field(..., gt=0)
avg_cost_basis: Decimal = Field(..., ge=0)
currency: str = Field(default="GBP", min_length=3, max_length=10)
class HoldingResponse(BaseModel):
id: uuid.UUID
account_id: uuid.UUID
asset_id: uuid.UUID
symbol: str
asset_name: str
asset_type: str
quantity: Decimal
avg_cost_basis: Decimal
current_price: Decimal | None
current_value: Decimal | None
cost_basis_total: Decimal
unrealised_gain: Decimal | None
unrealised_gain_pct: Decimal | None
currency: str
price_change_24h: Decimal | None
model_config = {"from_attributes": True}
class InvestmentTxnCreate(BaseModel):
holding_id: uuid.UUID
type: InvestmentTxnType
quantity: Decimal = Field(..., ge=0)
price: Decimal = Field(..., ge=0)
fees: Decimal = Field(default=Decimal("0"), ge=0)
currency: str = Field(default="GBP", min_length=3, max_length=10)
date: DateType
notes: str | None = None
class InvestmentTxnResponse(BaseModel):
id: uuid.UUID
holding_id: uuid.UUID
type: str
quantity: Decimal
price: Decimal
fees: Decimal
total_amount: Decimal
currency: str
date: DateType
created_at: datetime
model_config = {"from_attributes": True}
class PortfolioSummary(BaseModel):
total_value: Decimal
total_cost: Decimal
total_gain: Decimal
total_gain_pct: Decimal
currency: str
holdings: list[HoldingResponse]
class PerformanceMetrics(BaseModel):
twrr: Decimal | None
total_return: Decimal
total_return_pct: Decimal
currency: str