# source: https://raw.githubusercontent.com/Aatif-qmr/cipher/f3735aaf3655923bb1c8ee70c054c6a1a0d8831d/strategies/archive/BearScalpV1.py
# directory_url: https://github.com/Aatif-qmr/cipher/blob/main/strategies/archive/
# User: Aatif-qmr
# Repository: cipher
# --------------------import json
import logging
import sys
from datetime import datetime
from pathlib import Path

from pandas import DataFrame

# Resolve project root from this file's location (works on any machine)
_BASE = Path(__file__).resolve().parent.parent.parent
if str(_BASE) not in sys.path:
    sys.path.insert(0, str(_BASE))

from freqtrade.strategy import IStrategy

from qnt.oracle.hmm_regime import detect_regime
from qnt.thesis.thesis_reader import read_thesis
from risk.risk_manager import run_all_checks
from risk.stake_sizer import get_stake_multiplier
from sentiment.reader import get_current_sentiment

logger = logging.getLogger(__name__)


class Github_Aatif_qmr_cipher__BearScalpV1__20260901_081406(IStrategy):
    """
    Short-only scalp strategy. Activates exclusively when HMM detects BEAR regime.
    Entry: RSI > 70 + close > BB_upper + BEAR regime confirmed.
    Exit: RSI < 50 OR close < BB_middle (2-candle persistence).
    Complements ScalpV1 (long) to exploit both sides of the market.
    """

    INTERFACE_VERSION = 3
    can_short = True

    timeframe = "5m"
    stoploss = -0.02
    trailing_stop = True
    trailing_stop_positive = 0.01
    trailing_stop_positive_offset = 0.015

    minimal_roi = {
        "0": 0.02,
        "30": 0.015,
        "60": 0.01,
        "120": 0.005,
    }

    startup_candle_count: int = 30

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        from qnt.polars_indicators import add_bollinger_bands, add_rsi, add_sma
        from qnt.polars_ohlcv import ohlcv_to_pandas, pandas_to_polars

        df_pl = pandas_to_polars(dataframe)

        df_pl = add_rsi(df_pl, period=14, alias="rsi")
        df_pl = add_bollinger_bands(df_pl, period=20, std_dev=2.0, prefix="bb")
        df_pl = df_pl.rename({"bb_mid": "bb_middle"})
        df_pl = add_sma(df_pl, period=20, column="volume", alias="volume_avg")

        dataframe = ohlcv_to_pandas(df_pl)
        return dataframe

    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        sentiment = get_current_sentiment()
        regime = detect_regime(dataframe, metadata["pair"])

        # Only short in confirmed BEAR regime
        bear_confirmed = regime == "BEAR"

        dataframe.loc[
            (
                bear_confirmed
                & (dataframe["rsi"] > 70)
                & (dataframe["close"] > dataframe["bb_upper"])
                & (dataframe["volume"] > dataframe["volume_avg"])
                & (sentiment["score"] <= 0.3)  # not strongly bullish
            ),
            "enter_short",
        ] = 1

        return dataframe

    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        raw_exit = (dataframe["rsi"] < 50) | (dataframe["close"] < dataframe["bb_middle"])
        # 2-candle persistence — same whipsaw protection as long strategies
        dataframe.loc[raw_exit & raw_exit.shift(1).fillna(False), "exit_short"] = 1
        return dataframe

    def custom_stake_amount(
        self,
        current_time,
        current_rate,
        proposed_stake,
        min_stake,
        max_stake,
        leverage,
        entry_tag,
        side,
        **kwargs,
    ):
        multiplier = get_stake_multiplier("Github_Aatif_qmr_cipher__BearScalpV1__20260901_081406")
        stake = proposed_stake * multiplier
        if min_stake is not None:
            stake = max(stake, min_stake)
        return min(stake, max_stake)

    def confirm_trade_entry(
        self,
        pair: str,
        order_type: str,
        amount: float,
        rate: float,
        time_in_force: str,
        current_time: datetime,
        entry_tag: str,
        side: str,
        **kwargs,
    ) -> bool:
        # Block longs — this strategy is short-only
        if side != "short":
            return False

        thesis = read_thesis(pair)
        if thesis.get("bias") == "BUY":
            logger.info(f"[BEAR_SCALP BLOCK] {pair} thesis=BUY — not shorting into bullish thesis")
            return False

        try:
            total_balance = self.wallets.get_total("USDT")
            state_file = Path.home() / "cipher" / "risk" / "balance_state.json"
            state = json.loads(state_file.read_text()) if state_file.exists() else {}
            risk_result = run_all_checks(
                current_balance=total_balance,
                start_of_day_balance=state.get("start_of_day", total_balance),
                start_of_week_balance=state.get("start_of_week", total_balance),
                trade_amount_usdt=amount * rate,
                trades_last_hour=0,
                recent_trades=[],
                min_sentiment="NEUTRAL",
            )
            if not risk_result["safe_to_trade"]:
                return False
        except Exception as e:
            logger.warning(f"[BEAR_SCALP] Risk check error: {e}")

        return True
