# source: https://raw.githubusercontent.com/BuyMeAnIcecream/freqtrade-strategies/2c5e8a6e69ba98b8d8ec77ba63e865c3d2ef8a79/user_data/strategies/HighFreqMAPullback.py
from freqtrade.strategy import IStrategy
from pandas import DataFrame
import talib.abstract as ta
import freqtrade.vendor.qtpylib.indicators as qtpylib
import pandas as pd
from datetime import datetime
from freqtrade.persistence import Trade

class Github_BuyMeAnIcecream_freqtrade_strategies__HighFreqMAPullback__20250806_082610(IStrategy):
    INTERFACE_VERSION = 3

    timeframe = '1m'

    minimal_roi = {
        "0": 0.01,  # 1% target
        "10": 0.005  # 0.5% after 10 minutes
    }

    stoploss = -0.005  # Fixed 0.5% stoploss initially

    trailing_stop = True
    trailing_stop_positive = 0.002
    trailing_stop_positive_offset = 0.005
    trailing_only_offset_is_reached = True

    cooldown_lookback = 5  # Candles to wait after exit before new entry

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe['ema9'] = ta.EMA(dataframe, timeperiod=9)
        dataframe['ema21'] = ta.EMA(dataframe, timeperiod=21)
        dataframe['engulfing'] = ta.CDLENGULFING(dataframe['open'], dataframe['high'], dataframe['low'], dataframe['close'])  # Keep calculation but not using in entry
        dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14)
        dataframe['volume_sma'] = dataframe['volume'].rolling(20).mean()
        # Removed ADX
        dataframe['recent_low'] = dataframe['low'].rolling(window=5).min()
        return dataframe

    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        # Removed recent_exit calculation as exit_long not available here
        dataframe.loc[
            (dataframe['ema9'] > dataframe['ema21']) &  # Uptrend
            qtpylib.crossed_above(dataframe['close'], dataframe['ema9']) &  # Bounce above EMA9
            (dataframe['close'] > dataframe['open']) &  # Bullish candle for reversal
            (dataframe['rsi'] < 50) &  # Oversold filter (relaxed)
            (dataframe['volume'] > dataframe['volume_sma'] * 1.2) &  # Volume confirmation (relaxed)
            (dataframe['volume'] > 0),  # Guard
            'enter_long'] = 1
        return dataframe

    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe.loc[
            (dataframe['close'] < dataframe['ema21']),  # Exit if drops below EMA21
            'exit_long'] = 1

        return dataframe

    use_custom_stoploss = True

    def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime,
                        current_rate: float, current_profit: float, **kwargs) -> float:
        """
        Custom stoploss - set to recent pullback low
        """
        # Get current dataframe
        dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
        if dataframe is None or len(dataframe) == 0:
            return -1  # Don't change stoploss

        last_candle = dataframe.iloc[-1].squeeze()

        # Calculate relative stoploss based on recent low
        if 'recent_low' in last_candle and not pd.isna(last_candle['recent_low']):
            sl_price = last_candle['recent_low']
            sl_offset = (sl_price / current_rate) - 1
            return sl_offset
        return -1  # Don't change if no data 