# source: https://raw.githubusercontent.com/gwuml/seas-8414-2023/5ab8a50881fb88f9b6c3e93bcd50485f8f9e4d25/week-1/application/user_data/strategies/Aladdin1.py
import freqtrade.vendor.qtpylib.indicators as qtpylib
import talib.abstract as ta
from freqtrade.strategy import DecimalParameter
from pandas import DataFrame
from freqtrade.strategy import IStrategy

class Github_gwuml_seas_8414_2023__Aladdin1__20240113_044531(IStrategy):
    timeframe = "15m"
    minimal_roi = {"0": 0.1}
    stoploss = -0.20

    hold_file = f"hold-trades.json"
    buy_params = { "buy_limit": 0.943 }

    # Trailing stoploss
    trailing_stop = True
    trailing_stop_positive = 0.005
    trailing_stop_positive_offset = 0.02
    trailing_only_offset_is_reached = True

    # Can this strategy go short?
    can_short: bool = True

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

    buy_limit = DecimalParameter(0.90, 0.98, default=0.98, space='buy', decimals=3, optimize=True, load=True)

    @property
    def protections(self):
        return [
            {
                "method": "CooldownPeriod",
                "stop_duration_candles": 1
            },
            {
                "method": "StoplossGuard",
                "lookback_period_candles": 24,
                "trade_limit": 4,
                "stop_duration_candles": 2,
                "only_per_pair": False
            },

        ]

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        # RSI
        dataframe["rsi"] = ta.RSI(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"]

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

        return dataframe

    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe.loc[
            (
                    (dataframe['close'] > self.buy_limit.value * dataframe['bb_middleband'])
                    & (qtpylib.crossed_below(dataframe["rsi"], 40))
                    & (dataframe["tema"] > dataframe["bb_middleband"])
                    & (dataframe["tema"] < dataframe["tema"].shift(1))
                    & (dataframe["volume"] > 0)
            ),
            "enter_short",
        ] = 1

        dataframe.loc[
            (
                    (dataframe['close'] > self.buy_limit.value * dataframe['bb_middleband'])
                    & (qtpylib.crossed_above(dataframe["rsi"], 50))
                    & (dataframe["tema"] > dataframe["bb_middleband"])
                    & (dataframe["tema"] < dataframe["tema"].shift(1))
                    & (dataframe["volume"] > 0)
            ),
            "enter_long",
        ] = 1

        return dataframe

    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        return super().populate_exit_trend(dataframe, metadata)


