from typing import List, Dict, Any, Optional from pydantic import BaseModel, Field class ControlPoint(BaseModel): """A control point for a drawing shape. Control points define the position and properties of a shape. Different shapes have different numbers of control points. """ time: int = Field(..., description="Unix timestamp in seconds") price: float = Field(..., description="Price level") # Optional channel for multi-point shapes (e.g., parallel channels) channel: Optional[str] = Field(default=None, description="Channel identifier for multi-point shapes") class Shape(BaseModel): """A TradingView drawing shape/study. Represents any drawing the user creates on the chart (trendlines, horizontal lines, rectangles, Fibonacci retracements, etc.) """ id: str = Field(..., description="Unique identifier for the shape") type: str = Field(..., description="Shape type (e.g., 'trendline', 'horizontal_line', 'rectangle', 'fibonacci')") points: List[ControlPoint] = Field(default_factory=list, description="Control points that define the shape") # Visual properties color: Optional[str] = Field(default=None, description="Shape color (hex or color name)") line_width: Optional[int] = Field(default=1, description="Line width in pixels") line_style: Optional[str] = Field(default="solid", description="Line style: 'solid', 'dashed', 'dotted'") # Shape-specific properties stored as flexible dict properties: Dict[str, Any] = Field(default_factory=dict, description="Additional shape-specific properties") # Metadata symbol: Optional[str] = Field(default=None, description="Symbol this shape is drawn on") created_at: Optional[int] = Field(default=None, description="Creation timestamp (Unix seconds)") modified_at: Optional[int] = Field(default=None, description="Last modification timestamp (Unix seconds)") original_id: Optional[str] = Field(default=None, description="Original ID from backend/agent before TradingView assigns its own ID") class ShapeCollection(BaseModel): """Collection of all shapes/drawings on the chart.""" shapes: Dict[str, Shape] = Field(default_factory=dict, description="Dictionary of shapes keyed by ID")