# source: https://raw.githubusercontent.com/gilaigenttech/freqtrade-user_data/d16b7f5db829fb674151ed0894a239fe9ee6c3bd/strategies/PerpSpotBasisStrategy_Debug.py
#!/usr/bin/env python3
"""
Debug version of PerpSpotBasisStrategy to identify issues
"""
import pandas as pd
from freqtrade.strategy.interface import IStrategy
from freqtrade.strategy import IntParameter, DecimalParameter
from pandas import DataFrame
import talib.abstract as ta
import numpy as np
import os

class Github_gilaigenttech_freqtrade_user_data__PerpSpotBasisStrategy_Debug__20250926_111255(IStrategy):
    timeframe = "5m"
    can_short = False
    startup_candle_count = 200

    # Disable FreqAI exit signals - they cause premature exits
    use_exit_signal = False

    # ROI and stoploss
    minimal_roi = {
        "0": 0.217,
        "31": 0.058,
        "65": 0.04,
        "142": 0
    }
    stoploss = -0.274

    # Process only new candles
    process_only_new_candles = True

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        pair = metadata['pair']
        print(f"Processing pair: {pair}")
        print(f"Dataframe shape: {dataframe.shape}")
        print(f"Date range: {dataframe['date'].min()} to {dataframe['date'].max()}")

        # Load futures data for basis calculations
        futures_data = self.load_futures_data(pair)
        if futures_data is not None:
            print(f"Futures data loaded successfully for {pair}")
            dataframe = self.merge_futures_data(dataframe, futures_data)
            dataframe = self.calculate_basis_features(dataframe)
        else:
            print(f"No futures data found for {pair}")

        # Simplified feature set
        dataframe = self.calculate_volume_features(dataframe)

        # Technical indicators
        dataframe["rsi"] = ta.RSI(dataframe, timeperiod=14)
        dataframe["ema_20"] = ta.EMA(dataframe, timeperiod=20)
        dataframe["ema_50"] = ta.EMA(dataframe, timeperiod=50)
        dataframe["adx"] = ta.ADX(dataframe, timeperiod=14)
        macd = ta.MACD(dataframe)
        dataframe['macd'] = macd['macd']
        dataframe['macdsignal'] = macd['macdsignal']
        dataframe['macdhist'] = macd['macdhist']

        # Debug: Print available columns
        print(f"Available columns: {dataframe.columns.tolist()}")
        
        # Check for FreqAI columns
        freqai_cols = [col for col in dataframe.columns if col.startswith('&-')]
        print(f"FreqAI columns found: {freqai_cols}")
        
        if '&-enter_long' in dataframe.columns:
            print(f"FreqAI enter_long signal range: {dataframe['&-enter_long'].min()} to {dataframe['&-enter_long'].max()}")
            print(f"FreqAI enter_long signal last 10 values: {dataframe['&-enter_long'].tail(10).tolist()}")
        else:
            print("WARNING: No &-enter_long column found!")

        return dataframe

    def load_futures_data(self, pair):
        """Load corresponding futures data"""
        try:
            # Convert spot pair to futures pair (BTC/USDT -> BTC/USDT:USDT)
            futures_pair = pair.replace('/', '_') + '_USDT-5m-futures.feather'
            futures_path = f'/home/gil/freqtrade/user_data/data/binance/futures/{futures_pair}'
            
            print(f"Looking for futures data at: {futures_path}")

            if not os.path.exists(futures_path):
                print(f"Futures data file does not exist: {futures_path}")
                return None

            df = pd.read_feather(futures_path)
            print(f"Loaded futures data: {df.shape} rows")
            return df
        except Exception as e:
            print(f"Error loading futures data: {e}")
            return None

    def merge_futures_data(self, spot_df, futures_df):
        """Merge spot and futures data"""
        try:
            # Merge on date column
            merged = pd.merge(spot_df, futures_df[['date', 'close', 'volume']],
                            left_on='date', right_on='date', how='left',
                            suffixes=('', '_perp'))

            # Forward fill missing futures data
            merged[['close_perp', 'volume_perp']] = merged[['close_perp', 'volume_perp']].ffill()
            
            print(f"Merged data shape: {merged.shape}")
            print(f"Perp data coverage: {merged['close_perp'].notna().sum()}/{len(merged)} rows")

            return merged
        except Exception as e:
            print(f"Error merging futures data: {e}")
            return spot_df

    def calculate_basis_features(self, dataframe: DataFrame) -> DataFrame:
        """Calculate perp-spot basis features"""
        if 'close_perp' not in dataframe.columns:
            print("No perp data available for basis calculation")
            return dataframe

        # Basic basis calculation (perp - spot) / spot
        dataframe['basis'] = (dataframe['close_perp'] - dataframe['close']) / dataframe['close'] * 100

        # Basis moving averages
        dataframe['basis_ma_10'] = ta.SMA(dataframe['basis'], timeperiod=10)
        dataframe['basis_ma_30'] = ta.SMA(dataframe['basis'], timeperiod=30)

        # Basis rate of change
        dataframe['basis_roc'] = ta.ROC(dataframe['basis'], timeperiod=5)

        # Z-score of basis
        basis_mean = dataframe['basis'].rolling(window=50).mean()
        basis_std = dataframe['basis'].rolling(window=50).std()
        dataframe['basis_zscore'] = (dataframe['basis'] - basis_mean) / basis_std

        # Volume ratio
        dataframe['volume_ratio'] = dataframe['volume_perp'] / dataframe['volume']

        # Basis momentum
        dataframe['basis_momentum'] = dataframe['basis'] - dataframe['basis_ma_30']

        # Extreme basis conditions
        dataframe['basis_extreme_bull'] = (dataframe['basis_zscore'] > 2).astype(int)
        dataframe['basis_extreme_bear'] = (dataframe['basis_zscore'] < -2).astype(int)

        print(f"Basis stats - Mean: {dataframe['basis'].mean():.4f}, Std: {dataframe['basis'].std():.4f}")
        print(f"Basis Z-score range: {dataframe['basis_zscore'].min():.2f} to {dataframe['basis_zscore'].max():.2f}")

        return dataframe

    def calculate_volume_features(self, dataframe):
        """Enhanced volume analysis features"""
        try:
            # Volume moving averages
            dataframe['volume_ma_10'] = ta.SMA(dataframe['volume'], timeperiod=10)
            dataframe['volume_ma_30'] = ta.SMA(dataframe['volume'], timeperiod=30)

            # Volume rate of change
            dataframe['volume_roc'] = ta.ROC(dataframe['volume'], timeperiod=5)

            # Volume ratio (current vs moving average)
            dataframe['volume_ratio_ma'] = dataframe['volume'] / dataframe['volume_ma_30']

            # On-balance volume (OBV)
            dataframe['obv'] = ta.OBV(dataframe['close'], dataframe['volume'])

            # Volume weighted average price (VWAP)
            vwap_period = 20
            cumulative_price_volume = (dataframe['close'] * dataframe['volume']).rolling(vwap_period).sum()
            cumulative_volume = dataframe['volume'].rolling(vwap_period).sum()
            dataframe['vwap'] = cumulative_price_volume / cumulative_volume

            # Volume extremes
            dataframe['high_volume'] = (dataframe['volume'] > dataframe['volume_ma_30'] * 1.5).astype(int)
            dataframe['low_volume'] = (dataframe['volume'] < dataframe['volume_ma_30'] * 0.5).astype(int)

            return dataframe
        except Exception as e:
            print(f"Error calculating volume features: {e}")
            return dataframe

    freqai_prediction_threshold = DecimalParameter(0.5, 0.9, default=0.75, space='buy', optimize=True, load=True)

    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        pair = metadata['pair']
        
        print(f"\n=== ENTRY LOGIC DEBUG for {pair} ===")
        print(f"Dataframe shape in entry: {dataframe.shape}")
        
        # Check for FreqAI signal
        if '&-enter_long' in dataframe.columns:
            freqai_signal = dataframe['&-enter_long'].iloc[-1]
            threshold = self.freqai_prediction_threshold.value
            print(f"FreqAI signal: {freqai_signal}, Threshold: {threshold}")
            
            if freqai_signal > threshold:
                print(f"FreqAI signal triggered! Setting enter_long=1")
                dataframe.loc[dataframe.index[-1], 'enter_long'] = 1
            else:
                print(f"FreqAI signal below threshold")
        else:
            print("No FreqAI signal column found!")
            
            # Alternative entry logic for testing without FreqAI
            print("Using alternative entry logic...")
            
            # Simple RSI + EMA crossover entry
            rsi_condition = dataframe['rsi'] < 30  # Oversold
            ema_condition = dataframe['ema_20'] > dataframe['ema_50']  # Uptrend
            
            entry_condition = rsi_condition & ema_condition
            
            if entry_condition.iloc[-1]:
                print("Alternative entry condition met!")
                dataframe.loc[dataframe.index[-1], 'enter_long'] = 1
            else:
                print("Alternative entry condition not met")

        # Debug: Check if any entry signals were set
        entry_signals = dataframe['enter_long'].sum() if 'enter_long' in dataframe.columns else 0
        print(f"Total entry signals in dataframe: {entry_signals}")
        
        return dataframe

    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe.loc[:, 'exit_long'] = 0

        # Basis normalization exit
        if 'basis_zscore' in dataframe.columns:
            long_basis_normalization = dataframe['basis_zscore'] > 1.0
            dataframe.loc[long_basis_normalization, 'exit_long'] = 1

        # RSI overbought exit
        strong_overbought = dataframe['rsi'] > 75
        dataframe.loc[strong_overbought, 'exit_long'] = 1

        return dataframe

    # FreqAI configuration - same as original
    freqai_info = {
        "identifier": "SKLearnRandomForestClassifier",
        "features": [
            "rsi",
            "adx", 
            "ema_20",
            "ema_50",
            "macd",
            "macdsignal",
            "macdhist",
            "volume_ratio_ma",
            "obv",
            "vwap",
        ],
        "label_period_candles": 12, # Predict 1 hour into the future
        "data_split_parameters": {"split_train": 0.8, "split_test": 0.2},
        "model_training_parameters": {}
    }