# source: https://raw.githubusercontent.com/remiotore/freqtrade/44beaeb6a420cd8e9f2e4ea93e11d6cfa192ee03/strategies/el_hz.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_hz__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.EMA(df, timeperiod=ema_length)
    ema2 = ta.EMA(df, timeperiod=ema2_length)
    emadif = (ema1 - ema2) / df['close'] * 100
    return emadif

class Github_remiotore_freqtrade__el_hz__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_hz__20260111_210550l hyperspace params:
    sGithub_remiotore_freqtrade__el_hz__20260111_210550l_params = {
        "base_nb_candles_sGithub_remiotore_freqtrade__el_hz__20260111_210550l": 72,
        "high_offset": 1.008,
    }

    # ROI table (агрессивная настройка):
    minimal_roi = {
        "0": 0.15,    # 15% для быстрого выхода
        "10": 0.08,   # 8% через 10 свечей
        "30": 0.04,   # 4% через 30 свечей
        "120": 0      # Безубыток через 120 свечей
    }

    # Stoploss:
    stoploss = -0.242

    # Trailing stop (более агрессивный):
    trailing_stop = True
    trailing_stop_positive = 0.15
    trailing_stop_positive_offset = 0.20
    trailing_only_offset_is_reached = True

    # Max Open Trades:
    max_open_trades = 12  # Увеличено для диверсификации
    
    # 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_hz__20260111_210550l = IntParameter(5, 80, default=sGithub_remiotore_freqtrade__el_hz__20260111_210550l_params['base_nb_candles_sGithub_remiotore_freqtrade__el_hz__20260111_210550l'], space='sGithub_remiotore_freqtrade__el_hz__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_hz__20260111_210550l_params['high_offset'], space='sGithub_remiotore_freqtrade__el_hz__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)
    
    # Profit Protection
    profit_threshold_1 = DecimalParameter(0.03, 0.08, default=0.05, space='sGithub_remiotore_freqtrade__el_hz__20260111_210550l', optimize=True)
    profit_threshold_2 = DecimalParameter(0.08, 0.15, default=0.10, space='sGithub_remiotore_freqtrade__el_hz__20260111_210550l', 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_hz__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 = 95
    plot_config = {'main_plot': {'ma_buy': {'color': 'orange'}, 'ma_sGithub_remiotore_freqtrade__el_hz__20260111_210550l': {'color': 'orange'}}}
    
    # Активируем кастомные функции защиты
    use_custom_stoploss = True
    use_custom_stake_amount = True

    def informative_pairs(sGithub_remiotore_freqtrade__el_hz__20260111_210550f):
        pairs = sGithub_remiotore_freqtrade__el_hz__20260111_210550f.dp.current_whitGithub_remiotore_freqtrade__el_hz__20260111_210550ist()
        informative_pairs = [(pair, sGithub_remiotore_freqtrade__el_hz__20260111_210550f.informative_timeframe) for pair in pairs]
        return informative_pairs

    def get_informative_indicators(sGithub_remiotore_freqtrade__el_hz__20260111_210550f, metadata: dict):
        dataframe = sGithub_remiotore_freqtrade__el_hz__20260111_210550f.dp.get_pair_dataframe(pair=metadata['pair'], timeframe=sGithub_remiotore_freqtrade__el_hz__20260111_210550f.informative_timeframe)
        return dataframe

    def populate_indicators(sGithub_remiotore_freqtrade__el_hz__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_hz__20260111_210550tner = qtpylib.kGithub_remiotore_freqtrade__el_hz__20260111_210550tner_channGithub_remiotore_freqtrade__el_hz__20260111_210550(dataframe)
        dataframe['kc_upperband'] = kGithub_remiotore_freqtrade__el_hz__20260111_210550tner['upper']
        dataframe['kc_lowerband'] = kGithub_remiotore_freqtrade__el_hz__20260111_210550tner['lower']
        dataframe['kc_middleband'] = kGithub_remiotore_freqtrade__el_hz__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']

        heikinashi = qtpylib.heikinashi(dataframe)
        dataframe['ha_open'] = heikinashi['open']
        dataframe['ha_close'] = heikinashi['close']
        dataframe['ha_high'] = heikinashi['high']
        dataframe['ha_low'] = heikinashi['low']
        
        # Добавляем ATR для волатильности
        dataframe['atr'] = ta.ATR(dataframe, timeperiod=14)
        dataframe['atr_pct'] = dataframe['atr'] / dataframe['close']
        
        # Средний объем
        dataframe['volume_ma'] = ta.SMA(dataframe['volume'], timeperiod=20)
        
        # EMA для стратегии
        for val in sGithub_remiotore_freqtrade__el_hz__20260111_210550f.base_nb_candles_buy.range:
            dataframe[f'ma_buy_{val}'] = ta.EMA(dataframe, timeperiod=val)
        for val in sGithub_remiotore_freqtrade__el_hz__20260111_210550f.base_nb_candles_sGithub_remiotore_freqtrade__el_hz__20260111_210550l.range:
            dataframe[f'ma_sGithub_remiotore_freqtrade__el_hz__20260111_210550l_{val}'] = ta.EMA(dataframe, timeperiod=val)

        dataframe['EWO'] = EWO(dataframe, sGithub_remiotore_freqtrade__el_hz__20260111_210550f.fast_ewo, sGithub_remiotore_freqtrade__el_hz__20260111_210550f.slow_ewo)
        return dataframe

    def populate_entry_trend(sGithub_remiotore_freqtrade__el_hz__20260111_210550f, dataframe: DataFrame, metadata: dict) -> DataFrame:
        # Фильтры для повышения качества входов
        volume_filter = dataframe['volume'] > dataframe['volume_ma'] * 1.2
        volatility_filter = dataframe['atr_pct'] < 0.08
        trend_filter = dataframe['adx'] > 25
        
        # Условия для лонгов
        buy_conditions = []
        buy_conditions.append(
            (dataframe['close'] < dataframe[f'ma_buy_{sGithub_remiotore_freqtrade__el_hz__20260111_210550f.base_nb_candles_buy.value}'] * sGithub_remiotore_freqtrade__el_hz__20260111_210550f.low_offset.value) & 
            (dataframe['EWO'] > sGithub_remiotore_freqtrade__el_hz__20260111_210550f.ewo_high.value) & 
            (dataframe['rsi'] < sGithub_remiotore_freqtrade__el_hz__20260111_210550f.rsi_buy.value) & 
            volume_filter &
            trend_filter
        )
        buy_conditions.append(
            (dataframe['close'] < dataframe[f'ma_buy_{sGithub_remiotore_freqtrade__el_hz__20260111_210550f.base_nb_candles_buy.value}'] * sGithub_remiotore_freqtrade__el_hz__20260111_210550f.low_offset.value) & 
            (dataframe['EWO'] < sGithub_remiotore_freqtrade__el_hz__20260111_210550f.ewo_low.value) & 
            volume_filter &
            volatility_filter
        )
        
        if buy_conditions:
            dataframe.loc[reduce(lambda x, y: x | y, buy_conditions), 'enter_long'] = 1

        # Условия для шортов
        sGithub_remiotore_freqtrade__el_hz__20260111_210550l_conditions = []
        sGithub_remiotore_freqtrade__el_hz__20260111_210550l_conditions.append(
            (dataframe['close'] > dataframe[f'ma_sGithub_remiotore_freqtrade__el_hz__20260111_210550l_{sGithub_remiotore_freqtrade__el_hz__20260111_210550f.base_nb_candles_sGithub_remiotore_freqtrade__el_hz__20260111_210550l.value}'] * sGithub_remiotore_freqtrade__el_hz__20260111_210550f.high_offset.value) & 
            volume_filter &
            trend_filter
        )
        
        if sGithub_remiotore_freqtrade__el_hz__20260111_210550l_conditions:
            dataframe.loc[reduce(lambda x, y: x | y, sGithub_remiotore_freqtrade__el_hz__20260111_210550l_conditions), 'enter_short'] = 1

        return dataframe

    def populate_exit_trend(sGithub_remiotore_freqtrade__el_hz__20260111_210550f, dataframe: DataFrame, metadata: dict) -> DataFrame:
        # Частичный выход для фиксации прибыли
        dataframe.loc[
            (dataframe['close'] > dataframe['open'] * 1.05) & 
            (qtpylib.crossed_above(dataframe['rsi'], 70)),
            'exit_long'
        ] = 0.5  # Закрываем 50% позиции

        # Основные условия выхода
        exit_long_conditions = []
        exit_long_conditions.append(
            (dataframe['close'] > dataframe[f'ma_sGithub_remiotore_freqtrade__el_hz__20260111_210550l_{sGithub_remiotore_freqtrade__el_hz__20260111_210550f.base_nb_candles_sGithub_remiotore_freqtrade__el_hz__20260111_210550l.value}'] * sGithub_remiotore_freqtrade__el_hz__20260111_210550f.high_offset.value)
        )
        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_hz__20260111_210550f.base_nb_candles_buy.value}'] * sGithub_remiotore_freqtrade__el_hz__20260111_210550f.low_offset.value) & 
            (dataframe['EWO'] > sGithub_remiotore_freqtrade__el_hz__20260111_210550f.ewo_high.value) & 
            (dataframe['rsi'] < sGithub_remiotore_freqtrade__el_hz__20260111_210550f.rsi_buy.value)
        )
        exit_short_conditions.append(
            (dataframe['close'] < dataframe[f'ma_buy_{sGithub_remiotore_freqtrade__el_hz__20260111_210550f.base_nb_candles_buy.value}'] * sGithub_remiotore_freqtrade__el_hz__20260111_210550f.low_offset.value) & 
            (dataframe['EWO'] < sGithub_remiotore_freqtrade__el_hz__20260111_210550f.ewo_low.value)
        )
        if exit_short_conditions:
            dataframe.loc[reduce(lambda x, y: x | y, exit_short_conditions), 'exit_short'] = 1

        return dataframe

    # Адаптивный стоп-лосс с защитой прибыли
    def custom_stoploss(sGithub_remiotore_freqtrade__el_hz__20260111_210550f, pair: str, trade: Trade, current_time: datetime, 
                       current_rate: float, current_profit: float, **kwargs) -> float:
        # Жесткий стоп при убытке >12%
        if current_profit < -0.12:
            return -1
            
        # Защита прибыли
        if current_profit > sGithub_remiotore_freqtrade__el_hz__20260111_210550f.profit_threshold_2.value:
            return -0.02  # Очень тугой стоп при +10%
        Github_remiotore_freqtrade__el_hz__20260111_210550if current_profit > sGithub_remiotore_freqtrade__el_hz__20260111_210550f.profit_threshold_1.value:
            return -0.05  # Защищаем 5% прибыли
            
        # Базовый стоп
        return -0.242

    # Управление размером позиции (риск 3% на сделку)
    def custom_stake_amount(sGithub_remiotore_freqtrade__el_hz__20260111_210550f, pair: str, current_time: datetime, current_rate: float, 
                           proposed_stake: float, min_stake: float, max_stake: float, 
                           leverage: float, entry_tag: str, side: str, **kwargs) -> float:
        total_balance = sGithub_remiotore_freqtrade__el_hz__20260111_210550f.wallets.get_total('USDT')
        return min(proposed_stake, total_balance * 0.50)

    def leverage(sGithub_remiotore_freqtrade__el_hz__20260111_210550f, pair: str, current_time: datetime, current_rate: float, 
                proposed_leverage: float, max_leverage: float, entry_tag: str, 
                side: str, **kwargs) -> float:
        return 10.0