# source: https://raw.githubusercontent.com/WKoniczynski/freqtrade_bot/9741a5c7ea4195be4bf2bc959d26a09fd18fc06a/user_data/strategies/swing_high_to_sky.py
"""
Github_WKoniczynski_freqtrade_bot__swing_high_to_sky__20260408_073618 Strategy
author      = "Kevin Ossenbrück"
copyright   = "Free For Use"
credits     = ["Bloom Trading, Mohsen Hassan"]
license     = "MIT"
version     = "1.0"
maintainer  = "Kevin Ossenbrück"
email       = "kevin.ossenbrueck@pm.de"
status      = "Live"

Github: https://github.com/freqtrade/freqtrade-strategies

This strategy uses CCI (Commodity Channel Index) and RSI indicators
to identify mean reversion opportunities.

Entry: When CCI crosses below threshold AND RSI shows strength
Exit: When CCI and RSI reach overbought levels
"""

from freqtrade.strategy import IStrategy, IntParameter
from functools import reduce
from pandas import DataFrame

import talib.abstract as ta
import freqtrade.vendor.qtpylib.indicators as qtpylib
import numpy


class Github_WKoniczynski_freqtrade_bot__swing_high_to_sky__20260408_073618(IStrategy):
    INTERFACE_VERSION = 3

    timeframe = '15m'

    stoploss = -0.34338

    minimal_roi = {"0": 0.27058, "33": 0.0853, "64": 0.04093, "244": 0}

    # Buy hyperspace parameters
    buy_cci = IntParameter(low=-200, high=200, default=-175, space='buy', optimize=True)
    buy_cciTime = IntParameter(low=10, high=80, default=72, space='buy', optimize=True)
    buy_rsi = IntParameter(low=10, high=90, default=90, space='buy', optimize=True)
    buy_rsiTime = IntParameter(low=10, high=80, default=36, space='buy', optimize=True)

    # Sell hyperspace parameters
    sell_cci = IntParameter(low=-200, high=200, default=-106, space='sell', optimize=True)
    sell_cciTime = IntParameter(low=10, high=80, default=66, space='sell', optimize=True)
    sell_rsi = IntParameter(low=10, high=90, default=88, space='sell', optimize=True)
    sell_rsiTime = IntParameter(low=10, high=80, default=45, space='sell', optimize=True)

    # Buy hyperspace params (already optimized)
    buy_params = {
        "buy_cci": -175,
        "buy_cciTime": 72,
        "buy_rsi": 90,
        "buy_rsiTime": 36,
    }

    # Sell hyperspace params (already optimized)
    sell_params = {
        "sell_cci": -106,
        "sell_cciTime": 66,
        "sell_rsi": 88,
        "sell_rsiTime": 45,
    }

    def informative_pairs(self):
        return []

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        """
        Calculate CCI and RSI indicators for various timeperiods.
        The strategy will use the values with timeperiods from the buy/sell parameters.
        """

        # Calculate CCI for different timeperiods (for buy signals)
        for val in self.buy_cciTime.range:
            dataframe[f'cci-{val}'] = ta.CCI(dataframe, timeperiod=val)

        # Calculate CCI for different timeperiods (for sell signals)
        for val in self.sell_cciTime.range:
            dataframe[f'cci-sell-{val}'] = ta.CCI(dataframe, timeperiod=val)

        # Calculate RSI for different timeperiods (for buy signals)
        for val in self.buy_rsiTime.range:
            dataframe[f'rsi-{val}'] = ta.RSI(dataframe, timeperiod=val)

        # Calculate RSI for different timeperiods (for sell signals)
        for val in self.sell_rsiTime.range:
            dataframe[f'rsi-sell-{val}'] = ta.RSI(dataframe, timeperiod=val)

        return dataframe

    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        """
        Buy signal when:
        - CCI crosses below buy_cci threshold (mean reversion signal)
        - RSI is below buy_rsi threshold (not too overbought)
        """

        dataframe.loc[
            (
                (dataframe[f'cci-{self.buy_cciTime.value}'] < self.buy_cci.value) &
                (dataframe[f'rsi-{self.buy_rsiTime.value}'] < self.buy_rsi.value)
            ),
            'enter_long'] = 1

        return dataframe

    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        """
        Sell signal when:
        - CCI crosses above sell_cci threshold (reversal signal)
        - RSI is above sell_rsi threshold (overbought condition)
        """

        dataframe.loc[
            (
                (dataframe[f'cci-sell-{self.sell_cciTime.value}'] > self.sell_cci.value) &
                (dataframe[f'rsi-sell-{self.sell_rsiTime.value}'] > self.sell_rsi.value)
            ),
            'exit_long'] = 1

        return dataframe
