# source: https://raw.githubusercontent.com/DerSalvador/freqtrade-helm-chart/a669dc11b640b0eb63aa8f8b51e9f181fd7ee43c/chart/deployed_strategies/binance-futures-k8s-namespace/MultiOffsetLamboV0.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, timedelta
from freqtrade.persistence import Trade
from freqtrade.strategy import stoploss_from_open, merge_informative_pair, DecimalParameter, IntParameter, CategoricalParameter
import technical.indicators as ftt
# - Credits -
# tirail: SMAOffset idea
# rextea: EWO idea
# Lambo

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_DerSalvador_freqtrade_helm_chart__MultiOffsetLamboV0__20260115_122204(IStrategy):
    INTERFACE_VERSION = 3
    # Hyperopt Result
    # Buy hyperspace params:
    entry_params = {'base_nb_candles_entry': 16, 'ewo_high': 5.638, 'ewo_low': -19.993}
    # Sell hyperspace params:
    exit_params = {'base_nb_candles_exit': 49}
    # ROI table:
    minimal_roi = {'0': 0.01}
    # Stoploss:
    stoploss = -0.5
    # Offset
    base_nb_candles_entry = IntParameter(5, 80, default=20, load=True, space='entry', optimize=True)
    base_nb_candles_exit = IntParameter(5, 80, default=20, load=True, space='exit', optimize=True)
    low_offset_sma = DecimalParameter(0.9, 0.99, default=0.958, load=True, space='entry', optimize=True)
    high_offset_sma = DecimalParameter(0.99, 1.1, default=1.012, load=True, space='exit', optimize=True)
    low_offset_ema = DecimalParameter(0.9, 0.99, default=0.958, load=True, space='entry', optimize=True)
    high_offset_ema = DecimalParameter(0.99, 1.1, default=1.012, load=True, space='exit', optimize=True)
    low_offset_trima = DecimalParameter(0.9, 0.99, default=0.958, load=True, space='entry', optimize=True)
    high_offset_trima = DecimalParameter(0.99, 1.1, default=1.012, load=True, space='exit', optimize=True)
    low_offset_t3 = DecimalParameter(0.9, 0.99, default=0.958, load=True, space='entry', optimize=True)
    high_offset_t3 = DecimalParameter(0.99, 1.1, default=1.012, load=True, space='exit', optimize=True)
    low_offset_kama = DecimalParameter(0.9, 0.99, default=0.958, load=True, space='entry', optimize=True)
    high_offset_kama = DecimalParameter(0.99, 1.1, default=1.012, load=True, space='exit', optimize=True)
    # Protection
    ewo_low = DecimalParameter(-20.0, -8.0, default=-20.0, load=True, space='entry', optimize=True)
    ewo_high = DecimalParameter(2.0, 12.0, default=6.0, load=True, space='entry', optimize=True)
    fast_ewo = IntParameter(10, 50, default=50, load=True, space='entry', optimize=False)
    slow_ewo = IntParameter(100, 200, default=200, load=True, space='entry', optimize=False)
    # MA list
    ma_types = ['sma', 'ema', 'trima', 't3', 'kama']
    ma_map = {'sma': {'low_offset': low_offset_sma.value, 'high_offset': high_offset_sma.value, 'calculate': ta.SMA}, 'ema': {'low_offset': low_offset_ema.value, 'high_offset': high_offset_ema.value, 'calculate': ta.EMA}, 'trima': {'low_offset': low_offset_trima.value, 'high_offset': high_offset_trima.value, 'calculate': ta.TRIMA}, 't3': {'low_offset': low_offset_t3.value, 'high_offset': high_offset_t3.value, 'calculate': ta.T3}, 'kama': {'low_offset': low_offset_kama.value, 'high_offset': high_offset_kama.value, 'calculate': ta.KAMA}}
    # Trailing stop:
    trailing_stop = False
    trailing_stop_positive = 0.001
    trailing_stop_positive_offset = 0.01
    trailing_only_offset_is_reached = True
    # Sell signal
    use_exit_signal = True
    exit_profit_only = True
    exit_profit_offset = 0.01
    ignore_roi_if_entry_signal = True
    # Optimal timeframe for the strategy
    timeframe = '5m'
    informative_timeframe = '1h'
    use_exit_signal = True
    exit_profit_only = False
    process_only_new_candles = True
    startup_candle_count = 30
    plot_config = {'main_plot': {'ma_offset_entry': {'color': 'orange'}, 'ma_offset_exit': {'color': 'orange'}}}
    use_custom_stoploss = False

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        # Offset
        for i in self.ma_types:
            dataframe[f'{i}_offset_entry'] = self.ma_map[f'{i}']['calculate'](dataframe, self.base_nb_candles_entry.value) * self.ma_map[f'{i}']['low_offset']
            dataframe[f'{i}_offset_exit'] = self.ma_map[f'{i}']['calculate'](dataframe, self.base_nb_candles_exit.value) * self.ma_map[f'{i}']['high_offset']
        # Elliot
        dataframe['EWO'] = EWO(dataframe, self.fast_ewo.value, self.slow_ewo.value)
        return dataframe

    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        conditions = []
        for i in self.ma_types:
            conditions.append((dataframe['close'] < dataframe[f'{i}_offset_entry']) & ((dataframe['EWO'] < self.ewo_low.value) | (dataframe['EWO'] > self.ewo_high.value)) & (dataframe['volume'] > 0))
        if conditions:
            dataframe.loc[reduce(lambda x, y: x | y, conditions), 'enter_long'] = 1
        return dataframe

    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        conditions = []
        for i in self.ma_types:
            conditions.append((dataframe['close'] > dataframe[f'{i}_offset_exit']) & (dataframe['volume'] > 0))
        if conditions:
            dataframe.loc[reduce(lambda x, y: x | y, conditions), 'exit_long'] = 1
        return dataframe