# source: https://raw.githubusercontent.com/Vinylether/okx/71f225cd973d057f7b1f3c1a95c3ac5a6674df76/user_data/strategies/OkxFutures15mDonchian.py
from datetime import datetime

from pandas import DataFrame

import talib.abstract as ta

from freqtrade.persistence import Trade
from freqtrade.strategy import IStrategy


class Github_Vinylether_okx__OkxFutures15mDonchian__20260601_075127(IStrategy):
    INTERFACE_VERSION = 3

    can_short = True
    timeframe = "15m"
    startup_candle_count = 260
    process_only_new_candles = True

    minimal_roi = {
        "960": 0.0,
        "0": 0.20,
    }

    stoploss = -0.055

    trailing_stop = False
    use_exit_signal = True
    exit_profit_only = False
    ignore_roi_if_entry_signal = False

    order_types = {
        "entry": "limit",
        "exit": "limit",
        "stoploss": "market",
        "stoploss_on_exchange": False,
    }

    order_time_in_force = {
        "entry": "GTC",
        "exit": "GTC",
    }

    def leverage(
        self,
        pair: str,
        current_time,
        current_rate: float,
        proposed_leverage: float,
        max_leverage: float,
        entry_tag: str | None,
        side: str,
        **kwargs,
    ) -> float:
        return min(2.0, max_leverage)

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe["donchian_high_48"] = dataframe["high"].rolling(48).max().shift(1)
        dataframe["donchian_low_48"] = dataframe["low"].rolling(48).min().shift(1)
        dataframe["ema96"] = ta.EMA(dataframe, timeperiod=96)
        dataframe["ema384"] = ta.EMA(dataframe, timeperiod=384)
        dataframe["atr"] = ta.ATR(dataframe, timeperiod=14)
        dataframe["atr_pct"] = dataframe["atr"] / dataframe["close"]
        dataframe["adx"] = ta.ADX(dataframe, timeperiod=14)
        dataframe["volume_mean_48"] = dataframe["volume"].rolling(48).mean()
        return dataframe

    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        liquid = (
            (dataframe["volume"] > 0)
            & (dataframe["volume"] > dataframe["volume_mean_48"] * 0.5)
        )
        tradable_vol = (dataframe["atr_pct"] > 0.0015) & (dataframe["atr_pct"] < 0.04)
        trend_strength = dataframe["adx"] > 12

        dataframe.loc[
            (
                liquid
                & tradable_vol
                & trend_strength
                & (dataframe["close"] > dataframe["donchian_high_48"])
                & (dataframe["close"] > dataframe["ema96"])
            ),
            "enter_long",
        ] = 1

        dataframe.loc[
            (
                liquid
                & tradable_vol
                & trend_strength
                & (dataframe["close"] < dataframe["donchian_low_48"])
                & (dataframe["close"] < dataframe["ema96"])
            ),
            "enter_short",
        ] = 1
        return dataframe

    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        return dataframe

    def custom_exit(
        self,
        pair: str,
        trade: Trade,
        current_time: datetime,
        current_rate: float,
        current_profit: float,
        **kwargs,
    ) -> str | bool | None:
        if (current_time - trade.open_date_utc).total_seconds() >= 16 * 60 * 60:
            return "time_exit_16h"
        return None
