"""MACD (Moving Average Convergence Divergence) strategy."""

import pandas as pd
from decimal import Decimal
from typing import Optional, Dict, Any
from src.strategies.base import BaseStrategy, StrategySignal, SignalType
from src.data.indicators import get_indicators

class MACDStrategy(BaseStrategy):
    """MACD-based trading strategy."""
    
    def __init__(self, name: str, parameters: Optional[Dict[str, Any]] = None, timeframes: Optional[list] = None):
        """Initialize MACD strategy.
        
        Parameters:
            fast: Fast EMA period (default 12)
            slow: Slow EMA period (default 26)
            signal: Signal line period (default 9)
        """
        super().__init__(name, parameters, timeframes)
        self.fast = self.parameters.get('fast', 12)
        self.slow = self.parameters.get('slow', 26)
        self.signal = self.parameters.get('signal', 9)
        self.indicators = get_indicators()
        self._price_history = []
    
    async def on_tick(self, symbol: str, price: Decimal, timeframe: str, data: Dict[str, Any]) -> Optional[StrategySignal]:
        """Generate signal based on MACD."""
        
        
        # Add price to history
        self._price_history.append(float(price))
        if len(self._price_history) < self.slow + self.signal:
            return None
        
        # Calculate MACD
        prices = pd.Series(self._price_history[-self.slow-self.signal:])
        macd_data = self.indicators.macd(prices, self.fast, self.slow, self.signal)
        
        if len(macd_data['macd']) < 2:
            return None
        
        macd = macd_data['macd'].iloc[-1]
        signal_line = macd_data['signal'].iloc[-1]
        prev_macd = macd_data['macd'].iloc[-2]
        prev_signal = macd_data['signal'].iloc[-2]
        
        # Bullish crossover
        if prev_macd <= prev_signal and macd > signal_line:
            return StrategySignal(
                signal_type=SignalType.BUY,
                symbol=symbol,
                strength=min(1.0, abs(macd - signal_line) / abs(prev_macd - prev_signal) if prev_macd != prev_signal else 1.0),
                price=price,
                metadata={'macd': float(macd), 'signal': float(signal_line)}
            )
        # Bearish crossover
        elif prev_macd >= prev_signal and macd < signal_line:
            return StrategySignal(
                signal_type=SignalType.SELL,
                symbol=symbol,
                strength=min(1.0, abs(macd - signal_line) / abs(prev_macd - prev_signal) if prev_macd != prev_signal else 1.0),
                price=price,
                metadata={'macd': float(macd), 'signal': float(signal_line)}
            )
        
        return None
    
    def on_signal(self, signal: StrategySignal) -> Optional[StrategySignal]:
        """Process signal."""
        return signal if self.should_execute(signal) else None

