"""Portfolio domain models.""" from __future__ import annotations from dataclasses import dataclass from datetime import datetime from enum import Enum from typing import Protocol, runtime_checkable class MarketCode(str, Enum): KRX = "KRX" NXT = "NXT" SOR = "SOR" NASDAQ = "NASDAQ" NYSE = "NYSE" UPBIT = "UPBIT" BITHUMB = "BITHUMB" @dataclass class Asset: asset_id: str symbol: str markets: list[str] display_name: str | None = None status: str = "active" created_at: datetime | None = None updated_at: datetime | None = None @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 Daemon: id: str owner_user_id: str daemon_slug: str display_name: str | None = None is_active: bool = True created_at: datetime | None = None updated_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 runtime_id: str | None = None daemon_id: str | None = None @dataclass class TokenPrincipal: token_id: str user_id: str permission: str token_type: str runtime_id: str | None = None daemon_id: str | None = None @dataclass class Portfolio: portfolio_id: str broker: str status: str name: str symbol: str asset_id: str | None = None tags: list[str] | None = None owner_user_id: str | None = None 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 managed_by_daemon_id: str | 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 = "" @dataclass class PortfolioComment: id: str portfolio_id: str content: str created_at: datetime | None = None updated_at: datetime | None = None @dataclass class PortfolioTag: portfolio_id: str tag: str created_at: datetime | None = None @runtime_checkable class LiveAssetSource(Protocol): def get_asset_quantity(self, symbol: str) -> float: ... @dataclass class BrokerCredential: user_id: str broker: str account_ref: str encrypted_payload: str credential_version: int = 1 last_rotated_at: datetime | None = None @dataclass class LedgerTrade: ledger_entry_id: int asset_id: str order_id: str execution_id: str side: str quantity: float price: float fee_amount: float tax_amount: float executed_at: datetime recorded_at: datetime | None = None