# source: https://raw.githubusercontent.com/G3niusYukki/ethstrategy/a589f8ead2929251d4b8f0496a171cb755d305fe/user_data/strategies/ETHStrategyAggressive.py
# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement
# flake8: noqa: F401
# isort: skip_file
# --- Do not remove these libs ---
import numpy as np
import pandas as pd
from pandas import DataFrame
from datetime import datetime
from typing import Optional, Union

from freqtrade.strategy import (BooleanParameter, CategoricalParameter, DecimalParameter,
                                IntParameter, IStrategy, merge_informative_pair)

# --------------------------------
# Add your lib to import here
import talib.abstract as ta
import pandas_ta as pta
from freqtrade.persistence import Trade


class Github_G3niusYukki_ethstrategy__ETHStrategyAggressive__20260210_125247(IStrategy):
    """
    Aggressive ETH Trading Strategy with relaxed parameters
    
    Strategy Logic:
    - Entry: RSI < 50 (relaxed from 30) AND MACD momentum positive
    - Exit: RSI > 60 (relaxed from 70) OR MACD momentum negative
    - Uses 5-minute timeframe
    - More aggressive to generate trades in sideways markets
    """

    INTERFACE_VERSION = 3

    # Optimal timeframe for the strategy
    timeframe = '5m'

    # Can this strategy go short?
    can_short: bool = False

    # Minimal ROI designed for the strategy
    minimal_roi = {
        "0": 0.08,      # 8% profit target
        "30": 0.04,     # After 30 minutes, 4% profit
        "60": 0.02,     # After 1 hour, 2% profit
        "120": 0.01     # After 2 hours, 1% profit
    }

    # Optimal stoploss designed for the strategy
    stoploss = -0.03  # 3% stop loss (tighter)

    # Trailing stoploss
    trailing_stop = True
    trailing_stop_positive = 0.008
    trailing_stop_positive_offset = 0.015
    trailing_only_offset_is_reached = True

    # Run "populate_indicators()" only for new candle
    process_only_new_candles = True

    # These values can be overridden in the config
    use_exit_signal = True
    exit_profit_only = False
    ignore_roi_if_entry_signal = False

    # Number of candles the strategy requires before producing valid signals
    startup_candle_count: int = 30

    # Strategy parameters - more aggressive
    buy_rsi = IntParameter(40, 55, default=50, space="buy")
    sell_rsi = IntParameter(55, 70, default=60, space="sell")
    
    # MACD parameters
    macd_fast = IntParameter(8, 16, default=12, space="buy")
    macd_slow = IntParameter(20, 30, default=26, space="buy")
    macd_signal = IntParameter(7, 12, default=9, space="buy")

    def informative_pairs(self):
        return []

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        # RSI
        dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14)

        # MACD
        macd = ta.MACD(dataframe, 
                      fastperiod=self.macd_fast.value,
                      slowperiod=self.macd_slow.value, 
                      signalperiod=self.macd_signal.value)
        dataframe['macd'] = macd['macd']
        dataframe['macdsignal'] = macd['macdsignal']
        dataframe['macdhist'] = macd['macdhist']

        # Bollinger Bands
        bollinger = ta.BBANDS(dataframe, timeperiod=20, nbdevup=2.0, nbdevdn=2.0)
        dataframe['bb_lowerband'] = bollinger['lowerband']
        dataframe['bb_middleband'] = bollinger['middleband']
        dataframe['bb_upperband'] = bollinger['upperband']
        dataframe['bb_percent'] = (dataframe['close'] - dataframe['bb_lowerband']) / (dataframe['bb_upperband'] - dataframe['bb_lowerband'])
        dataframe['bb_width'] = (dataframe['bb_upperband'] - dataframe['bb_lowerband']) / dataframe['bb_middleband']

        # Volume
        dataframe['volume_mean'] = dataframe['volume'].rolling(window=20).mean()

        # EMA crossover
        dataframe['ema_fast'] = ta.EMA(dataframe, timeperiod=9)
        dataframe['ema_slow'] = ta.EMA(dataframe, timeperiod=21)

        return dataframe

    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe.loc[
            (
                # Relaxed RSI condition
                (dataframe['rsi'] < self.buy_rsi.value) &
                
                # MACD trending up
                (dataframe['macd'] > dataframe['macdsignal']) &
                
                # Price below middle BB (potential bounce)
                (dataframe['close'] < dataframe['bb_middleband']) &
                
                # OR EMA crossover
                (
                    (dataframe['ema_fast'] > dataframe['ema_slow']) |
                    (dataframe['macdhist'] > dataframe['macdhist'].shift(1))
                ) &
                
                # Guard: price is not 0
                (dataframe['close'] > 0)
            ),
            'enter_long'] = 1

        return dataframe

    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe.loc[
            (
                (
                    # Relaxed RSI overbought
                    (dataframe['rsi'] > self.sell_rsi.value) |
                    
                    # MACD turning down
                    (
                        (dataframe['macd'] < dataframe['macdsignal']) &
                        (dataframe['macd'].shift(1) >= dataframe['macdsignal'].shift(1))
                    ) |
                    
                    # Price above upper BB
                    (dataframe['close'] > dataframe['bb_upperband'])
                ) &
                
                # Volume confirmation
                (dataframe['volume'] > 0)
            ),
            'exit_long'] = 1
        
        return dataframe
