"""Portfolio domain models.""" from __future__ import annotations from dataclasses import dataclass from datetime import datetime from typing import Protocol, runtime_checkable @dataclass class StrategySet: id: str name: str config: str nick: str created_at: datetime | None = None @dataclass class User: id: str username: str email: str | None = None permission: str = "read" is_active: bool = True password_hash: str | None = None created_at: datetime | None = None updated_at: datetime | None = None last_login_at: datetime | None = None @dataclass class AuthToken: id: str user_id: str name: str token_prefix: str permission: str token_type: str expires_at: datetime | None = None last_used_at: datetime | None = None revoked_at: datetime | None = None created_at: datetime | None = None @dataclass class TokenPrincipal: token_id: str user_id: str permission: str token_type: str @dataclass class Portfolio: portfolio_id: str broker: str status: str symbol: str cash_balance: float = 0.0 asset_quantity: float = 0.0 price: float = 0.0 profit_buffer: float = 0.0 active_strategy_id: str | None = None avabile_strategies: list[str] | None = None created_at: datetime | None = None updated_at: datetime | None = None last_trade_at: datetime | None = None @dataclass class LedgerEntry: portfolio_id: str recorded_at: datetime action: str price: float quantity: float cash_balance_after: float asset_quantity_after: float total_value_after: float fee_amount: float = 0.0 tax_amount: float = 0.0 profit_buffer_after: float = 0.0 strategy_set_id: str = "legacy" note: str = "" @runtime_checkable class LiveAssetSource(Protocol): def get_asset_quantity(self, symbol: str) -> float: ...