# source: https://raw.githubusercontent.com/Cole-Godfrey/mean-reversion-strategy/1eb363913016a7305c8c6d726706a2149e5eb68f/user_data/strategies/DailyMeanReversionStrategy.py
from __future__ import annotations

from datetime import datetime
from typing import Optional

import numpy as np
from pandas import DataFrame

from freqtrade.strategy import IStrategy


class Github_Cole_Godfrey_mean_reversion_strategy__DailyMeanReversionStrategy__20260506_194424(IStrategy):
    """One-day close-to-close mean reversion for futures dry-run testing.

    Freqtrade signals are generated on a completed candle and are acted on near
    the next candle open. Therefore the signal on day D uses day D's completed
    close-to-close return to position for day D+1.
    """

    INTERFACE_VERSION = 3

    can_short = True
    timeframe = "1d"
    startup_candle_count = 2
    process_only_new_candles = True

    minimal_roi = {}
    stoploss = -0.99
    use_exit_signal = True
    exit_profit_only = False
    ignore_roi_if_entry_signal = False

    order_types = {
        "entry": "market",
        "exit": "market",
        "emergency_exit": "market",
        "force_entry": "market",
        "force_exit": "market",
        "stoploss": "market",
        "stoploss_on_exchange": False,
        "stoploss_on_exchange_interval": 60,
    }

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe["close_log_return"] = np.log(
            dataframe["close"] / dataframe["close"].shift(1)
        )
        return dataframe

    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        has_volume = dataframe["volume"] > 0

        dataframe.loc[
            (dataframe["close_log_return"] < 0) & has_volume,
            ["enter_long", "enter_tag"],
        ] = (1, "long_after_down_day")

        dataframe.loc[
            (dataframe["close_log_return"] > 0) & has_volume,
            ["enter_short", "enter_tag"],
        ] = (1, "short_after_up_day")

        return dataframe

    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        has_volume = dataframe["volume"] > 0

        dataframe.loc[
            (dataframe["close_log_return"] > 0) & has_volume,
            ["exit_long", "exit_tag"],
        ] = (1, "flip_to_short")

        dataframe.loc[
            (dataframe["close_log_return"] < 0) & has_volume,
            ["exit_short", "exit_tag"],
        ] = (1, "flip_to_long")

        return dataframe

    def leverage(
        self,
        pair: str,
        current_time: datetime,
        current_rate: float,
        proposed_leverage: float,
        max_leverage: float,
        entry_tag: Optional[str],
        side: str,
        **kwargs,
    ) -> float:
        return 1.0
