# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement
# flake8: noqa: F401
# isort: skip_file
from functools import reduce
import numpy as np
import pandas as pd
from datetime import datetime, timedelta, timezone
from pandas import DataFrame
from typing import Dict, Optional, Union, Tuple

from freqtrade.strategy import (
    IStrategy,
    Trade,
    Order,
    PairLocks,
    informative,
    BooleanParameter,
    CategoricalParameter,
    DecimalParameter,
    IntParameter,
    RealParameter,
    timeframe_to_minutes,
    timeframe_to_next_date,
    timeframe_to_prev_date,
    merge_informative_pair,
    stoploss_from_absolute,
    stoploss_from_open,
    AnnotationType,
)

import talib.abstract as ta
from technical import qtpylib


class OptimizedStrategy(IStrategy):
    """
    RSI Mean Reversion — No Trailing Stop.

    In a strong uptrend, trailing stops are your enemy.
    Stay in on RSI oversold, exit on RSI overbought.
    """
    INTERFACE_VERSION = 3

    timeframe = "5m"
    can_short: bool = False

    minimal_roi = {}  # No ROI — RSI exits only

    stoploss = -0.03

    trailing_stop = False  # DISABLED — let RSI handle exits

    process_only_new_candles = True
    use_exit_signal = True
    exit_profit_only = False
    ignore_roi_if_entry_signal = False

    startup_candle_count: int = 300

    # ===================== HYPEROPT PARAMETERS =====================

    buy_rsi = IntParameter(10, 40, default=25, space="buy", optimize=True)
    buy_adx = IntParameter(5, 25, default=10, space="buy", optimize=True)

    sell_rsi = IntParameter(60, 85, default=75, space="sell", optimize=True)

    # ===================== INDICATORS =====================

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14)
        dataframe['ema200'] = ta.EMA(dataframe, timeperiod=200)
        dataframe['ema50'] = ta.EMA(dataframe, timeperiod=50)
        dataframe['adx'] = ta.ADX(dataframe, timeperiod=14)

        return dataframe

    # ===================== ENTRY SIGNALS =====================

    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe.loc[
            (
                (qtpylib.crossed_above(dataframe['rsi'], self.buy_rsi.value)) &
                (dataframe['close'] > dataframe['ema200']) &
                (dataframe['adx'] > self.buy_adx.value) &
                (dataframe['volume'] > 0)
            ),
            'enter_long'
        ] = 1

        return dataframe

    # ===================== EXIT SIGNALS =====================

    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe.loc[
            (
                (qtpylib.crossed_above(dataframe['rsi'], self.sell_rsi.value)) &
                (dataframe['volume'] > 0)
            ),
            'exit_long'
        ] = 1

        return dataframe