# source: https://raw.githubusercontent.com/remiotore/freqtrade/44beaeb6a420cd8e9f2e4ea93e11d6cfa192ee03/strategies/el_hz480.py
# --- Do not remove these libs ---
from freqtrade.strategy.interface import IStrategy
from typing import Dict, List
from functools import reduce
from pandas import DataFrame
# --------------------------------
import talib.abstract as ta
import numpy as np
import freqtrade.vendor.qtpylib.indicators as qtpylib
import datetime
from technical.util import resample_to_interval, resampled_merge
from datetime import datetime, timedGithub_remiotore_freqtrade__el_hz480__20260111_210550ta
from freqtrade.persistence import Trade
from freqtrade.strategy import stoploss_from_open, merge_informative_pair, DecimalParameter, IntParameter, CategoricalParameter
import technical.indicators as ftt



def EWO(dataframe, ema_length=5, ema2_length=35):
    df = dataframe.copy()
    ema1 = ta.SMA(df, timeperiod=ema_length)
    ema2 = ta.SMA(df, timeperiod=ema2_length)
    emadif = (ema1 - ema2) / df['close'] * 100
    return emadif



def populate_indicators(sGithub_remiotore_freqtrade__el_hz480__20260111_210550f, dataframe: DataFrame, metadata: dict) -> DataFrame:

    dataframe['adx'] = ta.ADX(dataframe)
    dataframe['plus_dm'] = ta.PLUS_DM(dataframe)
    dataframe['plus_di'] = ta.PLUS_DI(dataframe)
    dataframe['minus_dm'] = ta.MINUS_DM(dataframe)
    dataframe['minus_di'] = ta.MINUS_DI(dataframe)

    aroon = ta.AROON(dataframe)
    dataframe['aroonup'] = aroon['aroonup']
    dataframe['aroondown'] = aroon['aroondown']
    dataframe['aroonosc'] = ta.AROONOSC(dataframe)
    dataframe['ao'] = qtpylib.awesome_oscillator(dataframe)

    kGithub_remiotore_freqtrade__el_hz480__20260111_210550tner = qtpylib.kGithub_remiotore_freqtrade__el_hz480__20260111_210550tner_channGithub_remiotore_freqtrade__el_hz480__20260111_210550(dataframe)
    dataframe['kc_upperband'] = kGithub_remiotore_freqtrade__el_hz480__20260111_210550tner['upper']
    dataframe['kc_lowerband'] = kGithub_remiotore_freqtrade__el_hz480__20260111_210550tner['lower']
    dataframe['kc_middleband'] = kGithub_remiotore_freqtrade__el_hz480__20260111_210550tner['mid']
    dataframe['kc_percent'] = (dataframe['close'] - dataframe['kc_lowerband']) / (dataframe['kc_upperband'] - dataframe['kc_lowerband'])
    dataframe['kc_width'] = (dataframe['kc_upperband'] - dataframe['kc_lowerband']) / dataframe['kc_middleband']
    dataframe['uo'] = ta.ULTOSC(dataframe)
    dataframe['cci'] = ta.CCI(dataframe)
    dataframe['rsi'] = ta.RSI(dataframe)

    rsi = 0.1 * (dataframe['rsi'] - 50)
    dataframe['fisher_rsi'] = (np.exp(2 * rsi) - 1) / (np.exp(2 * rsi) + 1)
    dataframe['fisher_rsi_norma'] = 50 * (dataframe['fisher_rsi'] + 1)

    stoch = ta.STOCH(dataframe)
    dataframe['slowd'] = stoch['slowd']
    dataframe['slowk'] = stoch['slowk']


    stoch_fast = ta.STOCHF(dataframe)
    dataframe['fastd'] = stoch_fast['fastd']
    dataframe['fastk'] = stoch_fast['fastk']


    stoch_rsi = ta.STOCHRSI(dataframe)
    dataframe['fastd_rsi'] = stoch_rsi['fastd']
    dataframe['fastk_rsi'] = stoch_rsi['fastk']


    macd = ta.MACD(dataframe)
    dataframe['macd'] = macd['macd']
    dataframe['macdsignal'] = macd['macdsignal']
    dataframe['macdhist'] = macd['macdhist']
    dataframe['mfi'] = ta.MFI(dataframe)
    dataframe['roc'] = ta.ROC(dataframe)



    bollinger = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=2)
    dataframe['bb_lowerband'] = bollinger['lower']
    dataframe['bb_middleband'] = bollinger['mid']
    dataframe['bb_upperband'] = bollinger['upper']
    dataframe['bb_percent'] = (dataframe['close'] - dataframe['bb_lowerband']) / (dataframe['bb_upperband'] - dataframe['bb_lowerband'])
    dataframe['bb_width'] = (dataframe['bb_upperband'] - dataframe['bb_lowerband']) / dataframe['bb_middleband']

    dataframe['sar'] = ta.SAR(dataframe)
    dataframe['tema'] = ta.TEMA(dataframe, timeperiod=9)


    hilbert = ta.HT_SINE(dataframe)
    dataframe['htsine'] = hilbert['sine']
    dataframe['htleadsine'] = hilbert['leadsine']

    dataframe['CDLHAMMER'] = ta.CDLHAMMER(dataframe)
    dataframe['CDLINVERTEDHAMMER'] = ta.CDLINVERTEDHAMMER(dataframe)
    dataframe['CDLDRAGONFLYDOJI'] = ta.CDLDRAGONFLYDOJI(dataframe)
    dataframe['CDLPIERCING'] = ta.CDLPIERCING(dataframe)  # values [0, 100]
    dataframe['CDLMORNINGSTAR'] = ta.CDLMORNINGSTAR(dataframe)  # values [0, 100]
    dataframe['CDL3WHITESOLDIERS'] = ta.CDL3WHITESOLDIERS(dataframe)  # values [0, 100]

    dataframe['CDLHANGINGMAN'] = ta.CDLHANGINGMAN(dataframe)
    dataframe['CDLSHOOTINGSTAR'] = ta.CDLSHOOTINGSTAR(dataframe)
    dataframe['CDLGRAVESTONEDOJI'] = ta.CDLGRAVESTONEDOJI(dataframe)
    dataframe['CDLDARKCLOUDCOVER'] = ta.CDLDARKCLOUDCOVER(dataframe)
    dataframe['CDLEVENINGDOJISTAR'] = ta.CDLEVENINGDOJISTAR(dataframe)
    dataframe['CDLEVENINGSTAR'] = ta.CDLEVENINGSTAR(dataframe)

    dataframe['CDL3LINESTRIKE'] = ta.CDL3LINESTRIKE(dataframe)
    dataframe['CDLSPINNINGTOP'] = ta.CDLSPINNINGTOP(dataframe)  # values [0, -100, 100]
    dataframe['CDLENGULFING'] = ta.CDLENGULFING(dataframe)  # values [0, -100, 100]
    dataframe['CDLHARAMI'] = ta.CDLHARAMI(dataframe)  # values [0, -100, 100]
    dataframe['CDL3OUTSIDE'] = ta.CDL3OUTSIDE(dataframe)  # values [0, -100, 100]
    dataframe['CDL3INSIDE'] = ta.CDL3INSIDE(dataframe)  # values [0, -100, 100]


    heikinashi = qtpylib.heikinashi(dataframe)
    dataframe['ha_open'] = heikinashi['open']
    dataframe['ha_close'] = heikinashi['close']
    dataframe['ha_high'] = heikinashi['high']
    dataframe['ha_low'] = heikinashi['low']
    return dataframe



