# source: https://raw.githubusercontent.com/Chris6622/class-AdvancedFuturesSwingStrategy-IStrategy-/786cfa2c323feab11c072706b06cb9e4243af820/user_data/strategies/future_kama_ha_obv.py
# --- Do not remove these libs ---
import numpy as np
import pandas as pd
from pandas import DataFrame
from freqtrade.strategy import IStrategy
from freqtrade.strategy import DecimalParameter, IntParameter
from functools import reduce

# --- Technical analysis library ---
import talib.abstract as ta
import freqtrade.vendor.qtpylib.indicators as qtpylib

class Github_Chris6622_class_AdvancedFuturesSwingStrategy_IStrategy___future_kama_ha_obv__20260208_084829(IStrategy):
    """
    Strategy: Adaptive Trend Confirmation
    Author: Gemini AI
    Version: 1.3 (Corrected column overlap issue by renaming HA columns)

    Description:
    This futures strategy uses a combination of KAMA, Heikin Ashi, and OBV.
    - KAMA defines the adaptive trend.
    - Heikin Ashi provides smooth momentum-based entry triggers.
    - OBV confirms that volume supports the trade direction.
    Exits are based on a reversal in the Heikin Ashi candle pattern.
    """

    # --- Strategy Configuration ---
    INTERFACE_VERSION = 3
    timeframe = '15m'
    can_short = True

    # --- Risk Management ---
    stoploss = -0.05  # 5% stop-loss. MUST be optimized.
    minimal_roi = {
        "0": 100 # Disable ROI, rely on Heikin Ashi exit signal
    }

    # --- Trailing Stop ---
    trailing_stop = True
    trailing_stop_positive = 0.015
    trailing_stop_positive_offset = 0.03
    trailing_only_offset_is_reached = True

    # --- Hyperparameters ---
    buy_kama_period = IntParameter(20, 80, default=60, space="buy")
    buy_obv_sma_period = IntParameter(10, 30, default=20, space="buy")
    
    sell_kama_period = IntParameter(20, 80, default=60, space="sell")
    sell_obv_sma_period = IntParameter(10, 30, default=20, space="sell")


    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        """
        Adds all necessary indicators to the given DataFrame
        """
        # --- Heikin Ashi ---------------
        ha_df = qtpylib.heikinashi(dataframe)

        # First, rename the Heikin Ashi columns to avoid a name collision
        ha_df.rename(columns={'open': 'ha_open', 'high': 'ha_high', 'low': 'ha_low', 'close': 'ha_close'}, inplace=True)

        # Now, join the renamed Heikin Ashi dataframe to the main dataframe
        dataframe = dataframe.join(ha_df)


        # --- Trend Indicator: KAMA ---
        dataframe['kama_buy'] = ta.KAMA(dataframe, timeperiod=self.buy_kama_period.value)
        dataframe['kama_sell'] = ta.KAMA(dataframe, timeperiod=self.sell_kama_period.value)

        # --- Volume Confirmation: OBV ---
        dataframe['obv'] = ta.OBV(dataframe)
        dataframe['obv_sma_buy'] = ta.SMA(dataframe['obv'], timeperiod=self.buy_obv_sma_period.value)
        dataframe['obv_sma_sell'] = ta.SMA(dataframe['obv'], timeperiod=self.sell_obv_sma_period.value)

        return dataframe

    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        """
        Based on the populated indicators, combines them to generate entry signals.
        """
        # --- Long Entry Conditions ---
        long_conditions = [
            # 1. Main Trend is UP (Price is above adaptive MA)
            (dataframe['close'] > dataframe['kama_buy']),
            # 2. Volume confirms bullish pressure (OBV is above its own SMA)
            (dataframe['obv'] > dataframe['obv_sma_buy']),
            # 3. Heikin Ashi momentum signal: A green candle appears
            (qtpylib.crossed_above(dataframe['ha_close'], dataframe['ha_open']))
        ]

        # --- Short Entry Conditions ---
        short_conditions = [
            # 1. Main Trend is DOWN (Price is below adaptive MA)
            (dataframe['close'] < dataframe['kama_sell']),
            # 2. Volume confirms bearish pressure (OBV is below its own SMA)
            (dataframe['obv'] < dataframe['obv_sma_sell']),
            # 3. Heikin Ashi momentum signal: A red candle appears
            (qtpylib.crossed_below(dataframe['ha_close'], dataframe['ha_open']))
        ]

        # Combine conditions with 'and'
        if long_conditions:
            dataframe.loc[
                reduce(lambda x, y: x & y, long_conditions),
                'enter_long'] = 1

        if short_conditions:
            dataframe.loc[
                reduce(lambda x, y: x & y, short_conditions),
                'enter_short'] = 1

        return dataframe

    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        """
        Based on the populated indicators, generates custom exit signals.
        The exit is a reversal in the Heikin Ashi pattern.
        """
        # --- Long Exit Condition: A red HA candle appears ---
        long_exit_conditions = [
            qtpylib.crossed_below(dataframe['ha_close'], dataframe['ha_open'])
        ]

        # --- Short Exit Condition: A green HA candle appears ---
        short_exit_conditions = [
            qtpylib.crossed_above(dataframe['ha_close'], dataframe['ha_open'])
        ]
        
        # Combine conditions
        if long_exit_conditions:
            dataframe.loc[
                reduce(lambda x, y: x & y, long_exit_conditions),
                'exit_long'] = 1

        if short_exit_conditions:
            dataframe.loc[
                reduce(lambda x, y: x & y, short_exit_conditions),
                'exit_short'] = 1

        return dataframe