"""
Iceberg / TWAP detection strategy.

Large traders often split big orders into small slices to avoid
slippage. This strategy detects those patterns by watching for
recurring same-sized trades above average volume, then enters
in the same direction.
"""
from collections import deque
from nautilus_trader.trading.strategy import Strategy
from nautilus_trader.config import StrategyConfig


class IcebergDetectorConfig(StrategyConfig, frozen=True):
    instrument_id: str
    lookback_seconds: int = 300
    volume_spike_mult: float = 3.0
    min_slices: int = 4
    trade_size: float = 0.001


class IcebergDetector(Strategy):
    """
    Detects iceberg/TWAP execution patterns.

    Logic:
    1. Track trade sizes in a rolling window
    2. When a trade is much larger than average, flag it
    3. If same size repeats N times -> confirmed iceberg
    4. Trade in the same direction
    """

    def __init__(self, config: IcebergDetectorConfig) -> None:
        super().__init__(config)
        self.config = config
        self.recent_sizes: deque[float] = deque(maxlen=100)
        self.slice_count = 0
        self.last_flagged_size: float | None = None

    def on_start(self) -> None:
        self.subscribe_trade_ticks(self.config.instrument_id)
        self.log.info(f"Iceberg detector started on {self.config.instrument_id}")

    def on_trade_tick(self, tick) -> None:
        self.recent_sizes.append(tick.size)
        avg = sum(self.recent_sizes) / len(self.recent_sizes) if self.recent_sizes else 0

        if tick.size > avg * self.config.volume_spike_mult:
            if tick.size == self.last_flagged_size:
                self.slice_count += 1
            else:
                self.slice_count = 1
                self.last_flagged_size = tick.size
        else:
            self.slice_count = 0

        if self.slice_count >= self.config.min_slices:
            self.log.info(
                f"Iceberg: {self.slice_count} slices of size {self.last_flagged_size}"
            )
            self.submit_order(self.order_factory.market(
                instrument_id=self.config.instrument_id,
                order_side="BUY" if tick.is_buyer_maker else "SELL",
                quantity=self.config.trade_size,
            ))
            self.slice_count = 0