class Github_remiotore_freqtrade__el_hz480__20260111_210550(IStrategy):
    INTERFACE_VERSION = 3
    can_short = True

    # Buy hyperspace params:
    buy_params = {
        "base_nb_candles_buy": 12,
        "ewo_high": 4.428,
        "ewo_low": -12.383,
        "low_offset": 0.915,
        "rsi_buy": 44,
    }

    # SGithub_remiotore_freqtrade__el_hz480__20260111_210550l hyperspace params:
    sGithub_remiotore_freqtrade__el_hz480__20260111_210550l_params = {
        "base_nb_candles_sGithub_remiotore_freqtrade__el_hz480__20260111_210550l": 72,
        "high_offset": 1.008,
    }

    # ROI table:
    minimal_roi = {
        "0": 0.219,
        "24": 0.087,
        "67": 0.024,
        "164": 0
    }

    # Stoploss:
    stoploss = -0.242

    # Trailing stop:
    trailing_stop = True
    trailing_stop_positive = 0.103
    trailing_stop_positive_offset = 0.2
    trailing_only_offset_is_reached = True


    # Max Open Trades:
    max_open_trades = 9
    
    # SMAOffset
    base_nb_candles_buy = IntParameter(5, 80, default=buy_params['base_nb_candles_buy'], space='buy', optimize=True)
    base_nb_candles_sGithub_remiotore_freqtrade__el_hz480__20260111_210550l = IntParameter(5, 80, default=sGithub_remiotore_freqtrade__el_hz480__20260111_210550l_params['base_nb_candles_sGithub_remiotore_freqtrade__el_hz480__20260111_210550l'], space='sGithub_remiotore_freqtrade__el_hz480__20260111_210550l', optimize=True)
    low_offset = DecimalParameter(0.9, 0.99, default=buy_params['low_offset'], space='buy', optimize=True)
    high_offset = DecimalParameter(0.99, 1.1, default=sGithub_remiotore_freqtrade__el_hz480__20260111_210550l_params['high_offset'], space='sGithub_remiotore_freqtrade__el_hz480__20260111_210550l', optimize=True)
    
    
    # Protection
    fast_ewo = 50
    slow_ewo = 200
    ewo_low = DecimalParameter(-20.0, -8.0, default=buy_params['ewo_low'], space='buy', optimize=True)
    ewo_high = DecimalParameter(2.0, 12.0, default=buy_params['ewo_high'], space='buy', optimize=True)
    rsi_buy = IntParameter(30, 70, default=buy_params['rsi_buy'], space='buy', optimize=True)
    
    
    
    # Trailing stop:
    trailing_stop = True
    trailing_stop_positive = 0.005
    trailing_stop_positive_offset = 0.03
    trailing_only_offset_is_reached = True
    
    
    # SGithub_remiotore_freqtrade__el_hz480__20260111_210550l signal
    use_exit_signal = True
    exit_profit_only = False
    exit_profit_offset = 0.01
    ignore_roi_if_entry_signal = True
    
    
    # Optimal timeframe for the strategy
    timeframe = '5m'
    informative_timeframe = '1h'
    process_only_new_candles = True
    startup_candle_count = 499
    plot_config = {'main_plot': {'ma_buy': {'color': 'orange'}, 'ma_sGithub_remiotore_freqtrade__el_hz480__20260111_210550l': {'color': 'orange'}}}
    use_custom_stoploss = False



    def informative_pairs(sGithub_remiotore_freqtrade__el_hz480__20260111_210550f):
        pairs = sGithub_remiotore_freqtrade__el_hz480__20260111_210550f.dp.current_whitGithub_remiotore_freqtrade__el_hz480__20260111_210550ist()
        informative_pairs = [(pair, sGithub_remiotore_freqtrade__el_hz480__20260111_210550f.informative_timeframe) for pair in pairs]
        return informative_pairs



    def get_informative_indicators(sGithub_remiotore_freqtrade__el_hz480__20260111_210550f, metadata: dict):
        dataframe = sGithub_remiotore_freqtrade__el_hz480__20260111_210550f.dp.get_pair_dataframe(pair=metadata['pair'], timeframe=sGithub_remiotore_freqtrade__el_hz480__20260111_210550f.informative_timeframe)
        return dataframe



    def populate_indicators(sGithub_remiotore_freqtrade__el_hz480__20260111_210550f, dataframe: DataFrame, metadata: dict) -> DataFrame:

        for val in sGithub_remiotore_freqtrade__el_hz480__20260111_210550f.base_nb_candles_buy.range:
            dataframe[f'ma_buy_{val}'] = ta.EMA(dataframe, timeperiod=val)
        for val in sGithub_remiotore_freqtrade__el_hz480__20260111_210550f.base_nb_candles_sGithub_remiotore_freqtrade__el_hz480__20260111_210550l.range:
            dataframe[f'ma_sGithub_remiotore_freqtrade__el_hz480__20260111_210550l_{val}'] = ta.EMA(dataframe, timeperiod=val)

        dataframe['EWO'] = EWO(dataframe, sGithub_remiotore_freqtrade__el_hz480__20260111_210550f.fast_ewo, sGithub_remiotore_freqtrade__el_hz480__20260111_210550f.slow_ewo)
        dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14)
        return dataframe



    def populate_entry_trend(sGithub_remiotore_freqtrade__el_hz480__20260111_210550f, dataframe: DataFrame, metadata: dict) -> DataFrame:
        buy_conditions = []
        buy_conditions.append((dataframe['close'] < dataframe[f'ma_buy_{sGithub_remiotore_freqtrade__el_hz480__20260111_210550f.base_nb_candles_buy.value}'] * sGithub_remiotore_freqtrade__el_hz480__20260111_210550f.low_offset.value) & (dataframe['EWO'] > sGithub_remiotore_freqtrade__el_hz480__20260111_210550f.ewo_high.value) & (dataframe['rsi'] < sGithub_remiotore_freqtrade__el_hz480__20260111_210550f.rsi_buy.value) & (dataframe['volume'] > 0))
        buy_conditions.append((dataframe['close'] < dataframe[f'ma_buy_{sGithub_remiotore_freqtrade__el_hz480__20260111_210550f.base_nb_candles_buy.value}'] * sGithub_remiotore_freqtrade__el_hz480__20260111_210550f.low_offset.value) & (dataframe['EWO'] < sGithub_remiotore_freqtrade__el_hz480__20260111_210550f.ewo_low.value) & (dataframe['volume'] > 0))
        if buy_conditions:
            dataframe.loc[reduce(lambda x, y: x | y, buy_conditions), 'enter_long'] = 1


        sGithub_remiotore_freqtrade__el_hz480__20260111_210550l_conditions = []
        sGithub_remiotore_freqtrade__el_hz480__20260111_210550l_conditions.append((dataframe['close'] > dataframe[f'ma_sGithub_remiotore_freqtrade__el_hz480__20260111_210550l_{sGithub_remiotore_freqtrade__el_hz480__20260111_210550f.base_nb_candles_sGithub_remiotore_freqtrade__el_hz480__20260111_210550l.value}'] * sGithub_remiotore_freqtrade__el_hz480__20260111_210550f.high_offset.value) & (dataframe['volume'] > 0))
        if sGithub_remiotore_freqtrade__el_hz480__20260111_210550l_conditions:
            dataframe.loc[reduce(lambda x, y: x | y, sGithub_remiotore_freqtrade__el_hz480__20260111_210550l_conditions), 'enter_short'] = 1


        return dataframe





    def populate_exit_trend(sGithub_remiotore_freqtrade__el_hz480__20260111_210550f, dataframe: DataFrame, metadata: dict) -> DataFrame:
        exit_long_conditions = []
        exit_long_conditions.append((dataframe['close'] > dataframe[f'ma_sGithub_remiotore_freqtrade__el_hz480__20260111_210550l_{sGithub_remiotore_freqtrade__el_hz480__20260111_210550f.base_nb_candles_sGithub_remiotore_freqtrade__el_hz480__20260111_210550l.value}'] * sGithub_remiotore_freqtrade__el_hz480__20260111_210550f.high_offset.value) & (dataframe['volume'] > 0))
        if exit_long_conditions:
            dataframe.loc[reduce(lambda x, y: x | y, exit_long_conditions), 'exit_long'] = 1

        exit_short_conditions = []
        exit_short_conditions.append((dataframe['close'] < dataframe[f'ma_buy_{sGithub_remiotore_freqtrade__el_hz480__20260111_210550f.base_nb_candles_buy.value}'] * sGithub_remiotore_freqtrade__el_hz480__20260111_210550f.low_offset.value) & (dataframe['EWO'] > sGithub_remiotore_freqtrade__el_hz480__20260111_210550f.ewo_high.value) & (dataframe['rsi'] < sGithub_remiotore_freqtrade__el_hz480__20260111_210550f.rsi_buy.value) & (dataframe['volume'] > 0))
        exit_short_conditions.append((dataframe['close'] < dataframe[f'ma_buy_{sGithub_remiotore_freqtrade__el_hz480__20260111_210550f.base_nb_candles_buy.value}'] * sGithub_remiotore_freqtrade__el_hz480__20260111_210550f.low_offset.value) & (dataframe['EWO'] < sGithub_remiotore_freqtrade__el_hz480__20260111_210550f.ewo_low.value) & (dataframe['volume'] > 0))
        if exit_short_conditions:
            dataframe.loc[reduce(lambda x, y: x | y, exit_short_conditions), 'exit_short'] = 1


            return dataframe


    def leverage(sGithub_remiotore_freqtrade__el_hz480__20260111_210550f, pair: str, current_time: datetime, current_rate: float, proposed_leverage: float, max_leverage: float, entry_tag:str, side: str, **kwargs) -> float:
        """
        Customize leverage for each new trade. This method is only called in futures mode.

        :param pair: Pair that's currently analyzed
        :param current_time: datetime object, containing the current datetime
        :param current_rate: Rate, calculated based on pricing settings in exit_pricing.
        :param proposed_leverage: A leverage proposed by the bot.
        :param max_leverage: Max leverage allowed on this pair
        :param entry_tag: Optional entry_tag (buy_tag) if provided with the buy signal.
        :param side: 'long' or 'short' - indicating the direction of the proposed trade
        :return: A leverage amount, which is between 1.0 and max_leverage.
        """
        return 10.0