# source: https://raw.githubusercontent.com/remiotore/freqtrade/44beaeb6a420cd8e9f2e4ea93e11d6cfa192ee03/strategies/Discord_EMAsStochastic.py
from functools import reduce

import freqtrade.vendor.qtpylib.indicators as qtpylib
import talib.abstract as ta
from freqtrade.strategy import IntParameter
from freqtrade.strategy.interface import IStrategy
from pandas import DataFrame, Series
from datetime import datetime, timedelta
from freqtrade.persistence import Trade
import numpy as np


###########################################################################################################
##                WORK IN PROGRESS! USE AT YOUR OWN RISK!!!                                                                                                 ##
###########################################################################################################
##                Github_remiotore_freqtrade__Discord_EMAsStochastic__20260111_210550 by birrafondaio                                                         ##
##                                                                                                       ##
##    https://github.com/brokenseal                                                                      ##
##                                                                                                       ##                                                                                                       ##
###########################################################################################################
##                 GENERAL RECOMMENDATIONS                                                               ##
##                                                                                                       ##
##   For optimal performance, suggested to use 2 open trades, with unlimited stake.                      ##
##   With my pairlist which can be found in this repo.                                                   ##
##                                                                                                       ##
###########################################################################################################
##               DONATIONS 2 @brokenseal                                                                 ##
##                                                                                                       ##
##   Absolutely not required. However, will be accepted as a token of appreciation.                      ##
##                                                                                                       ##
##   ETH: 0x531CfE1fb299709726FE38259dD7dc666a2fA95D                                                     ##
##                                                                                                       ##
###########################################################################################################


class Github_remiotore_freqtrade__Discord_EMAsStochastic__20260111_210550(IStrategy):
    timeframe = "1h"

    first_ema_length = IntParameter(6, 10, default=8, space="buy")
    second_ema_length = IntParameter(12, 16, default=14, space="buy")
    third_ema_length = IntParameter(40, 60, default=50, space="buy")
    max_open_hours = IntParameter(2, 48, default=12, space="buy")

    buy_params = {
        "first_ema_length": 10,
        "second_ema_length": 14,
        "third_ema_length": 42,
        "max_open_hours": 4,
    }

    # Sell hyperspace params:
    sell_params = {}

    # ROI table:
    minimal_roi = {"0": 0.567, "173": 0.218, "403": 0.059, "1295": 0}

    # Trailing stop:
    trailing_stop = True
    trailing_stop_positive = 0.01
    trailing_stop_positive_offset = 0.1
    trailing_only_offset_is_reached = False

    process_only_new_candles = True
    use_sell_signal = True
    sell_profit_only = True
    ignore_roi_if_buy_signal = False
    order_types = {
        "buy": "limit",
        "sell": "limit",
        "stoploss": "market",
        "stoploss_on_exchange": False,
    }
    plot_config = {
        "main_plot": {
            "first_ema": {"color": "red"},
            "second_ema": {"color": "orange"},
            "third_ema": {"color": "blue"},
        },
        "subplots": {
            "stochastic": {
                "fastk": {"color": "red"},
                "slowd": {"color": "blue"},
            }
        },
    }

    use_custom_stoploss = True
    stoploss = -0.9

    def custom_stoploss(
        self,
        pair: str,
        trade: Trade,
        current_time: datetime,
        current_rate: float,
        current_profit: float,
        **kwargs
    ) -> float:
        # Manage losing trades and open room for better ones.
        if (current_profit < 0) & (
            current_time - timedelta(hours=int(self.max_open_hours.value))
            > trade.open_date_utc
        ):
            return 0.01
        return 0.99

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe["has_volume"] = dataframe["volume"] > 0

        dataframe["first_ema"] = ta.EMA(dataframe["close"], self.first_ema_length.value)
        dataframe["second_ema"] = ta.EMA(
            dataframe["close"], self.second_ema_length.value
        )
        dataframe["third_ema"] = ta.EMA(dataframe["close"], self.third_ema_length.value)

        fastk, slowd = ta.STOCH(
            dataframe["high"],
            dataframe["low"],
            dataframe["close"],
        )
        dataframe["fastk"] = fastk
        dataframe["slowd"] = slowd

        return dataframe

    def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        conditions = (
            dataframe["has_volume"]
            & (dataframe["first_ema"] > dataframe["second_ema"])
            & (dataframe["second_ema"] > dataframe["third_ema"])
        )
        trigger = qtpylib.crossed_above(dataframe["fastk"], dataframe["slowd"])

        dataframe.loc[
            conditions & trigger,
            "buy",
        ] = 1

        return dataframe

    def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe.loc[
            qtpylib.crossed_below(dataframe["fastk"], dataframe["slowd"]), "sell"
        ] = 0
        return dataframe
