# source: https://raw.githubusercontent.com/remiotore/freqtrade/44beaeb6a420cd8e9f2e4ea93e11d6cfa192ee03/strategies/OptimizedSupertrend.py



import os
import sys

import numpy as np  # noqa
import pandas as pd  # noqa
from pandas import DataFrame

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


import talib

from numba import njit

script_path = os.path.dirname(os.path.abspath(__file__))
os.chdir(script_path);
sys.path.append(script_path)


class Github_remiotore_freqtrade__OptimizedSupertrend__20260111_210550(IStrategy):


    minimal_roi = {
        "0": 100
    }

    stoploss = -0.1

    trailing_stop = False
    trailing_stop_positive = 0.032
    trailing_stop_positive_offset = 0.084
    trailing_only_offset_is_reached = True

    timeframe = '4h'

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        entries, exits = supertrend_strategy(dataframe)
        dataframe['buy'] = entries
        dataframe['sell'] = exits

        return dataframe

    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe.loc[dataframe['buy'] == 1, 'enter_long'] = 1

        return dataframe

    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe.loc[dataframe['sell'] == 1, 'exit_long'] = 1

        return dataframe


@njit
def get_final_bands_nb(close, upper, lower):
    trend = np.full(close.shape, np.nan)
    dir_ = np.full(close.shape, 1)
    long = np.full(close.shape, np.nan)
    short = np.full(close.shape, np.nan)

    for i in range(1, close.shape[0]):
        if close[i] > upper[i - 1]:
            dir_[i] = 1
        elif close[i] < lower[i - 1]:
            dir_[i] = -1
        else:
            dir_[i] = dir_[i - 1]
            if dir_[i] > 0 and lower[i] < lower[i - 1]:
                lower[i] = lower[i - 1]
            if dir_[i] < 0 and upper[i] > upper[i - 1]:
                upper[i] = upper[i - 1]

        if dir_[i] > 0:
            trend[i] = long[i] = lower[i]
        else:
            trend[i] = short[i] = upper[i]

    return trend, dir_, long, short


def get_med_price(high, low):
    return (high + low) / 2


def get_basic_bands(med_price, atr, multiplier):
    matr = multiplier * atr
    upper = med_price + matr
    lower = med_price - matr
    return upper, lower


def faster_supertrend_talib(high, low, close, period=7, multiplier=3):







    avg_price = talib.MEDPRICE(high, low)
    atr = talib.ATR(high, low, close, period)
    upper, lower = get_basic_bands(avg_price, atr, multiplier)

    close = np.array(close)
    upper = np.array(upper)
    lower = np.array(lower)
    return get_final_bands_nb(close, upper, lower)

def supertrend_strategy(ohlcv, period=4, multiplier=3.5):
    high = ohlcv.high
    low = ohlcv.low
    close = ohlcv.close
    trend, dir_, long, short = faster_supertrend_talib(high, low, close, period, multiplier)

    long = np.where(long > 0, True, False)
    short = np.where(short > 0, True, False)

    return long, short
