#!/usr/bin/env python3
"""
Weekend Pattern Trading Strategy
Exploite les patterns récurrents du weekend dans le crypto trading
"""

from datetime import datetime, timezone
from typing import Dict, Tuple

class WeekendPatternStrategy:
    """
    Stratégie basée sur les patterns weekend observés :
    - Vendredi : Bias LONG (accumulation avant weekend)
    - Samedi/Dimanche : Bias SHORT (volumes faibles, dérive baissière)
    - Lundi : Bias LONG (retour des institutionnels)
    """
    
    def __init__(self):
        self.day_bias = {
            0: 'LONG',     # Lundi - Retour après weekend
            1: 'NEUTRAL',  # Mardi
            2: 'NEUTRAL',  # Mercredi  
            3: 'NEUTRAL',  # Jeudi
            4: 'LONG',     # Vendredi - Accumulation pré-weekend
            5: 'SHORT',    # Samedi - Faibles volumes
            6: 'SHORT'     # Dimanche - Faibles volumes
        }
        
        self.confidence_boost = {
            0: 0.15,   # +15% confiance le lundi pour LONG
            1: 0.00,   
            2: 0.00,
            3: 0.00,
            4: 0.10,   # +10% confiance le vendredi pour LONG
            5: 0.20,   # +20% confiance le samedi pour SHORT
            6: 0.20    # +20% confiance le dimanche pour SHORT
        }
        
        self.leverage_adjustment = {
            0: 1.0,    # Leverage normal lundi
            1: 1.0,
            2: 1.0,
            3: 1.0,
            4: 0.8,    # Réduire leverage vendredi (avant volatilité weekend)
            5: 0.6,    # Leverage réduit weekend (faibles volumes = risque)
            6: 0.6     # Leverage réduit weekend
        }
    
    def get_current_bias(self) -> Tuple[str, float]:
        """Retourne le bias actuel et le boost de confiance"""
        now = datetime.now(timezone.utc)
        weekday = now.weekday()
        
        bias = self.day_bias[weekday]
        boost = self.confidence_boost[weekday]
        
        # Ajustements horaires supplémentaires
        hour = now.hour
        
        # Vendredi soir (après 18h UTC) : renforcer SHORT
        if weekday == 4 and hour >= 18:
            bias = 'SHORT'
            boost = 0.15
            
        # Dimanche soir (après 20h UTC) : anticiper LONG du lundi
        elif weekday == 6 and hour >= 20:
            bias = 'LONG'
            boost = 0.10
            
        # Lundi matin (avant 8h UTC) : opportunité LONG forte
        elif weekday == 0 and hour < 8:
            boost = 0.25  # Boost maximal
        
        return bias, boost
    
    def adjust_signal(self, signal: Dict) -> Dict:
        """
        Ajuste un signal de trading selon le pattern weekend
        
        Args:
            signal: Signal original avec 'signal_type', 'confidence', etc.
            
        Returns:
            Signal ajusté avec bias weekend appliqué
        """
        bias, boost = self.get_current_bias()
        weekday = datetime.now(timezone.utc).weekday()
        
        adjusted_signal = signal.copy()
        original_confidence = signal.get('confidence', 0.5)
        
        # Appliquer le bias si aligné avec le signal
        if bias != 'NEUTRAL':
            signal_type = signal.get('signal_type', 'HOLD')
            
            # Signal aligné avec le bias : booster la confiance
            if (bias == 'LONG' and signal_type == 'BUY') or \
               (bias == 'SHORT' and signal_type == 'SELL'):
                adjusted_signal['confidence'] = min(1.0, original_confidence + boost)
                adjusted_signal['reasoning'] = signal.get('reasoning', '') + \
                    f' [WEEKEND_PATTERN: {bias} bias, +{boost*100:.0f}% confidence]'
            
            # Signal opposé au bias : réduire la confiance
            elif (bias == 'LONG' and signal_type == 'SELL') or \
                 (bias == 'SHORT' and signal_type == 'BUY'):
                adjusted_signal['confidence'] = max(0.0, original_confidence - boost/2)
                adjusted_signal['reasoning'] = signal.get('reasoning', '') + \
                    f' [WEEKEND_PATTERN: Against {bias} bias, -{boost*50:.0f}% confidence]'
        
        # Ajuster le leverage selon le jour
        if 'leverage' in adjusted_signal:
            leverage_mult = self.leverage_adjustment[weekday]
            adjusted_signal['leverage'] = int(adjusted_signal['leverage'] * leverage_mult)
            if leverage_mult != 1.0:
                adjusted_signal['reasoning'] += f' [Leverage adjusted x{leverage_mult:.1f} for weekend]'
        
        return adjusted_signal
    
    def should_close_before_weekend(self, position: Dict) -> bool:
        """
        Détermine si une position devrait être fermée avant le weekend
        
        Args:
            position: Position avec 'pnl_percent', 'side', etc.
            
        Returns:
            True si la position devrait être fermée
        """
        now = datetime.now(timezone.utc)
        weekday = now.weekday()
        hour = now.hour
        
        # Vendredi après-midi : fermer les positions profitables
        if weekday == 4 and hour >= 14:
            pnl = position.get('pnl_percent', 0)
            
            # Fermer les LONG profitables avant weekend
            if position.get('side') == 'LONG' and pnl > 5:
                return True
            
            # Fermer les SHORT perdants (risque de pump vendredi soir)
            if position.get('side') == 'SHORT' and pnl < -3:
                return True
        
        # Dimanche soir : fermer les SHORT profitables
        if weekday == 6 and hour >= 20:
            pnl = position.get('pnl_percent', 0)
            if position.get('side') == 'SHORT' and pnl > 3:
                return True
        
        return False
    
    def get_strategy_status(self) -> Dict:
        """Retourne le statut actuel de la stratégie"""
        bias, boost = self.get_current_bias()
        weekday = datetime.now(timezone.utc).weekday()
        day_names = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
        
        return {
            'current_day': day_names[weekday],
            'current_bias': bias,
            'confidence_boost': f'+{boost*100:.0f}%',
            'leverage_multiplier': self.leverage_adjustment[weekday],
            'strategy': 'WEEKEND_PATTERN',
            'description': self._get_day_description(weekday)
        }
    
    def _get_day_description(self, weekday: int) -> str:
        """Description de la stratégie pour chaque jour"""
        descriptions = {
            0: "Monday bounce - Institutional return after weekend",
            1: "Neutral day - Follow technical signals",
            2: "Mid-week - No specific bias",
            3: "Thursday - Monitor for Friday setup",
            4: "Friday accumulation - Long bias before weekend",
            5: "Saturday low volume - Short bias on weak hands",
            6: "Sunday drift - Short bias, prepare Monday long"
        }
        return descriptions.get(weekday, "Unknown")

# Singleton instance
weekend_strategy = WeekendPatternStrategy()

def apply_weekend_pattern(signal: Dict) -> Dict:
    """Fonction helper pour appliquer le pattern weekend à un signal"""
    return weekend_strategy.adjust_signal(signal)

def should_close_for_weekend(position: Dict) -> bool:
    """Fonction helper pour déterminer si fermer avant weekend"""
    return weekend_strategy.should_close_before_weekend(position)