# source: https://raw.githubusercontent.com/huckhuck12/freqtrade-futures-lab/40a97470897a3ebfe2853eca7586a325598dc0f0/user_data/strategies/NineSecondSniper.py
from freqtrade.strategy import IStrategy
from pandas import DataFrame
import pandas as pd
import talib.abstract as ta
from datetime import datetime
import numpy as np


class Github_huckhuck12_freqtrade_futures_lab__NineSecondSniper__20260122_145205(IStrategy):
    """
    9秒狙击手策略 - 真实实现

    核心逻辑：
    - SAR指标为核心找反转点
    - 激进用法：在SAR压制价格时做多，赌突破
    - 9秒价格对比动能判断
    - 仓位减半机制
    - 动态止损和模糊止盈
    """

    timeframe = '1m'
    max_open_trades = 1
    stake_amount = 100
    startup_candle_count = 50

    minimal_roi = {
        "0": 0.01,     # 赚够就平仓
        "60": 0.005,   # 模糊止盈
    }

    stoploss = -0.05  # 默认止损，但实际由custom_exit控制
    trailing_stop = False  # 不使用追踪止损

    order_types = {
        'entry': 'market',
        'exit': 'market',
        'stoploss': 'market',
        'stoploss_on_exchange': False
    }

    unfilledtimeout = {
        'entry': 10,
        'exit': 10,
        'unit': 'seconds'
    }

    leverage_config = {
        'BTC/USDT:USDT': 8.0,   # 恢复保守杠杆配置
        'ETH/USDT:USDT': 6.0,
        'SOL/USDT:USDT': 5.0,
        'XRP/USDT:USDT': 4.0,
        'DOGE/USDT:USDT': 4.0
    }

    # 9秒价格缓冲区（环形缓冲区）
    price_buffer_size = 9
    price_buffers = {}  # 为每个交易对维护缓冲区

    def informative_pairs(self) -> list:
        return []

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        df = dataframe.copy()
        pair = metadata['pair']

        # SAR指标 - 恢复标准参数
        df['sar'] = ta.SAR(df['high'].values, df['low'].values,
                          acceleration=0.02, maximum=0.2)

        # SAR压制判断：价格在SAR下方
        df['sar_suppression'] = df['close'] < df['sar']

        # 9秒价格对比（当前价格 vs 9秒前价格）
        df['price_9sec_ago'] = df['close'].shift(9)  # 9根K线前 = 9分钟 ≈ 9秒概念
        df['price_change_9sec'] = (df['close'] - df['price_9sec_ago']) / df['price_9sec_ago']

        # 波动幅度要求（动能判断）
        df['volatility_9sec'] = abs(df['price_change_9sec'])

        # 成交量确认
        df['volume_sma'] = ta.SMA(df['volume'].values, timeperiod=10)
        df['volume_ratio'] = df['volume'] / df['volume_sma']

        # 环形缓冲区维护（模拟代码的高级设计）
        if pair not in self.price_buffers:
            self.price_buffers[pair] = np.zeros(self.price_buffer_size)

        # 更新缓冲区（存储最近9秒价格）
        buffer = self.price_buffers[pair]
        for i in range(len(df)):
            if i >= self.price_buffer_size:
                # 环形缓冲区逻辑： oldest -> newest
                buffer[:-1] = buffer[1:]
                buffer[-1] = df['close'].iloc[i]

        # 从缓冲区计算9秒动量
        df['buffer_momentum'] = 0.0
        if len(buffer) >= self.price_buffer_size:
            df['buffer_momentum'] = (buffer[-1] - buffer[0]) / buffer[0]

        return df

    def leverage(self, pair: str, current_time: datetime, current_rate: float,
                 current_profit: float = 0.0, min_stops: float = 0.0,
                 max_stops: float = 0.0, current_time_rows: DataFrame = None,
                 **kwargs) -> float:
        base_leverage = self.leverage_config.get(pair, 5.0)

        # 恢复仓位减半机制：盈利时自动减半仓位（降低风险）
        if current_profit > 0.005:  # 0.5%盈利就开始减仓
            base_leverage *= 0.5  # 减半杠杆

        return min(base_leverage, 15.0)

    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        df = dataframe.copy()
        df['enter_long'] = 0

        if len(df) < self.startup_candle_count:
            return df

        # 9秒狙击手核心逻辑 - 平衡参数
        sniper_conditions = (
            # SAR指标核心：价格被SAR压制（激进做多）
            df['sar_suppression'] &  # SAR在价格上方压制
            # 9秒动能判断：恢复合理波动要求
            (df['volatility_9sec'] > 0.0015) &  # 9秒内波动>0.15% (中等)
            (df['price_change_9sec'] > 0.0008) &  # 9秒内上涨>0.08% (中等)
            # 成交量确认：合理要求
            (df['volume_ratio'] > 1.4) &  # 成交量1.4倍 (中等)
            # 缓冲区动量确认：合理标准
            (df['buffer_momentum'] > 0.0008)  # 合理动量要求
        )

        df.loc[sniper_conditions, 'enter_long'] = 1

        return df

    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        df = dataframe.copy()
        df['exit'] = 0

        # SAR反转：SAR跌破价格（原压制失效）
        df.loc[df['close'] > df['sar'], 'exit'] = 1

        # 9秒动量反转
        df.loc[df['price_change_9sec'] < -0.001, 'exit'] = 1

        return df

    def custom_exit(self, pair: str, current_time: datetime, current_rate: float,
                    current_profit: float, **kwargs) -> bool:
        """
        显著风控缺陷：无预设止损，要等浮亏扩大且动能恶化时才设置
        止盈也无具体点位，只设定赚够目标金额就平仓

        优化：调整阈值以平衡风险收益
        """

        # 止盈：赚够目标金额就平仓（模糊标准）- 更激进
        if current_profit > 0.012:  # 1.2%利润就平仓 (更快获利)
            return True

        # 止损：等浮亏扩大且动能恶化时才设置（被动止损）
        # 优化：稍微提前止损
        if current_profit < -0.012:  # -1.2%止损 (稍微提前)
            return True

        return False
