# source: https://raw.githubusercontent.com/Willemstijn/user_data/758a23f80ce7a5dca176e939c4f3f8562d11a304/strategies/powerx_tpsl.py
# --- Do not remove these libs ---
from freqtrade.strategy.interface import IStrategy
from pandas import DataFrame

# 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


class github_Willemstijn_user_data__powerx_tpsl__20230822_152729(IStrategy):
    # Trading strategy based on Markus Heitkoetter's PowerX strategy
    # https://www.youtube.com/watch?v=6C_ac36iXMw
    #
    # Stoploss set to 100% to let the strategy decide the SL moment.
    stoploss = -1
    # Initial timeframe for this strategy.
    timeframe = "1d"
    # TP set to 100% to let the strategy decide the TP moment.
    minimal_roi = {"0": 100.}

    order_types = {
        "buy": "limit",
        "sell": "limit",
        "emergencysell": "market",
        "stoploss": "market",
        "stoploss_on_exchange": True,
        "stoploss_on_exchange_interval": 60,
        "stoploss_on_exchange_limit_ratio": 0.99,
    }

    plot_config = {
        # Main plot indicators (Moving averages, ...)
        "main_plot": {
            "sma": {},
        },
        "subplots": {
            # Subplots - each dict defines one additional plot
            "MACD": {
                "macd": {"color": "blue"},
                "macdsignal": {"color": "orange"},
            },
            "RSI": {
                "rsi": {"color": "red"},
            },
            "STOCH": {
                "stochd": {"color": "red"},
            },
        },
    }

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        # Reconfigured the original strategy indicators based on talib to  make use of the Pandas_TA library
        # RSI
        dataframe['rsi'] = pta.rsi(close=dataframe['close'], length=14)
        # STOCHASTICS
        k=14
        d=3
        smooth_k=3
        stoch = pta.stoch(high=dataframe['high'],low=dataframe['low'],close=dataframe['close'], k=k, d=d, smooth_k=smooth_k)
        dataframe['stochk']=stoch[f'STOCHk_{k}_{d}_{smooth_k}']
        dataframe['stochd']=stoch[f'STOCHd_{k}_{d}_{smooth_k}']
        # MACD
        f=12
        s=26
        sig=9
        macd = pta.macd(close=dataframe['close'], fast=f, slow=s, signal=sig)
        dataframe['macd'] = macd[f'MACD_{f}_{s}_{sig}']
        dataframe['macd_signal'] = macd[f'MACDs_{f}_{s}_{sig}']
        dataframe['macd_hist'] = macd[f'MACDh_{f}_{s}_{sig}']
        # ATR
        dataframe['atr'] = pta.atr(high=dataframe['high'], low=dataframe['low'], close=dataframe['close'], length=14)
        # #print(metadata)
        # #print(dataframe.tail(20))
        
        # === Funtions ===
        def buy_sell(data):
            rsi_level = 50
            stochd_level = 50
            signal = []
            for i in range(len(dataframe)):
                # Determine the 'default' indicator signals based on the PowerX strategy.
                if (dataframe['rsi'][i] > rsi_level) & (dataframe['stochd'][i] > stochd_level) & (dataframe['macd'][i] > dataframe['macd_signal'][i]):
                    signal.append('buy')
                else:
                    signal.append('sell')

            return signal
        
        # Use the signal function and add the outcome to the dataframe 'signal' column.
        dataframe['signal'] = buy_sell(dataframe)
        
        # if current signal is not equal to previous signal, then set advice_changed to True
        dataframe['advice_changed'] = dataframe['signal'].shift(+1) != dataframe['signal']
        
        # Calculation of takeprofit and stoploss points, based on a calculation of the ATR
        atr_sl_mult = 1
        atr_tp_mult = 2

        for i, row in dataframe.iterrows():
            if row['advice_changed'] == True and row['signal'] == 'buy':
                # for each row that has buy signal, create a tp, sl value & store the buy price
                dataframe.loc[i,'takeprofit'] = row['close'] + (row['atr'] * atr_tp_mult)
                dataframe.loc[i,'stoploss'] = row['close'] - (row['atr'] * atr_sl_mult)
                dataframe.loc[i,'buyprice'] = row['close']
            elif row['advice_changed'] == True and row['signal'] == 'sell':
                # else there is no buy signal and thus no values necessary
                dataframe.loc[i,'takeprofit'] = np.nan
                dataframe.loc[i,'stoploss'] = np.nan
                dataframe.loc[i,'buyprice'] = np.nan
            else:
                # When no change in signal (buy or sell), store the previous value in the current cell
                dataframe.loc[i,'takeprofit'] = dataframe.loc[i-1,'takeprofit']
                dataframe.loc[i,'stoploss'] = dataframe.loc[i-1,'stoploss']
                dataframe.loc[i,'buyprice'] = dataframe.loc[i-1,'buyprice']
        
        #print(dataframe)
        return dataframe

    def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        # pass
        dataframe.loc[
            (
                (dataframe['signal'] == 'buy')
                & (dataframe['advice_changed'] == True)
            ),
            "buy",
        ] = 1
        return dataframe

    def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        # pass
        dataframe.loc[
            (
                (dataframe['signal'] == 'sell')
                & (dataframe['advice_changed'] == True)
            ),
            "sell",
        ] = 1
        # #print(metadata)
        # #print(dataframe.tail(20))
        return dataframe
