# source: https://raw.githubusercontent.com/Serge-sudo/EnsembleTradingStrategy/93cbd257893475d805651cca732cce2165e0a317/freqtrade/user_data/strategies/bases/FSampleStrategy.py
# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement
# flake8: noqa: F401
# isort: skip_file
# --- Do not remove these libs ---
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.abstract as ta
import freqtrade.vendor.qtpylib.indicators as qtpylib


# This class is a sample. Feel free to customize it.
class Github_Serge_sudo_EnsembleTradingStrategy__FSampleStrategy__20240414_162331(IStrategy):

	INTERFACE_VERSION = 3
	timeframe = "1h"
	minimal_roi = {"0": 1}

	stoploss = -0.05
	can_short = True

	# Trailing stoploss
	trailing_stop = False

	# Run "populate_indicators()" only for new candle.
	process_only_new_candles = True

	# Number of candles the strategy requires before producing valid signals
	startup_candle_count: int = 30

	def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:

		dataframe["adx"] = ta.ADX(dataframe)
		# RSI
		dataframe["rsi"] = ta.RSI(dataframe)

		# Stochastic Fast
		stoch_fast = ta.STOCHF(dataframe)
		dataframe["fastd"] = stoch_fast["fastd"]
		dataframe["fastk"] = stoch_fast["fastk"]

		# MACD
		macd = ta.MACD(dataframe)
		dataframe["macd"] = macd["macd"]
		dataframe["macdsignal"] = macd["macdsignal"]
		dataframe["macdhist"] = macd["macdhist"]

		# MFI
		dataframe["mfi"] = ta.MFI(dataframe)

		# Bollinger Bands
		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"]

		# Parabolic SAR
		dataframe["sar"] = ta.SAR(dataframe)

		# TEMA - Triple Exponential Moving Average
		dataframe["tema"] = ta.TEMA(dataframe, timeperiod=9)

		# Cycle Indicator
		# ------------------------------------
		# Hilbert Transform Indicator - SineWave
		hilbert = ta.HT_SINE(dataframe)
		dataframe["htsine"] = hilbert["sine"]
		dataframe["htleadsine"] = hilbert["leadsine"]

		return dataframe

	def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:

		dataframe.loc[
			(
				# Signal: RSI crosses above 30
				(qtpylib.crossed_above(dataframe["rsi"], 30))
				& (dataframe["tema"] <= dataframe["bb_middleband"])
				& (  # Guard: tema below BB middle
					dataframe["tema"] > dataframe["tema"].shift(1)
				)
				& (  # Guard: tema is raising
					dataframe["volume"] > 0
				)  # Make sure Volume is not 0
			),
			"enter_long",
		] = 1

		dataframe.loc[
			(
				# Signal: RSI crosses above 70
				(qtpylib.crossed_above(dataframe["rsi"], 70))
				& (dataframe["tema"] > dataframe["bb_middleband"])
				& (  # Guard: tema above BB middle
					dataframe["tema"] < dataframe["tema"].shift(1)
				)
				& (  # Guard: tema is falling
					dataframe["volume"] > 0
				)  # Make sure Volume is not 0
			),
			"enter_short",
		] = 1

		return dataframe

	def get_name(self) -> str:
		return "fsample_strategy"


	def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
		dataframe.loc[
			(
				# Signal: RSI crosses above 70
				(qtpylib.crossed_above(dataframe["rsi"], 70))
				& (dataframe["tema"] > dataframe["bb_middleband"])
				& (  # Guard: tema above BB middle
					dataframe["tema"] < dataframe["tema"].shift(1)
				)
				& (  # Guard: tema is falling
					dataframe["volume"] > 0
				)  # Make sure Volume is not 0
			),
			"exit_long",
		] = 1

		dataframe.loc[
			(
				# Signal: RSI crosses above 30
				(qtpylib.crossed_above(dataframe["rsi"], 30))
				&
				# Guard: tema below BB middle
				(dataframe["tema"] <= dataframe["bb_middleband"])
				& (dataframe["tema"] > dataframe["tema"].shift(1))
				& (  # Guard: tema is raising
					dataframe["volume"] > 0
				)  # Make sure Volume is not 0
			),
			"exit_short",
		] = 1

		return dataframe