# source: https://raw.githubusercontent.com/remiotore/ccxt-freqtrade/44beaeb6a420cd8e9f2e4ea93e11d6cfa192ee03/strategies/ObeliskRSI_v6_1_375.py

from freqtrade.strategy.interface import IStrategy
from pandas import DataFrame
import talib.abstract as ta
import freqtrade.vendor.qtpylib.indicators as qtpylib

import pandas as pd  # noqa
pd.options.mode.chained_assignment = None  # default='warn'

from technical.util import resample_to_interval, resampled_merge
from freqtrade.exchange import timeframe_to_minutes

from functools import reduce
from datetime import datetime, timedelta





















































def easeInCubic(t):
    return t * t * t

def clamp(num, min_value, max_value):
    return max(min(num, max_value), min_value)

def clamp01(num):
    return clamp(num, 0, 1)


class Github_remiotore_ccxt_freqtrade__ObeliskRSI_v6_1_375__20260111_210550(IStrategy):

    timeframe = '5m'

    startup_candle_count = 240
    process_only_new_candles = True

    minimal_roi = {
        "0": 0.15,
        "35": 0.04,
        "65": 0.01,
        "120": 0
    }

    buy_params = {
     'bear-buy-rsi-value': 21,
     'bull-buy-rsi-value': 35
    }

    sell_params = {
     'bear-sell-rsi-value': 55,
     'bull-sell-rsi-value': 69
    }

    stoploss = -0.30

    use_custom_stoploss = True
    custom_stop_ramp_minutes = 110

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:

        resample_rsi_interval = timeframe_to_minutes(self.timeframe) * 12
        resample_rsi_key = 'resample_{}_rsi'.format(resample_rsi_interval)

        dataframe_long = resample_to_interval(dataframe, resample_rsi_interval)
        dataframe_long['rsi'] = ta.RSI(dataframe_long, timeperiod=14)
        dataframe = resampled_merge(dataframe, dataframe_long)
        dataframe[resample_rsi_key].fillna(method='ffill', inplace=True)


        dataframe['bull'] = dataframe[resample_rsi_key].gt(60).astype('int')


        dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14)

        return dataframe

    def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        params = self.buy_params

        conditions = []
        conditions.append(dataframe['volume'] > 0)

        conditions.append(
            ((dataframe['bull'] > 0) & qtpylib.crossed_below(dataframe['rsi'], params['bull-buy-rsi-value'])) |
            (~(dataframe['bull'] > 0) & qtpylib.crossed_below(dataframe['rsi'], params['bear-buy-rsi-value']))
            )

        dataframe.loc[
            reduce(lambda x, y: x & y, conditions),
            'buy'] = 1

        return dataframe

    def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        params = self.sell_params

        conditions = []
        conditions.append(dataframe['volume'] > 0)

        conditions.append(
            ((dataframe['bull'] > 0) & (dataframe['rsi'] > params['bull-sell-rsi-value'])) |
            (~(dataframe['bull'] > 0) & (dataframe['rsi'] > params['bear-sell-rsi-value']))
            )

        dataframe.loc[
            reduce(lambda x, y: x & y, conditions),
            'sell'] = 1

        return dataframe



    def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime, current_rate: float, current_profit: float, **kwargs) -> float:



        since_open = current_time.replace(tzinfo=trade.open_date.tzinfo) - trade.open_date

        sl_pct = 1 - easeInCubic( clamp01( since_open / timedelta(minutes=self.custom_stop_ramp_minutes) ) )
        sl_ramp = abs(self.stoploss) * sl_pct

        return sl_ramp + 0.001 # we can't go all the way to zero