from freqtrade.strategy import IStrategy, IntParameter, DecimalParameter
from pandas import DataFrame
import talib.abstract as ta
import numpy as np


class Hermes_v11(IStrategy):
    # Configuración general
    timeframe = '1m'
    minimal_roi = {"0": 0.005}  # 0.5%
    stoploss = -0.01  # 1%
    startup_candle_count: int = 30
    process_only_new_candles = True

    # Parámetros optimizables
    adx_threshold = IntParameter(15, 30, default=20, space="buy", optimize=True)
    rsi_sell_threshold = IntParameter(70, 90, default=80, space="sell", optimize=True)

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe['ema3'] = ta.EMA(dataframe, timeperiod=3)
        dataframe['ema6'] = ta.EMA(dataframe, timeperiod=6)
        dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14)
        dataframe['adx'] = ta.ADX(dataframe, timeperiod=14)

        # VWAP manual: acumulado (precio típico * volumen) / volumen acumulado
        typical_price = (dataframe['high'] + dataframe['low'] + dataframe['close']) / 3
        pv = typical_price * dataframe['volume']
        dataframe['vwap'] = pv.cumsum() / dataframe['volume'].replace(0, np.nan).cumsum()

        dataframe['volume_mean'] = dataframe['volume'].rolling(window=10).mean()
        return dataframe

    def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe.loc[
            (
                (dataframe['ema3'] > dataframe['ema6']) &
                (dataframe['ema3'].shift(1) <= dataframe['ema6'].shift(1)) &  # cruce
                (dataframe['close'] > dataframe['vwap']) &
                (dataframe['adx'] > self.adx_threshold.value) &
                (dataframe['volume'] > dataframe['volume_mean'])
            ),
            'buy'
        ] = 1
        return dataframe

    def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe.loc[
            (
                (dataframe['rsi'] > self.rsi_sell_threshold.value) |
                ((dataframe['ema3'] < dataframe['ema6']) &
                 (dataframe['ema3'].shift(1) >= dataframe['ema6'].shift(1)))
            ),
            'sell'
        ] = 1
        return dataframe
