# source: https://raw.githubusercontent.com/MelvynClark/Freqtrade-Strategy/b67cf5eaae87205b6851b232cc5c8bd4923fbcc1/Simple%20Strategy/SimpleHoptSLeverage.py
# --- Do not remove these libs ---
from freqtrade.strategy.interface import IStrategy
from pandas import DataFrame
from datetime import datetime
from email.policy import default
from typing import Optional
from freqtrade.persistence import Trade

# Add your lib to import here
import talib.abstract as ta
import freqtrade.vendor.qtpylib.indicators as qtpylib
import pandas_ta as pta
import numpy as np  # noqa
import pandas as pd  # noqa


# These libs are for hyperopt
from functools import reduce
from freqtrade.strategy import (BooleanParameter, CategoricalParameter, DecimalParameter,IStrategy, IntParameter)
# --------------------------------
# freqtrade hyperopt --timeframe 1d --hyperopt-loss SharpeHyperOptLossDaily --space buy roi stoploss --epochs 10 -s SimpleHopt

import talib.abstract as ta
import freqtrade.vendor.qtpylib.indicators as qtpylib


class Github_MelvynClark_Freqtrade_Strategy__SimpleHoptSLeverage__20221123_054143(IStrategy):
    """

    author@: Gert Wohlgemuth

    idea:
        this strategy is based on the book, 'The Simple Strategy' and can be found in detail here:

        https://www.amazon.com/Simple-Strategy-Powerful-Trading-Futures-ebook/dp/B00E66QPCG/ref=sr_1_1?ie=UTF8&qid=1525202675&sr=8-1&keywords=the+simple+strategy
    """
    INTERFACE_VERSION: int = 3

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

    minimal_roi = {"0": 0.01}
    stoploss = -0.99
    timeframe = '1d'

    # The hyperopt spaces where the optimal parameters for this strategy are hidden
    rsi_buylong_hline = IntParameter(50, 75, default=70, space='buy')
    rsi_buyshort_hline = IntParameter(50, 75, default=70, space='buy')
    rsi_selllong_hline = IntParameter(70, 95, default=80, space='sell')
    rsi_sellshort_hline = IntParameter(70, 95, default=80, space='sell')
    rsi_period = IntParameter(4, 16, default=7, space='buy')

    protection_enabled = BooleanParameter(default=True)
    protection_cooldown_lookback = IntParameter([0, 50], default=30)

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        macd = ta.MACD(
            dataframe,
            fastperiod=12,
            fastmatype=0,
            slowperiod=26,
            slowmatype=0,
            signalperiod=9,
            signalmatype=0,)
        dataframe['macd'] = macd['macd']
        dataframe['macdsignal'] = macd['macdsignal']
        dataframe['macdhist'] = macd['macdhist']

        # For each value in the space of the indicator above, 
        # see if it produces better results in the buy/sell trend below
        for val in self.rsi_period.range:
            dataframe[f'rsi_{val}'] = ta.RSI(dataframe, timeperiod=val)

        bollinger = qtpylib.bollinger_bands(dataframe['close'], window=12, stds=2)
        dataframe['bb_lowerband'] = bollinger['lower']
        dataframe['bb_upperband'] = bollinger['upper']
        dataframe['bb_middleband'] = bollinger['mid']

        return dataframe

    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe.loc[
            (
                (
                    # test the given indicator value in the buy condition
                        (dataframe['macd'] > 0)
                        & (dataframe['macd'] > dataframe['macdsignal'])
                        & (dataframe['bb_upperband'] > dataframe['bb_upperband'].shift(1))
                        & (dataframe[f'rsi_{self.rsi_period.value}'] > self.rsi_buylong_hline.value)
                )
            ),
            'enter_long'] = 1

        dataframe.loc[
            (
                (
                    # test the given indicator value in the buy condition
                        (dataframe['macd'] < 0)
                        & (dataframe['macd'] < dataframe['macdsignal'])
                        & (dataframe['bb_upperband'] < dataframe['bb_upperband'].shift(1))
                        & (dataframe[f'rsi_{self.rsi_period.value}'] < self.rsi_buyshort_hline.value)
                )
            ),
            'enter_short'] = 1

        return dataframe

    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe.loc[
            (
                # test the given indicator value in the sell condition
                (dataframe[f'rsi_{self.rsi_period.value}'] < self.rsi_selllong_hline.value)
            ),
            'exit_long'] = 1

        return dataframe
        dataframe.loc[
            (
                # test the given indicator value in the sell condition
                (dataframe[f'rsi_{self.rsi_period.value}'] > self.rsi_sellshort_hline.value)
            ),
            'exit_short'] = 1

        return dataframe

    def leverage(self, pair: str, current_time: datetime, current_rate: float,
                 proposed_leverage: float, max_leverage: float, entry_tag: Optional[str],
                 side: str, **kwargs) -> float:
                 
        entry_tag = ''
        max_leverage = 3.0

        return max_leverage    
