# source: https://raw.githubusercontent.com/mohsenjfar/trade/17ea10e916b730006e142258d67c307b102faca1/user_data/Archive/scalping_strategy_v2.py
# directory_url: https://github.com/mohsenjfar/trade/blob/main/user_data/Archive/
# User: mohsenjfar
# Repository: trade
# --------------------from pandas import DataFrame
import freqtrade.vendor.qtpylib.indicators as qtpylib
from freqtrade.strategy import (
    IStrategy,
    informative,
    stoploss_from_open,
    IntParameter
)
import talib.abstract as ta
from freqtrade.persistence import Trade
from datetime import datetime
from typing import Optional
import logging

logger = logging.getLogger(__name__)

class Github_mohsenjfar_trade__scalping_strategy_v2__20260816_043218(IStrategy):

    startup_candle_count: int = 30
    can_short: bool = True
    stoploss = -0.01
    timeframe = '1m'
    long_timeframe = "15m"
    use_exit_signal = True
    use_custom_stoploss = True

    rsi_15m_enter_long = IntParameter(60, 90, default=70, space='buy')
    rsi_15m_enter_short = IntParameter(10, 40, default=30, space='buy')
    rsi_1m_enter_long = IntParameter(10, 40, default=30, space='buy')
    rsi_1m_enter_short = IntParameter(60, 90, default=70, space='buy')
    atr_multiplexer = IntParameter(1, 10, default=4, space='buy')


    @informative(long_timeframe)
    def populate_indicators_inf1(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        
        dataframe['rsi'] = ta.RSI(dataframe, 14)
        dataframe['max'] = dataframe['high'].rolling(14).max()
        dataframe['min'] = dataframe['low'].rolling(14).min()

        return dataframe

    def calculate_risk(self, p1, p2):
        return abs(1 - (p1 / p2))
    

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

        dataframe['rsi'] = ta.RSI(dataframe, 14)
        dataframe['atr'] = ta.ATR(dataframe, timeperiod=14)
        dataframe['short_distance'] = dataframe['close'] + (dataframe['atr'] * self.atr_multiplexer.value)
        dataframe['long_distance'] = dataframe['close'] - (dataframe['atr'] * self.atr_multiplexer.value)
        dataframe['short_risk'] = self.calculate_risk(dataframe.close, dataframe.short_distance)
        dataframe['long_risk'] = self.calculate_risk(dataframe.close, dataframe.long_distance)

        return dataframe


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


        dataframe.loc[
            (
                (dataframe[f'rsi_{self.long_timeframe}'] > self.rsi_15m_enter_long.value) &
                (qtpylib.crossed_above(dataframe[f'rsi'], self.rsi_1m_enter_long.value))
            ),
            'enter_long'
        ] = 1

        dataframe.loc[
            (
                (dataframe[f'rsi_{self.long_timeframe}'] < self.rsi_15m_enter_short.value) &
                (qtpylib.crossed_below(dataframe[f'rsi'], self.rsi_1m_enter_short.value))
            ),
            'enter_short'
        ] = 1

        return dataframe


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

        return dataframe


    def custom_stake_amount(self, pair: str, current_time: datetime, current_rate: float,
                            proposed_stake: float, min_stake: Optional[float], max_stake: float,
                            leverage: float, entry_tag: Optional[str], side: str,
                            **kwargs) -> float:

        dataframe, _ = self.dp.get_analyzed_dataframe(pair=pair, timeframe=self.timeframe)
        candle = dataframe.iloc[-1].squeeze()
        risk = candle.short_risk if side == "short" else candle.long_risk

        if risk > 0.01: return None

        return max(max_stake - max_stake * risk / abs(self.stoploss * 2), min_stake)


    def order_filled(self, pair: str, trade: Trade, order, current_time: datetime, **kwargs) -> None:

        if trade.nr_of_successful_entries == 1:
            dataframe, _ = self.dp.get_analyzed_dataframe(pair=pair, timeframe=self.timeframe)
            candle = dataframe.iloc[-1].squeeze()
            risk = candle.short_risk if trade.is_short else candle.long_risk
            trade.set_custom_data(key='risk', value=risk)

        return None

    
    def custom_exit(self, pair: str, trade: 'Trade', current_time: 'datetime', current_rate: float,
                    current_profit: float, **kwargs):
        
        risk = trade.get_custom_data(key='risk')
        if current_profit > 2 * risk:
            return "Target Hit!"


    def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime,
                        current_rate: float, current_profit: float, after_fill: bool, 
                        **kwargs) -> Optional[float]:

        return stoploss_from_open(
            - trade.get_custom_data(key='risk'),
            current_profit, 
            is_short=trade.is_short, 
            leverage=trade.leverage
        )
