""" Trading journal Pydantic schemas. """ from datetime import date, datetime from decimal import Decimal from typing import Optional from enum import Enum from pydantic import BaseModel, Field from app.schemas.portfolio import FloatDecimal class TradeType(str, Enum): BUY = "buy" SELL = "sell" class JournalStatus(str, Enum): OPEN = "open" CLOSED = "closed" class TradeJournalCreate(BaseModel): stock_code: str = Field(..., min_length=1, max_length=20) stock_name: Optional[str] = Field(None, max_length=100) trade_type: TradeType entry_price: Optional[FloatDecimal] = Field(None, gt=0) target_price: Optional[FloatDecimal] = Field(None, gt=0) stop_loss_price: Optional[FloatDecimal] = Field(None, gt=0) entry_date: date quantity: Optional[int] = Field(None, gt=0) entry_reason: Optional[str] = None scenario: Optional[str] = None emotional_state: Optional[str] = None strategy_id: Optional[int] = None class TradeJournalUpdate(BaseModel): stock_name: Optional[str] = Field(None, max_length=100) exit_price: Optional[FloatDecimal] = Field(None, gt=0) exit_date: Optional[date] = None exit_reason: Optional[str] = None target_price: Optional[FloatDecimal] = Field(None, gt=0) stop_loss_price: Optional[FloatDecimal] = Field(None, gt=0) quantity: Optional[int] = Field(None, gt=0) lessons_learned: Optional[str] = None emotional_state: Optional[str] = None scenario: Optional[str] = None entry_reason: Optional[str] = None status: Optional[JournalStatus] = None class TradeJournalResponse(BaseModel): id: int user_id: int stock_code: str stock_name: Optional[str] = None trade_type: str entry_price: Optional[FloatDecimal] = None target_price: Optional[FloatDecimal] = None stop_loss_price: Optional[FloatDecimal] = None exit_price: Optional[FloatDecimal] = None entry_date: date exit_date: Optional[date] = None quantity: Optional[int] = None profit_loss: Optional[FloatDecimal] = None profit_loss_pct: Optional[FloatDecimal] = None entry_reason: Optional[str] = None exit_reason: Optional[str] = None scenario: Optional[str] = None lessons_learned: Optional[str] = None emotional_state: Optional[str] = None strategy_id: Optional[int] = None status: str created_at: datetime updated_at: datetime class Config: from_attributes = True class TradeJournalStats(BaseModel): total_trades: int = 0 open_trades: int = 0 closed_trades: int = 0 win_count: int = 0 loss_count: int = 0 win_rate: Optional[FloatDecimal] = None avg_profit_loss_pct: Optional[FloatDecimal] = None max_profit_pct: Optional[FloatDecimal] = None max_loss_pct: Optional[FloatDecimal] = None total_profit_loss: Optional[FloatDecimal] = None