# source: https://raw.githubusercontent.com/RoboticAutomations/freqtradestrategies/52c4bd40414645f079a980cf4486dc7af4061efb/AIRA%20-%20open%20code%20v2/strategies/scalping/scalpv3.py
# directory_url: https://github.com/RoboticAutomations/freqtradestrategies/blob/main/AIRA - open code v2/strategies/scalping/
# User: RoboticAutomations
# Repository: freqtradestrategies
# --------------------import numpy as np
import pandas as pd
from freqtrade.strategy import IStrategy, IntParameter, DecimalParameter
from pandas import DataFrame
import talib.abstract as ta
import datetime

class Github_RoboticAutomations_freqtradestrategies__scalpv3__20260915_233254(IStrategy):
    INTERFACE_VERSION = 3

    # 定义交易对的时间框架
    timeframe = '5m'

    # 定义最小ROI的设置
    minimal_roi = {
        "0": 0.06,
        "5": 0.055,
        "10": 0.04,
        "15": 0.03,
        "20": 0.02,
        "25": 0.01
    }

    stoploss = -0.7  # 定义固定的止损
    trailing_stop = True # 启用追踪止损
    trailing_stop_positive = 0.01
    trailing_stop_positive_offset = 0.045
    trailing_only_offset_is_reached = True
    can_short = True
    exit_profit_only = False

    # 定义可调参数
    n1 = IntParameter(5, 20, default=10, space='buy')
    n2 = IntParameter(5, 30, default=21, space='buy')
    moneyFlowMultiplier = DecimalParameter(1, 10, default=5, space='buy')
    moneyFlowMultiplierSlow = DecimalParameter(1, 10, default=5, space='buy')

    # 添加绘图配置
    plot_config = {
        "main_plot": {
            "wt1": {
                "color": "green",
                "title": "WaveTrend 1 (WT1)",
            },
            "wt2": {
                "color": "red",
                "title": "WaveTrend 2 (WT2)",
            },
            "fast_money_flow": {
                "color": "blue",
                "title": "Fast Money Flow",
            },
            "slow_money_flow": {
                "color": "yellow",
                "title": "Slow Money Flow",
            },
        },
    }

    def leverage(self, pair: str, current_time: datetime, current_rate: float,
                 proposed_leverage: float, max_leverage: float, entry_tag: str | None, side: str,
                 **kwargs) -> float:
        return 10.0  # Apply 10x leverage

    def smoothrng(self, dataframe: DataFrame, period: int, multiplier: float) -> pd.Series:
        abs_diff = abs(dataframe['close'] - dataframe['close'].shift(1))
        smooth_range = ta.EMA(abs_diff, timeperiod=period)
        smooth_range = ta.EMA(smooth_range, timeperiod=(period * 2 - 1)) * multiplier
        return pd.Series(smooth_range, index=dataframe.index)

    def range_filter(self, dataframe: DataFrame, smooth_range: pd.Series) -> pd.Series:
        rngfilt = dataframe['close'].copy()
        for i in range(1, len(dataframe)):
            if rngfilt.iloc[i-1] is not None:
                if dataframe['close'].iloc[i] > rngfilt.iloc[i-1]:
                    rngfilt.iloc[i] = max(dataframe['close'].iloc[i] - smooth_range.iloc[i], rngfilt.iloc[i-1])
                else:
                    rngfilt.iloc[i] = min(dataframe['close'].iloc[i] + smooth_range.iloc[i], rngfilt.iloc[i-1])
        return rngfilt

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        """
        添加指标到市场数据
        """
        dataframe['hlc3'] = (dataframe['high'] + dataframe['low'] + dataframe['close']) / 3
        dataframe['esa'] = ta.EMA(dataframe['hlc3'], timeperiod=self.n1.value)
        dataframe['d'] = ta.EMA(abs(dataframe['hlc3'] - dataframe['esa']), timeperiod=self.n1.value)
        dataframe['ci'] = (dataframe['hlc3'] - dataframe['esa']) / (0.015 * dataframe['d'])
        dataframe['tci'] = ta.EMA(dataframe['ci'], timeperiod=self.n2.value)
        dataframe['wt1'] = dataframe['tci']
        dataframe['wt2'] = ta.SMA(dataframe['wt1'], timeperiod=4)

        # 添加 money flow 指标
        dataframe['fast_money_flow'] = (2 * ta.SMA(dataframe['hlc3'] - ta.SMA(dataframe['hlc3'], 9), 9)) / ta.SMA(dataframe['high'] - dataframe['low'], 9) * self.moneyFlowMultiplier.value
        dataframe['slow_money_flow'] = (2 * ta.SMA(dataframe['hlc3'] - ta.SMA(dataframe['hlc3'], 10), 10)) / ta.SMA(dataframe['high'] - dataframe['low'], 10) * self.moneyFlowMultiplierSlow.value

        # 添加Range Filter指标
        smooth_range = self.smoothrng(dataframe, 100, 3.0)
        dataframe['rngfilt'] = self.range_filter(dataframe, smooth_range)
        dataframe['hband'] = dataframe['rngfilt'] + smooth_range
        dataframe['lband'] = dataframe['rngfilt'] - smooth_range

        # 添加RSI指标
        dataframe['rsi'] = ta.RSI(dataframe['close'], timeperiod=14)
        dataframe['rsi_ma'] = ta.SMA(dataframe['rsi'], timeperiod=14)

        # 添加MACD指标
        macd, macdsignal, macdhist = ta.MACD(dataframe['close'], fastperiod=14, slowperiod=26, signalperiod=9)
        dataframe['macd'] = macd
        dataframe['macd_signal'] = macdsignal

        return dataframe
    
    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        """
        定义开仓条件
        """
        # 检测多头交叉点
        dataframe['cross_above'] = ((dataframe['wt1'] > dataframe['wt2']) & (dataframe['wt1'].shift() <= dataframe['wt2'].shift())).astype(int)
        dataframe['cross_below'] = ((dataframe['wt1'] < dataframe['wt2']) & (dataframe['wt1'].shift() >= dataframe['wt2'].shift())).astype(int)

        # 多头开仓条件
        dataframe.loc[
            (dataframe['cross_above'] == 1) & (dataframe['fast_money_flow'] > dataframe['slow_money_flow']) &
            (dataframe['close'] < dataframe['hband']) & (dataframe['rsi'] < 70) & (dataframe['macd'] > dataframe['macd_signal']),
            'enter_long'] = 1

        # 空头开仓条件
        dataframe.loc[
            (dataframe['cross_below'] == 1) & (dataframe['fast_money_flow'] < dataframe['slow_money_flow']) &
            (dataframe['close'] > dataframe['lband']) & (dataframe['rsi'] > 30) & (dataframe['macd'] < dataframe['macd_signal']),
            'enter_short'] = 1

        return dataframe

    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
            """
            定义平仓条件
            """
            # 检测多头交叉点
            dataframe['cross_below'] = ((dataframe['wt1'] < dataframe['wt2']) & (dataframe['wt1'].shift() >= dataframe['wt2'].shift())).astype(int)
            dataframe['cross_above'] = ((dataframe['wt1'] > dataframe['wt2']) & (dataframe['wt1'].shift() <= dataframe['wt2'].shift())).astype(int)

            # 多头平仓条件
            dataframe.loc[
                (dataframe['cross_below'] == 1) & (dataframe['close'] > dataframe['hband']) &
                (dataframe['rsi'] > 70) & (dataframe['macd'] < dataframe['macd_signal']),
                'exit_long'] = 1

            # 空头平仓条件
            dataframe.loc[
                (dataframe['cross_above'] == 1) & (dataframe['close'] < dataframe['lband']) &
                (dataframe['rsi'] < 30) & (dataframe['macd'] > dataframe['macd_signal']),
                'exit_short'] = 1

            return dataframe