"""
RSI divergence reversal strategy for gold
Auto-generated by StrategyCodeGenerator.
Strategy ID: rsi_divergence_reversal_strategy_for_gol
"""
from strategy_sdk.interfaces import StrategyPlugin
from strategy_sdk.types import (
    MarketSnapshot,
    PortfolioStateView,
    StrategyInitContext,
    StrategyIntent,
    StrategyManifest,
    StrategyRiskOpinion,
)


class RsiDivergenceReversalStrategyForGol(StrategyPlugin):
    """RSI divergence reversal strategy for gold"""

    def __init__(self, params=None):
        self._params = params or {}
        self._ctx = None

    def manifest(self):
        return StrategyManifest(
            strategy_id="rsi_divergence_reversal_strategy_for_gol",
            name="RSI divergence reversal strategy for gold",
            version="1.0.0",
            kind="signal",
            entrypoint="strategies.rsi_divergence_reversal_strategy_for_gol",
            description="RSI divergence reversal strategy for gold",
            author="AI",
            tags=[["ai-generated"]],
            capabilities=[["intraday"]],
            supported_symbols=["XAUUSD"],
            supported_timeframes=["M5", "M15", "H1"],
            params_schema={"ema_short": {"type": "int", "default": 9, "range": [5, 20]}, "ema_long": {"type": "int", "default": 21, "range": [15, 50]}, "atr_period": {"type": "int", "default": 14, "range": [7, 21]}},
            default_mode="plugin",
            trust_level="sandbox",
        )

    def initialize(self, ctx: StrategyInitContext) -> None:
        self._ctx = ctx
        self._params.update(ctx.config)

    def on_market_snapshot(self, snapshot: MarketSnapshot) -> StrategyIntent:
        bars = snapshot.bars
        if not bars or len(bars) < 30:
            return StrategyIntent(
                strategy_id=self.manifest().strategy_id,
                strategy_version="1.0.0",
                config_revision="sandbox",
                instance_id="rsi",
                action="HOLD",
                side="BUY",
                confidence=0.0,
                reason="insufficient bars",
            )

        closes = [float(b.get("close", 0)) for b in bars]
        highs = [float(b.get("high", 0)) for b in bars]
        lows = [float(b.get("low", 0)) for b in bars]
        n = len(closes)
        atr_period = int(self._params.get("atr_period", 14))
        rsi_period = int(self._params.get("ema_short", 14))
        rsi_oversold = 35
        rsi_overbought = 65

        # Simple RSI
        gains = sum(max(closes[i] - closes[i-1], 0) for i in range(max(n - rsi_period, 0), n))
        losses = sum(max(closes[i-1] - closes[i], 0) for i in range(max(n - rsi_period, 0), n))
        rs = gains / losses if losses > 0 else 100
        rsi = 100 - 100 / (1 + rs) if losses > 0 else 50

        entry = closes[-1]
        atr = sum(h - l for h, l in zip(highs[-atr_period:], lows[-atr_period:])) / atr_period

        if rsi < rsi_oversold and closes[-1] > closes[-2]:
            return StrategyIntent(
                strategy_id=self.manifest().strategy_id,
                strategy_version="1.0.0",
                config_revision="sandbox",
                instance_id="rsi",
                action="BUY",
                side="BUY",
                confidence=0.70,
                reason=f"RSI divergence bullish (RSI={rsi:.0f})",
                entry_plan={"entry": entry},
                exit_plan={"sl": entry - 1.5 * atr, "tp": entry + 3.0 * atr},
            )
        if rsi > rsi_overbought and closes[-1] < closes[-2]:
            return StrategyIntent(
                strategy_id=self.manifest().strategy_id,
                strategy_version="1.0.0",
                config_revision="sandbox",
                instance_id="rsi",
                action="SELL",
                side="SELL",
                confidence=0.70,
                reason=f"RSI overbought bearish (RSI={rsi:.0f})",
                entry_plan={"entry": entry},
                exit_plan={"sl": entry + 1.5 * atr, "tp": entry - 3.0 * atr},
            )
        return StrategyIntent(
            strategy_id=self.manifest().strategy_id,
            strategy_version="1.0.0",
            config_revision="sandbox",
            instance_id="rsi",
            action="HOLD",
            side="BUY",
            confidence=0.0,
            reason=f"no divergence (RSI={rsi:.0f})",
        )

    def on_risk_check(
        self,
        intent: StrategyIntent,
        portfolio: PortfolioStateView,
    ) -> StrategyRiskOpinion:
        # NOTE: allow=True by design. Per-strategy risk opinions are advisory only.
        # Hard blocking (circuit breaker, daily loss, session filter, spread, position
        # limits) is enforced centrally by bridge/risk_manager.py.
        reasons = []
        if intent.action == "HOLD":
            return StrategyRiskOpinion(allow=True, reasons=["no action"])
        if intent.confidence < 0.5:
            reasons.append("low confidence")
        if portfolio.position_side != "FLAT" and portfolio.position_side == intent.side:
            reasons.append("already positioned")
        if not reasons:
            reasons.append("signal OK")
        return StrategyRiskOpinion(
            allow=True,
            severity="WARN" if reasons else "INFO",
            score=intent.confidence,
            reasons=reasons,
        )

    def shutdown(self) -> None:
        pass
