# source: https://raw.githubusercontent.com/henryle97/freqtrade_strategy/d7eab093755c4f8dfaff009fe9861938ac0b1372/user_data_weekly/strategies/bullish_week_strategy.py
import datetime

import pytz
import talib.abstract as ta
from pandas import DataFrame
from technical import qtpylib

from freqtrade.strategy import IStrategy


class Github_henryle97_freqtrade_strategy__bullish_week_strategy__20240926_163135(IStrategy):
    """
    Alert when meet following conditions:
    - Bullish candlestick pattern
    - Close price > open price
    - abs(high - close) < abs(open - low) ~ hammer
    - Volume: TODO
    """

    INTERFACE_VERSION = 3

    can_short: bool = False

    timeframe = "1w"

    startup_candle_count: int = 14

    stoploss = -0.05

    # https://ta-lib.github.io/ta-lib-python/func_groups/pattern_recognition.html
    bullish_candlestick_patterns = {
        # "2 CROWS": ta.CDL2CROWS,
        # "3 BLACK CROWS": ta.CDL3BLACKCROWS,
        # "3 INSIDE": ta.CDL3INSIDE,
        # "3 LINE STRIKE": ta.CDL3LINESTRIKE,
        # "3 OUTSIDE": ta.CDL3OUTSIDE,
        # "3 STARS IN SOUTH": ta.CDL3STARSINSOUTH,
        # "3 WHITE SOLDIERS": ta.CDL3WHITESOLDIERS,
        # "ABANDONED BABY": ta.CDLABANDONEDBABY,
        # "ADVANCE BLOCK": ta.CDLADVANCEBLOCK,
        # "BELT HOLD": ta.CDLBELTHOLD,
        # "BREAKAWAY": ta.CDLBREAKAWAY,
        # "CLOSING MARUBOZU": ta.CDLCLOSINGMARUBOZU,
        # "CONCEAL BABY SWALL": ta.CDLCONCEALBABYSWALL,
        # "COUNTERATTACK": ta.CDLCOUNTERATTACK,
        # "DARK CLOUD COVER": ta.CDLDARKCLOUDCOVER,
        "DOJI": ta.CDLDOJI,
        # "DOJI STAR": ta.CDLDOJISTAR,
        # "DRAGONFLY DOJI": ta.CDLDRAGONFLYDOJI,
        "ENGULFING": ta.CDLENGULFING,
        # "EVENING DOJI STAR": ta.CDLEVENINGDOJISTAR,
        "EVENING STAR": ta.CDLEVENINGSTAR,
        # "GAP SIDE SIDE WHITE": ta.CDLGAPSIDESIDEWHITE,
        # "GRAVESTONE DOJI": ta.CDLGRAVESTONEDOJI,
        "HAMMER": ta.CDLHAMMER,
        "HANGING MAN": ta.CDLHANGINGMAN,
        # "HARAMI": ta.CDLHARAMI,
        # "HARAMI CROSS": ta.CDLHARAMICROSS,
        # "HIGH WAVE": ta.CDLHIGHWAVE,
        # "HIKKAKE": ta.CDLHIKKAKE,
        # "HIKKAKE MOD": ta.CDLHIKKAKEMOD,
        # "HOMING PIGEON": ta.CDLHOMINGPIGEON,
        # "IDENTICAL 3 CROWS": ta.CDLIDENTICAL3CROWS,
        # "IN NECK": ta.CDLINNECK,
        # "INVERTED HAMMER": ta.CDLINVERTEDHAMMER,
        # "KICKING": ta.CDLKICKING,
        # "KICKING BY LENGTH": ta.CDLKICKINGBYLENGTH,
        # "LADDER BOTTOM": ta.CDLLADDERBOTTOM,
        # "LONG LEGGED DOJI": ta.CDLLONGLEGGEDDOJI,
        # "LONG LINE": ta.CDLLONGLINE,
        # "MARUBOZU": ta.CDLMARUBOZU,
        # "MATCHING LOW": ta.CDLMATCHINGLOW,
        # "MAT HOLD": ta.CDLMATHOLD,
        # "MORNING DOJI STAR": ta.CDLMORNINGDOJISTAR,
        "MORNING STAR": ta.CDLMORNINGSTAR,
        # "ON NECK": ta.CDLONNECK,
        # "PIERCING": ta.CDLPIERCING,
        # "RICKSHAW MAN": ta.CDLRICKSHAWMAN,
        # "RISE FALL 3 METHODS": ta.CDLRISEFALL3METHODS,
        # "SEPARATING LINES": ta.CDLSEPARATINGLINES,
        "SHOOTING STAR": ta.CDLSHOOTINGSTAR,
        # "SHORT LINE": ta.CDLSHORTLINE,
        # "SPINNING TOP": ta.CDLSPINNINGTOP,
        # "STALLED PATTERN": ta.CDLSTALLEDPATTERN,
        # "STICK SANDWICH": ta.CDLSTICKSANDWICH,
        # "TAKURI": ta.CDLTAKURI,
        # "TASUKI GAP": ta.CDLTASUKIGAP,
        # "THRUSTING": ta.CDLTHRUSTING,
        # "TRISTAR": ta.CDLTRISTAR,
        # "UNIQUE 3 RIVER": ta.CDLUNIQUE3RIVER,
        # "UPSIDE GAP 2 CROWS": ta.CDLUPSIDEGAP2CROWS,
        # "XSIDE GAP 3 METHODS": ta.CDLXSIDEGAP3METHODS,
    }

    def informative_pairs(self):
        return []

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

        # RSI
        dataframe["rsi"] = ta.RSI(dataframe, timeperiod=14)

        # pattern recognition - bullish candlestick
        for (
            pattern_name,
            pattern_function,
        ) in self.bullish_candlestick_patterns.items():
            dataframe[pattern_name] = pattern_function(dataframe)
        return dataframe

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

        # close price > open price
        dataframe.loc[
            (dataframe["close"] > dataframe["open"]), "price_high_trend"
        ] = "up"

        dataframe.loc[
            (dataframe["close"] <= dataframe["open"]), "price_high_trend"
        ] = "down"

        # rsi > 70 -> down
        dataframe.loc[(dataframe["rsi"] > 70), "rsi_trend"] = "down"

        # Bullish candlestick pattern
        dataframe.loc[
            dataframe[list(self.bullish_candlestick_patterns.keys())]
            .gt(0)
            .any(axis=1),
            "candle_trend",
        ] = "up"

        # hammer: abs(high - close) < abs(open - low)
        dataframe.loc[
            (
                (
                    abs(dataframe["high"] - dataframe["close"])
                    < abs(dataframe["open"] - dataframe["low"])
                )
                or (
                    (dataframe["high"] - dataframe["close"])
                    < (dataframe["close"] - dataframe["open"])
                )
                # & (
                #     (
                #         (dataframe["high"] - dataframe["close"])
                #         < (dataframe["open"] - dataframe["low"])
                #     )
                #     or (
                #         (dataframe["high"] - dataframe["close"])
                #         < (dataframe["close"] - dataframe["open"])
                #     )
                # )
            ),
            "hammer_trend",
        ] = "up"

        # combine all trend -> signal
        dataframe.loc[
            (dataframe["price_high_trend"] == "up")
            & (dataframe["candle_trend"] == "up")
            & (dataframe["hammer_trend"] == "up"),
            "enter_long",
        ] = 1

        # notify signal if previsous candle have enter_long = 1
        if dataframe["enter_long"].iloc[-1] == 1:
            # get candle names for notification for current candle
            candle_names = []
            for pattern_name in self.bullish_candlestick_patterns.keys():
                if dataframe[pattern_name].iloc[-1] > 0:
                    candle_names.append(pattern_name)

            # Get current time in timezone HoChiMinh
            current_time = datetime.datetime.now(
                tz=pytz.timezone("Asia/Ho_Chi_Minh")
            ).strftime("%Y-%m-%d %H:%M:%S")

            self.dp.send_msg(
                f"Weekly - {current_time}: Enter Long for {metadata['pair']} with {', '.join(candle_names)} candlestick pattern"
            )
        return dataframe

    def populate_exit_trend(
        self, dataframe: DataFrame, metadata: dict
    ) -> DataFrame:
        dataframe.loc[
            (
                # RSI crosse above 80
                (qtpylib.crossed_above(dataframe["rsi"], 80))
            ),
            "exit_long",
        ] = 1
        return dataframe
