# src/core_data.py

from dataclasses import dataclass, field
import pandas as pd
from typing import Dict, Any, List, Optional
import uuid  # 用于生成唯一订单ID


@dataclass()  #  使实例变为不可变
class Bar:
    """
    K线数据对象，包含期货或股票的 OHLCV 和持仓量信息。
    """
    datetime: pd.Timestamp
    open: float
    high: float
    low: float
    close: float
    volume: int
    open_oi: int  # 开盘持仓量 (Open Interest)
    close_oi: int  # 收盘持仓量
    symbol: str

    def __post_init__(self):
        """
        数据验证（可选）：确保持仓量为非负整数。
        """
        if self.volume < 0:
            raise ValueError(f"Volume must be a non-negative integer, got {self.volume}")
        if  self.open_oi < 0:
            raise ValueError(f"Open interest must be a non-negative integer, got {self.open_oi}")
        if self.close_oi < 0:
            raise ValueError(f"Close interest must be a non-negative integer, got {self.close_oi}")

        # 验证价格是否合理
        if not (self.high >= self.open and self.high >= self.close and \
                self.low <= self.open and self.low <= self.close and \
                self.high >= self.low):
            # 仅作警告，如果数据源可靠，可能不需要严格检查
            # print(f"Warning: Abnormal OHLC for bar at {self.datetime}")
            pass


@dataclass()
class Order:
    """
    代表一个待执行的交易指令。
    """
    symbol: str  # 暂时简化为单品种交易，可扩展
    direction: str  # "BUY", "SELL", "CLOSE_LONG", "CLOSE_SHORT"
    volume: int  # 交易数量
    id: str = field(default_factory=lambda: str(uuid.uuid4()))  # 唯一订单ID
    price_type: str = "MARKET"  # "MARKET", "LIMIT" (简易版默认市价)
    limit_price: Optional[float] = None  # 限价单价格
    submitted_time: pd.Timestamp = field(default_factory=pd.Timestamp.now)  # 订单提交时间
    offset: str = "OPEN"

    def __post_init__(self):
        if self.direction not in ["BUY", "SELL", "CLOSE_LONG", "CLOSE_SHORT", "CANCEL"]:
            raise ValueError(f"Invalid order direction: {self.direction}")
        if self.price_type not in ["MARKET", "LIMIT", "CANCEL"]:
            raise ValueError(f"Invalid price type: {self.price_type}")
        if not isinstance(self.volume, int) or self.volume < 0:
            raise ValueError(f"Order volume must be a positive integer, got {self.volume}")


@dataclass()
class Trade:
    """
    代表一个已完成的成交记录。
    """
    order_id: str
    fill_time: pd.Timestamp
    symbol: str
    direction: str  # "BUY", "SELL" (实际成交方向)
    volume: int
    price: float
    commission: float
    # 记录成交后的账户状态（可选，用于方便调试）
    cash_after_trade: float
    positions_after_trade: Dict[str, int]
    realized_pnl: float = 0.0 # <--- 新增字段：这笔交易带来的实现盈亏
    is_open_trade: bool = False # <--- 新增字段：是否是开仓交易（用于跟踪成本）
    is_close_trade: bool = False # <--- 新增字段：是否是平仓交易 (用于计算盈亏)


@dataclass()
class PortfolioSnapshot:
    """
    在特定时间点记录投资组合的快照。
    """
    datetime: pd.Timestamp
    total_value: float
    cash: float
    positions: Dict[str, int]  # {symbol: quantity}
    price_at_snapshot: Dict[str, float]  # {symbol: price}，用于计算市值

# 确保 Pandas Timestamp 的默认时区为None，或者在创建时明确指定
# pd.set_option('mode.chained_assignment', None) # 避免SettingWithCopyWarning