# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement
# flake8: noqa: F401

# --- Do not remove these libs ---
import numpy as np  # noqa
import pandas as pd  # noqa
from pandas import DataFrame, Series
# from functools import reduce
# import statistics
import talib.abstract as ta
from freqtrade.strategy import IStrategy, IntParameter
# from freqtrade.exchange import timeframe_to_minutes
# from technical.util import resample_to_interval, resampled_merge
pd.set_option("display.precision",8)

# --------------------------------
# Add your lib to import here
import freqtrade.vendor.qtpylib.indicators as qtpylib

class BBRSIStrategy_darthvader666uk_20210729(IStrategy):
    INTERFACE_VERSION = 2

    minimal_roi = {
        "0": 0.05,
        "20": 0.04,
        "40": 0.03,
        "60": 0.02,
        "201": 0.01,
    }

    # Stoploss:
    stoploss = -0.5

    ## Optional order time in force.
    order_time_in_force = {
        'buy': 'gtc',
        'sell': 'ioc'
    }

    #TTF
    ttf_length       = IntParameter(1, 50, default=15)
    ttf_upperTrigger = IntParameter(1, 400, default=100)
    ttf_lowerTrigger = IntParameter(1, -400, default=-100)

    # Optimal timeframe for the strategy
    timeframe = '15m'

    plot_config = {
        # Main plot indicators (Moving averages, ...)
        'main_plot': {
            'bb_upperband': {'color': 'blue'},
            'bb_middleband': {'color': 'white'},
            'bb_lowerband': {'color': 'yellow'},
        },
        'subplots': {
            "RSI": {
                'rsi': {'color': 'red'},
            },
            "TTF": {
                'ttf': {'color': 'green'},
            }
        }
    }

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:

        # TTF -  Trend Trigger Factor - https://traders.com/Documentation/FEEDbk_docs/2004/12/Abstracts_new/Pee/pee.html
        dataframe['ttf'] = ttf(dataframe, self.ttf_length.value)

        # RSI
        dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14)

        # 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"]
        # )

        return dataframe

    def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe.loc[
            (
                (dataframe['rsi'] < 30) &
                (qtpylib.crossed_below(dataframe['ttf'], self.ttf_lowerTrigger.value)) &
                (dataframe['close'] < dataframe['bb_lowerband'])
                |
                (dataframe['rsi'] < 30) &
                (qtpylib.crossed_below(dataframe['ttf'], self.ttf_lowerTrigger.value)) &
                (dataframe['open'] < dataframe['bb_lowerband'])
            ),
            'buy'] = 1
        return dataframe

    def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe.loc[
            (
                (dataframe['rsi'] > 70) &
                (qtpylib.crossed_above(dataframe['ttf'], self.ttf_upperTrigger.value)) &
                (dataframe['close'] > dataframe['bb_upperband'])
                |
                (dataframe['rsi'] > 70) &
                (qtpylib.crossed_above(dataframe['ttf'], self.ttf_upperTrigger.value)) &
                (dataframe['open'] > dataframe['bb_upperband'])
            ),
            'sell'] = 1
        return dataframe

def ttf(dataframe, ttf_length):
    df = dataframe.copy()
    high, low = df['high'], df['low']
    buyPower = high.rolling(ttf_length).max() - low.shift(ttf_length).fillna(99999).rolling(ttf_length).min()
    sellPower = high.shift(ttf_length).fillna(0).rolling(ttf_length).max() - low.rolling(ttf_length).min()
    
    # ttf = 200 * (buyPower - sellPower) / (buyPower + sellPower)
    ttf = ((buyPower - sellPower) / (0.5 * (buyPower + sellPower))) * 100
    return Series(ttf, name ='ttf')
