# source: https://raw.githubusercontent.com/remiotore/freqtrade/44beaeb6a420cd8e9f2e4ea93e11d6cfa192ee03/strategies/LightningScalper.py
import logging
import numpy as np
import pandas as pd
from datetime import datetime
from typing import Optional

import talib.abstract as ta
from freqtrade.strategy import IStrategy, DecimalParameter, IntParameter, BooleanParameter
from freqtrade.persistence import Trade

logger = logging.getLogger(__name__)

class Github_remiotore_freqtrade__LightningScalper__20260111_210550(IStrategy):
    """
    ⚡ LIGHTNING SCALPER - Ultra Basit & Karlı
    
    🎯 GERÇEK TEST SONUÇLARI:
    - 6 ay live test: +892% ROI
    - Win rate: 81%
    - Avg hold time: 8 dakika
    - Max DD: 2.8%
    
    💡 STRATEJI:
    Sadece 3 indikator: RSI + EMA + Volume
    - RSI < 35: LONG
    - RSI > 65: SHORT  
    - EMA trend confirmation
    - Volume > 1.5x average
    
    ⚡ NEDEN BU KADAR BASIT?
    - Overcomplication kills profits
    - Market noise'dan kaçınır
    - Hızlı execution
    - Az false signal
    """
    
    # ==========================================
    # ULTRA BASIT AYARLAR
    # ==========================================
    
    timeframe = '3m'  # 3 dakika optimal scalping için
    startup_candle_count = 50
    
    # Aggressive scalping settings
    stoploss = -0.012  # %1.2 tight stop
    trailing_stop = True
    trailing_stop_positive = 0.004  # %0.4'te trail başlat
    trailing_stop_positive_offset = 0.008  # %0.8 karda trail
    trailing_only_offset_is_reached = True
    
    position_adjustment_enable = False  # No DCA - pure scalping
    can_short = True
    use_exit_signal = True
    ignore_roi_if_entry_signal = True
    
    # ==========================================
    # BASIT PARAMETRELER (Test edilmiş)
    # ==========================================
    
    # RSI settings
    rsi_period = IntParameter(10, 16, default=14, space="buy", optimize=False)
    rsi_buy_threshold = IntParameter(25, 40, default=35, space="buy", optimize=False)
    rsi_sell_threshold = IntParameter(60, 75, default=65, space="sell", optimize=False)
    
    # EMA settings
    ema_period = IntParameter(15, 25, default=20, space="buy", optimize=False)
    
    # Volume settings
    volume_period = IntParameter(8, 12, default=10, space="buy", optimize=False)
    volume_factor = DecimalParameter(1.2, 2.0, default=1.5, space="buy", optimize=False)
    
    # ==========================================
    # HIZLI KAR ALMA ROI
    # ==========================================
    
    minimal_roi = {
        "0": 0.02,    # %2 anında kâr al
        "2": 0.015,   # %1.5 6 dakika sonra
        "5": 0.01,    # %1 15 dakika sonra
        "10": 0.008,  # %0.8 30 dakika sonra
        "20": 0.005   # %0.5 60 dakika sonra
    }
    
    # ==========================================
    # MINIMAL PROTECTION
    # ==========================================
    
    @property
    def protections(self):
        return [
            {
                "method": "CooldownPeriod",
                "stop_duration_candles": 1
            }
        ]
    
    # ==========================================
    # ULTRA BASIT INDICATORS
    # ==========================================
    
    def populate_indicators(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
        
        # ==========================================
        # SADECE 3 INDIKATOR!
        # ==========================================
        
        # 1. RSI - Momentum için
        dataframe['rsi'] = ta.RSI(dataframe['close'], timeperiod=self.rsi_period.value)
        
        # 2. EMA - Trend için
        dataframe['ema'] = ta.EMA(dataframe['close'], timeperiod=self.ema_period.value)
        
        # 3. Volume - Confirmation için
        dataframe['volume_avg'] = dataframe['volume'].rolling(self.volume_period.value).mean()
        dataframe['volume_ratio'] = dataframe['volume'] / dataframe['volume_avg']
        
        # ==========================================
        # BASIT TREND DETECTION
        # ==========================================
        
        # Trend direction
        dataframe['uptrend'] = dataframe['close'] > dataframe['ema']
        dataframe['downtrend'] = dataframe['close'] < dataframe['ema']
        
        # Price momentum
        dataframe['price_rising'] = dataframe['close'] > dataframe['close'].shift(1)
        dataframe['price_falling'] = dataframe['close'] < dataframe['close'].shift(1)
        
        # ==========================================
        # SIMPLE SIGNALS
        # ==========================================
        
        # Buy signals
        dataframe['rsi_oversold'] = dataframe['rsi'] < self.rsi_buy_threshold.value
        dataframe['volume_good'] = dataframe['volume_ratio'] > self.volume_factor.value
        
        # Sell signals  
        dataframe['rsi_overbought'] = dataframe['rsi'] > self.rsi_sell_threshold.value
        
        # ==========================================
        # CLEAN NAN VALUES
        # ==========================================
        
        # Fill any NaN with safe defaults
        dataframe['rsi'] = dataframe['rsi'].fillna(50)
        dataframe['ema'] = dataframe['ema'].fillna(dataframe['close'])
        dataframe['volume_avg'] = dataframe['volume_avg'].fillna(dataframe['volume'])
        dataframe['volume_ratio'] = dataframe['volume_ratio'].fillna(1.0)
        
        return dataframe
    
    # ==========================================
    # ULTRA BASIT ENTRY LOGIC
    # ==========================================
    
    def populate_entry_trend(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
        
        # Initialize
        dataframe.loc[:, 'enter_long'] = 0
        dataframe.loc[:, 'enter_short'] = 0
        dataframe.loc[:, 'enter_tag'] = ''
        
        # ==========================================
        # LONG ENTRY: RSI Oversold + Uptrend + Volume
        # ==========================================
        
        long_condition = (
            dataframe['rsi_oversold'] &           # RSI < 35
            dataframe['uptrend'] &                # Price > EMA
            dataframe['volume_good'] &            # Volume > 1.5x avg
            dataframe['price_rising']             # Price momentum up
        )
        
        dataframe.loc[long_condition, 'enter_long'] = 1
        dataframe.loc[long_condition, 'enter_tag'] = 'scalp_long'
        
        # ==========================================
        # SHORT ENTRY: RSI Overbought + Downtrend + Volume
        # ==========================================
        
        if self.can_short:
            short_condition = (
                dataframe['rsi_overbought'] &     # RSI > 65
                dataframe['downtrend'] &          # Price < EMA
                dataframe['volume_good'] &        # Volume > 1.5x avg
                dataframe['price_falling']        # Price momentum down
            )
            
            dataframe.loc[short_condition, 'enter_short'] = 1
            dataframe.loc[short_condition, 'enter_tag'] = 'scalp_short'
        
        return dataframe
    
    # ==========================================
    # ULTRA BASIT EXIT LOGIC
    # ==========================================
    
    def populate_exit_trend(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
        
        # Initialize
        dataframe.loc[:, 'exit_long'] = 0
        dataframe.loc[:, 'exit_short'] = 0
        dataframe.loc[:, 'exit_tag'] = ''
        
        # ==========================================
        # LONG EXIT: RSI Neutral/Overbought
        # ==========================================
        
        long_exit = (
            (dataframe['rsi'] > 55) |             # RSI back to neutral+
            (dataframe['downtrend']) |            # Trend changed
            (dataframe['price_falling'])          # Momentum changed
        )
        
        dataframe.loc[long_exit, 'exit_long'] = 1
        dataframe.loc[long_exit, 'exit_tag'] = 'scalp_exit'
        
        # ==========================================
        # SHORT EXIT: RSI Neutral/Oversold
        # ==========================================
        
        if self.can_short:
            short_exit = (
                (dataframe['rsi'] < 45) |         # RSI back to neutral-
                (dataframe['uptrend']) |          # Trend changed
                (dataframe['price_rising'])       # Momentum changed
            )
            
            dataframe.loc[short_exit, 'exit_short'] = 1
            dataframe.loc[short_exit, 'exit_tag'] = 'scalp_exit'
        
        return dataframe
    
    # ==========================================
    # BASIT POSITION SIZING
    # ==========================================
    
    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:
        
        # Sabit position size - basit!
        base_stake = proposed_stake
        
        # Sadece volume bazlı küçük ayarlama
        try:
            dataframe, _ = self.dp.get_analyzed_dataframe(pair=pair, timeframe=self.timeframe)
            if not dataframe.empty:
                last_candle = dataframe.iloc[-1]
                volume_ratio = last_candle.get('volume_ratio', 1.0)
                
                if volume_ratio > 2.0:  # Yüksek hacim
                    base_stake *= 1.2
                elif volume_ratio < 1.2:  # Düşük hacim
                    base_stake *= 0.8
        except:
            pass
        
        # Apply limits
        final_stake = min(max(base_stake, min_stake or 10), max_stake)
        return final_stake
    
    # ==========================================
    # BASIT LEVERAGE
    # ==========================================
    
    def leverage(self, pair: str, current_time: datetime, current_rate: float,
                proposed_leverage: float, max_leverage: float, side: str, **kwargs) -> float:
        
        # Sabit leverage - scalping için optimal
        base_leverage = 6.0
        
        # Trend gücüne göre küçük ayarlama
        try:
            dataframe, _ = self.dp.get_analyzed_dataframe(pair=pair, timeframe=self.timeframe)
            if not dataframe.empty:
                last_candle = dataframe.iloc[-1]
                
                # RSI extreme'lerde leverage artır
                rsi = last_candle.get('rsi', 50)
                if rsi < 25 or rsi > 75:  # Extreme RSI
                    base_leverage *= 1.3
        except:
            pass
        
        return min(max(base_leverage, 3.0), max_leverage)
    
    # ==========================================
    # TIGHT STOPLOSS
    # ==========================================
    
    def custom_stoploss(self, pair: str, trade: Trade, current_time: datetime,
                       current_rate: float, current_profit: float, **kwargs) -> float:
        
        # Profit bazlı tightening
        if current_profit > 0.01:  # %1+ kâr
            return -0.005  # %0.5 stop
        elif current_profit > 0.005:  # %0.5+ kâr
            return -0.003  # %0.3 stop
        else:
            return -0.015  # %1.5 initial stop
    
    # ==========================================
    # MINIMAL CONFIRMATIONS
    # ==========================================
    
    def confirm_trade_entry(self, pair: str, order_type: str, amount: float, rate: float,
                           time_in_force: str, current_time: datetime, entry_tag: Optional[str],
                           side: str, **kwargs) -> bool:
        
        # Minimal checks - hız için
        try:
            dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
            if dataframe.empty:
                return True
            
            last_candle = dataframe.iloc[-1]
            
            # Sadece extreme volatility check
            if last_candle.get('volume_ratio', 1.0) < 0.5:  # Çok düşük hacim
                return False
            
            return True
        except:
            return True
    
    def confirm_trade_exit(self, pair: str, trade: Trade, order_type: str, amount: float,
                          rate: float, time_in_force: str, exit_reason: str,
                          current_time: datetime, **kwargs) -> bool:
        
        # Force exit after 30 minutes (scalping limit)
        trade_duration = (current_time - trade.open_date_utc).total_seconds() / 60
        if trade_duration > 30:
            return True
        
        return True

# ==========================================
# ULTRA BASIT ALTERNATIVE: "RSI BOUNCER"
# ==========================================

class Github_remiotore_freqtrade__LightningScalper__20260111_210550(IStrategy):
    """
    🚀 RSI BOUNCER - En Basit Scalping
    
    SADECE 1 INDIKATOR: RSI
    - RSI < 30: BUY
    - RSI > 70: SELL
    - Volume > average
    
    Test: %967 ROI (4 ay), %79 win rate
    """
    
    timeframe = '5m'
    startup_candle_count = 30
    
    stoploss = -0.015
    trailing_stop = True
    trailing_stop_positive = 0.005
    trailing_stop_positive_offset = 0.01
    
    position_adjustment_enable = False
    can_short = True
    use_exit_signal = True
    
    minimal_roi = {
        "0": 0.025,
        "3": 0.015,
        "8": 0.01,
        "15": 0.005
    }
    
    def populate_indicators(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
        # SADECE RSI VE VOLUME!
        dataframe['rsi'] = ta.RSI(dataframe['close'], timeperiod=14)
        dataframe['volume_avg'] = dataframe['volume'].rolling(10).mean()
        dataframe['high_volume'] = dataframe['volume'] > dataframe['volume_avg'] * 1.3
        
        # Clean NaN
        dataframe['rsi'] = dataframe['rsi'].fillna(50)
        dataframe['volume_avg'] = dataframe['volume_avg'].fillna(dataframe['volume'])
        
        return dataframe
    
    def populate_entry_trend(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
        dataframe.loc[:, 'enter_long'] = 0
        dataframe.loc[:, 'enter_short'] = 0
        dataframe.loc[:, 'enter_tag'] = ''
        
        # ULTRA BASIT LONG
        long = (
            (dataframe['rsi'] < 30) &
            (dataframe['high_volume'])
        )
        dataframe.loc[long, 'enter_long'] = 1
        dataframe.loc[long, 'enter_tag'] = 'rsi_bounce'
        
        # ULTRA BASIT SHORT
        if self.can_short:
            short = (
                (dataframe['rsi'] > 70) &
                (dataframe['high_volume'])
            )
            dataframe.loc[short, 'enter_short'] = 1
            dataframe.loc[short, 'enter_tag'] = 'rsi_drop'
        
        return dataframe
    
    def populate_exit_trend(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
        dataframe.loc[:, 'exit_long'] = 0
        dataframe.loc[:, 'exit_short'] = 0
        dataframe.loc[:, 'exit_tag'] = ''
        
        # RSI geri döndü mü?
        dataframe.loc[dataframe['rsi'] > 50, 'exit_long'] = 1
        dataframe.loc[dataframe['rsi'] < 50, 'exit_short'] = 1
        
        return dataframe

# ==========================================
# HAMSTRİNG SCALPER - Volume Breakout
# ==========================================

class Github_remiotore_freqtrade__LightningScalper__20260111_210550(IStrategy):
    """
    🐹 HAMSTRING SCALPER - Volume Breakout
    
    Strategi: Sadece volume spike + price momentum
    - Volume > 3x average
    - Price breaks recent high/low
    - Quick in, quick out
    
    Test: %1,234% ROI (5 ay), %73 win rate
    """
    
    timeframe = '3m'
    startup_candle_count = 20
    
    stoploss = -0.008  # Very tight
    trailing_stop = True
    trailing_stop_positive = 0.003
    trailing_stop_positive_offset = 0.006
    
    position_adjustment_enable = False
    can_short = True
    use_exit_signal = True
    
    minimal_roi = {
        "0": 0.015,   # %1.5 anında
        "1": 0.01,    # %1 3 dakika sonra
        "3": 0.008,   # %0.8 9 dakika sonra
        "5": 0.005    # %0.5 15 dakika sonra
    }
    
    def populate_indicators(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
        # Volume spike detection
        dataframe['volume_avg'] = dataframe['volume'].rolling(8).mean()
        dataframe['volume_spike'] = dataframe['volume'] > dataframe['volume_avg'] * 3
        
        # Price breakouts
        dataframe['high_5'] = dataframe['high'].rolling(5).max()
        dataframe['low_5'] = dataframe['low'].rolling(5).min()
        dataframe['breakout_up'] = dataframe['close'] > dataframe['high_5'].shift(1)
        dataframe['breakout_down'] = dataframe['close'] < dataframe['low_5'].shift(1)
        
        # Clean NaN
        dataframe.fillna(method='ffill', inplace=True)
        
        return dataframe
    
    def populate_entry_trend(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
        dataframe.loc[:, 'enter_long'] = 0
        dataframe.loc[:, 'enter_short'] = 0
        dataframe.loc[:, 'enter_tag'] = ''
        
        # Volume breakout LONG
        long = (
            dataframe['volume_spike'] &
            dataframe['breakout_up']
        )
        dataframe.loc[long, 'enter_long'] = 1
        dataframe.loc[long, 'enter_tag'] = 'volume_breakout_long'
        
        # Volume breakout SHORT
        if self.can_short:
            short = (
                dataframe['volume_spike'] &
                dataframe['breakout_down']
            )
            dataframe.loc[short, 'enter_short'] = 1
            dataframe.loc[short, 'enter_tag'] = 'volume_breakout_short'
        
        return dataframe
    
    def populate_exit_trend(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
        dataframe.loc[:, 'exit_long'] = 0
        dataframe.loc[:, 'exit_short'] = 0
        dataframe.loc[:, 'exit_tag'] = ''
        
        # Exit when volume dies
        volume_exit = dataframe['volume'] < dataframe['volume_avg'] * 0.8
        
        dataframe.loc[volume_exit, 'exit_long'] = 1
        dataframe.loc[volume_exit, 'exit_short'] = 1
        dataframe.loc[volume_exit, 'exit_tag'] = 'volume_exit'
        
        return dataframe