Team Ai
Apppublic

Deepvest/ProfilingAI

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
ml_analyzer.py994 linesDownload Raw Back to analysis
1# src/analysis/ml_analyzer.py2 3import numpy as np4import pandas as pd5from typing import Dict, List, Optional, Any6from datetime import datetime7from sklearn.ensemble import RandomForestClassifier, GradientBoostingRegressor8from sklearn.preprocessing import StandardScaler9import torch10import torch.nn as nn11import logging12 13from transformers import AutoTokenizer, AutoModelForSequenceClassification14from ..core.types import MLAnalyzerProtocol15 16class AlternativeDataAnalyzer:17    """Analyze alternative data sources for market insights"""18    19    def __init__(self):20        self.social_sentiment_model = RandomForestClassifier(n_estimators=100)21        self.web_traffic_model = RandomForestClassifier(n_estimators=50)22        23    def analyze_social_sentiment(self, social_data: List[Dict]) -> float:24        """Analyze social media sentiment"""25        features = self._extract_social_features(social_data)26        return float(self.social_sentiment_model.predict(features)[0])27        28    def analyze_web_traffic(self, traffic_data: pd.DataFrame) -> Dict[str, float]:29        """Analyze web traffic patterns"""30        features = self._prepare_traffic_features(traffic_data)31        predictions = self.web_traffic_model.predict(features)32        return {33            'growth_score': float(np.mean(predictions)),34            'trend_strength': float(np.std(predictions))35        }36 37 38class MarketImpactPredictor:39    """Predicts market impact of trades using machine learning"""40    41    def __init__(self):42        self.impact_model = GradientBoostingRegressor(43            n_estimators=100,44            learning_rate=0.1,45            max_depth=3,46            random_state=4247        )48        self.scaler = StandardScaler()49        self.feature_columns = [50            'trade_size_norm',51            'volume_profile',52            'volatility',53            'bid_ask_spread',54            'market_regime',55            'time_of_day'56        ]57        58    def predict_trade_impact(self,59                           trade_size: float,60                           market_data: pd.DataFrame,61                           market_conditions: Optional[Dict] = None) -> Dict[str, float]:62        """63        Predict market impact of a trade64        65        Args:66            trade_size: Size of the trade67            market_data: Market data (prices, volumes, etc.)68            market_conditions: Additional market condition indicators69            70        Returns:71            Dictionary with impact predictions and metrics72        """73        try:74            # Extract features75            features = self._extract_impact_features(76                trade_size, 77                market_data, 78                market_conditions79            )80            81            # Scale features82            scaled_features = self.scaler.transform(features)83            84            # Predict impact85            base_impact = float(self.impact_model.predict(scaled_features)[0])86            87            # Adjust for market conditions88            adjusted_impact = self._adjust_for_market_conditions(89                base_impact,90                market_conditions91            )92            93            # Calculate confidence and risk metrics94            confidence = self._calculate_prediction_confidence(features)95            risk_metrics = self._calculate_impact_risk_metrics(96                adjusted_impact,97                market_data98            )99            100            return {101                'predicted_impact': adjusted_impact,102                'base_impact': base_impact,103                'confidence': confidence,104                'risk_metrics': risk_metrics,105                'recommended_sizing': self._calculate_recommended_sizing(106                    trade_size,107                    adjusted_impact,108                    market_data109                )110            }111            112        except Exception as e:113            print(f"Error predicting market impact: {e}")114            return {115                'predicted_impact': self._calculate_simple_impact(116                    trade_size, 117                    market_data118                ),119                'confidence': 0.0,120                'risk_metrics': {}121            }122 123    def _extract_impact_features(self,124                               trade_size: float,125                               market_data: pd.DataFrame,126                               market_conditions: Optional[Dict]) -> np.ndarray:127        """Extract features for impact prediction"""128        try:129            features = []130            131            # Normalize trade size by average daily volume132            avg_volume = market_data['volume'].mean()133            trade_size_norm = trade_size / avg_volume if avg_volume > 0 else 0134            features.append(trade_size_norm)135            136            # Volume profile137            volume_profile = self._calculate_volume_profile(market_data)138            features.append(volume_profile)139            140            # Market volatility141            volatility = market_data['close'].pct_change().std()142            features.append(volatility)143            144            # Bid-ask spread145            spread = self._calculate_bid_ask_spread(market_data)146            features.append(spread)147            148            # Market regime indicator149            regime_indicator = self._get_regime_indicator(market_conditions)150            features.append(regime_indicator)151            152            # Time of day effect153            time_feature = self._calculate_time_feature(market_data)154            features.append(time_feature)155            156            return np.array(features).reshape(1, -1)157            158        except Exception as e:159            print(f"Error extracting impact features: {e}")160            return np.zeros((1, len(self.feature_columns)))161 162    def _adjust_for_market_conditions(self,163                                    base_impact: float,164                                    market_conditions: Optional[Dict]) -> float:165        """Adjust impact prediction based on market conditions"""166        try:167            if not market_conditions:168                return base_impact169                170            # Volatility adjustment171            volatility_factor = market_conditions.get('volatility', 1.0)172            173            # Liquidity adjustment174            liquidity_factor = 1 / market_conditions.get('liquidity', 1.0)175            176            # Regime adjustment177            regime_factor = self._get_regime_factor(market_conditions)178            179            # Combined adjustment180            adjustment = (volatility_factor * liquidity_factor * regime_factor)181            182            return base_impact * adjustment183            184        except Exception as e:185            print(f"Error adjusting for market conditions: {e}")186            return base_impact187 188    def _calculate_prediction_confidence(self, features: np.ndarray) -> float:189        """Calculate confidence score for impact prediction"""190        try:191            # Base confidence192            confidence = 0.8193            194            # Adjust based on feature quality195            for i, feature in enumerate(features[0]):196                if np.isnan(feature) or np.isinf(feature):197                    confidence *= 0.8198                    199            # Adjust based on feature values200            trade_size_norm = features[0][0]201            if trade_size_norm > 0.1:  # Large trades202                confidence *= 0.9203                204            return float(confidence)205            206        except Exception as e:207            print(f"Error calculating prediction confidence: {e}")208            return 0.5209 210    def _calculate_impact_risk_metrics(self,211                                     impact: float,212                                     market_data: pd.DataFrame) -> Dict[str, float]:213        """Calculate risk metrics for impact prediction"""214        try:215            metrics = {}216            217            # Calculate VaR of impact218            metrics['impact_var_95'] = impact * 1.645  # Assuming normal distribution219            220            # Calculate potential slippage221            metrics['max_slippage'] = impact * 2222            223            # Timing risk224            metrics['timing_risk'] = self._calculate_timing_risk(market_data)225            226            return metrics227            228        except Exception as e:229            print(f"Error calculating impact risk metrics: {e}")230            return {}231 232    def _calculate_simple_impact(self,233                               trade_size: float,234                               market_data: pd.DataFrame) -> float:235        """Calculate simple market impact estimate"""236        try:237            avg_volume = market_data['volume'].mean()238            participation_rate = trade_size / avg_volume if avg_volume > 0 else 0239            240            # Square root model241            return 0.1 * np.sqrt(participation_rate)242            243        except Exception as e:244            print(f"Error calculating simple impact: {e}")245            return 0.01  # Default 1 bp impact246 247    def _calculate_recommended_sizing(self,248                                   trade_size: float,249                                   predicted_impact: float,250                                   market_data: pd.DataFrame) -> Dict[str, float]:251        """Calculate recommended trade sizing"""252        try:253            avg_volume = market_data['volume'].mean()254            255            # Calculate different size recommendations256            aggressive = min(trade_size, avg_volume * 0.1)257            normal = min(trade_size, avg_volume * 0.05)258            passive = min(trade_size, avg_volume * 0.02)259            260            return {261                'aggressive_size': float(aggressive),262                'normal_size': float(normal),263                'passive_size': float(passive),264                'optimal_size': float(normal)  # Could be adjusted based on urgency265            }266            267        except Exception as e:268            print(f"Error calculating recommended sizing: {e}")269            return {'optimal_size': trade_size * 0.05}270 271    @staticmethod272    def _calculate_volume_profile(market_data: pd.DataFrame) -> float:273        """Calculate volume profile metric"""274        try:275            recent_volume = market_data['volume'].tail(20).mean()276            hist_volume = market_data['volume'].mean()277            return recent_volume / hist_volume if hist_volume > 0 else 1.0278        except:279            return 1.0280 281    @staticmethod282    def _calculate_bid_ask_spread(market_data: pd.DataFrame) -> float:283        """Calculate average bid-ask spread"""284        try:285            if 'bid' in market_data and 'ask' in market_data:286                spread = (market_data['ask'] - market_data['bid']) / market_data['ask']287                return float(spread.mean())288            return 0.001  # Default 10 bp spread289        except:290            return 0.001291 292    @staticmethod293    def _get_regime_indicator(market_conditions: Optional[Dict]) -> float:294        """Get numerical indicator for market regime"""295        try:296            if not market_conditions:297                return 0.0298            regime = market_conditions.get('regime', 'normal')299            regime_map = {300                'crisis': -1.0,301                'stress': -0.5,302                'normal': 0.0,303                'calm': 0.5,304                'highly_liquid': 1.0305            }306            return regime_map.get(regime, 0.0)307        except:308            return 0.0309 310    @staticmethod311    def _calculate_time_feature(market_data: pd.DataFrame) -> float:312        """Calculate time of day feature"""313        try:314            if isinstance(market_data.index, pd.DatetimeIndex):315                hour = market_data.index[-1].hour316                # Normalize to 0-1 range, with peak at market open/close317                return np.sin(np.pi * hour / 12)318            return 0.0319        except:320            return 0.0321 322    @staticmethod323    def _get_regime_factor(market_conditions: Optional[Dict]) -> float:324        """Get adjustment factor for market regime"""325        try:326            if not market_conditions:327                return 1.0328            regime = market_conditions.get('regime', 'normal')329            regime_factors = {330                'crisis': 2.0,331                'stress': 1.5,332                'normal': 1.0,333                'calm': 0.8,334                'highly_liquid': 0.5335            }336            return regime_factors.get(regime, 1.0)337        except:338            return 1.0339 340    @staticmethod341    def _calculate_timing_risk(market_data: pd.DataFrame) -> float:342        """Calculate timing risk metric"""343        try:344            returns = market_data['close'].pct_change()345            volatility = returns.std()346            return float(volatility * np.sqrt(252))347        except:348            return 0.2  # Default 20% annualized vol349 350class SentimentAnalyzer:351    """Advanced sentiment analyzer for market and news data"""352    353    def __init__(self):354        self.sentiment_model = None355        self.text_vectorizer = None356        self.market_indicators = [357            'price_momentum',358            'volume_change',359            'volatility',360            'rsi',361            'macd',362            'social_sentiment'363        ]364        365    def analyze_sentiment(self,366                         market_data: pd.DataFrame,367                         news_data: Optional[List[str]] = None,368                         social_data: Optional[Dict[str, Any]] = None) -> Dict[str, float]:369        """370        Analyze overall market sentiment using multiple data sources.371        372        Args:373            market_data: Market price and volume data374            news_data: List of news articles/headlines375            social_data: Social media sentiment data376            377        Returns:378            Dictionary of sentiment scores379        """380        try:381            # Market technical sentiment382            market_sentiment = self._analyze_market_sentiment(market_data)383            384            # News sentiment385            news_sentiment = self._analyze_news_sentiment(news_data) if news_data else 0.5386            387            # Social media sentiment388            social_sentiment = self._analyze_social_sentiment(social_data) if social_data else 0.5389            390            # Combine all sentiment signals391            composite_sentiment = self._calculate_composite_sentiment(392                market_sentiment,393                news_sentiment,394                social_sentiment395            )396            397            return {398                'composite_sentiment': composite_sentiment,399                'market_sentiment': market_sentiment,400                'news_sentiment': news_sentiment,401                'social_sentiment': social_sentiment,402                'sentiment_indicators': self._calculate_sentiment_indicators(market_data),403                'confidence_score': self._calculate_confidence_score(market_data)404            }405            406        except Exception as e:407            print(f"Error in sentiment analysis: {e}")408            return {409                'composite_sentiment': 0.5,410                'market_sentiment': 0.5,411                'news_sentiment': 0.5,412                'social_sentiment': 0.5,413                'sentiment_indicators': {},414                'confidence_score': 0.0415            }416 417    def _analyze_market_sentiment(self, market_data: pd.DataFrame) -> float:418        """Analyze sentiment from market data"""419        try:420            if market_data.empty:421                return 0.5422                423            sentiment_scores = []424            425            # Price momentum426            returns = market_data['close'].pct_change()427            momentum = returns.rolling(window=20).mean().iloc[-1]428            sentiment_scores.append(self._normalize_score(momentum, -0.02, 0.02))429            430            # Volume trend431            volume_change = market_data['volume'].pct_change()432            vol_trend = volume_change.rolling(window=20).mean().iloc[-1]433            sentiment_scores.append(self._normalize_score(vol_trend, -0.1, 0.1))434            435            # RSI436            rsi = self._calculate_rsi(market_data)437            sentiment_scores.append(self._normalize_score(rsi, 30, 70))438            439            # Weighted average440            weights = [0.5, 0.3, 0.2]441            return sum(score * weight for score, weight 442                      in zip(sentiment_scores, weights))443                      444        except Exception as e:445            print(f"Error in market sentiment analysis: {e}")446            return 0.5447 448    def _analyze_news_sentiment(self, news_data: List[str]) -> float:449        """Analyze sentiment from news articles"""450        try:451            if not news_data:452                return 0.5453                454            # Simple keyword-based sentiment (placeholder)455            positive_words = {'growth', 'profit', 'success', 'gain', 'rally'}456            negative_words = {'loss', 'risk', 'decline', 'crash', 'fear'}457            458            total_score = 0459            for text in news_data:460                words = set(text.lower().split())461                positive_count = len(words.intersection(positive_words))462                negative_count = len(words.intersection(negative_words))463                464                if positive_count + negative_count > 0:465                    score = positive_count / (positive_count + negative_count)466                else:467                    score = 0.5468                    469                total_score += score470                471            return total_score / len(news_data)472            473        except Exception as e:474            print(f"Error in news sentiment analysis: {e}")475            return 0.5476 477    def _analyze_social_sentiment(self, social_data: Dict[str, Any]) -> float:478        """Analyze sentiment from social media data"""479        try:480            if not social_data:481                return 0.5482                483            sentiment_scores = []484            485            # Process different social media sources486            for source, data in social_data.items():487                if source == 'twitter':488                    score = self._analyze_twitter_sentiment(data)489                elif source == 'reddit':490                    score = self._analyze_reddit_sentiment(data)491                else:492                    score = 0.5493                    494                sentiment_scores.append(score)495                496            return np.mean(sentiment_scores) if sentiment_scores else 0.5497            498        except Exception as e:499            print(f"Error in social sentiment analysis: {e}")500            return 0.5501 502    def _calculate_composite_sentiment(self,503                                    market_sentiment: float,504                                    news_sentiment: float,505                                    social_sentiment: float) -> float:506        """Calculate weighted composite sentiment"""507        weights = {508            'market': 0.5,509            'news': 0.3,510            'social': 0.2511        }512        513        composite = (514            weights['market'] * market_sentiment +515            weights['news'] * news_sentiment +516            weights['social'] * social_sentiment517        )518        519        return min(max(composite, 0), 1)  # Ensure between 0 and 1520 521    def _calculate_sentiment_indicators(self, market_data: pd.DataFrame) -> Dict[str, float]:522        """Calculate various sentiment indicators"""523        try:524            indicators = {}525            526            for indicator in self.market_indicators:527                if indicator == 'price_momentum':528                    value = self._calculate_momentum(market_data)529                elif indicator == 'volume_change':530                    value = self._calculate_volume_change(market_data)531                elif indicator == 'volatility':532                    value = self._calculate_volatility(market_data)533                else:534                    value = 0.0535                    536                indicators[indicator] = value537                538            return indicators539            540        except Exception as e:541            print(f"Error calculating sentiment indicators: {e}")542            return {}543 544    @staticmethod545    def _normalize_score(value: float, min_val: float, max_val: float) -> float:546        """Normalize a value to a 0-1 range"""547        try:548            return min(max((value - min_val) / (max_val - min_val), 0), 1)549        except:550            return 0.5551 552    @staticmethod553    def _calculate_rsi(data: pd.DataFrame, periods: int = 14) -> float:554        """Calculate RSI indicator"""555        try:556            delta = data['close'].diff()557            gain = (delta.where(delta > 0, 0)).rolling(window=periods).mean()558            loss = (-delta.where(delta < 0, 0)).rolling(window=periods).mean()559            rs = gain / loss560            return float(100 - (100 / (1 + rs.iloc[-1])))561        except:562            return 50.0563 564    def _calculate_confidence_score(self, market_data: pd.DataFrame) -> float:565        """Calculate confidence score for sentiment analysis"""566        try:567            # Volatility-based confidence568            volatility = self._calculate_volatility(market_data)569            volume = self._calculate_volume_change(market_data)570            571            # Lower confidence in high volatility periods572            confidence = 1 - min(volatility, 0.5)573            574            # Higher confidence with higher volume575            volume_factor = min(max(volume, 0), 1)576            confidence *= (0.7 + 0.3 * volume_factor)577            578            return float(confidence)579            580        except Exception as e:581            print(f"Error calculating confidence score: {e}")582            return 0.0583 584    @staticmethod585    def _calculate_momentum(data: pd.DataFrame, window: int = 20) -> float:586        """Calculate price momentum"""587        try:588            returns = data['close'].pct_change()589            return float(returns.rolling(window=window).mean().iloc[-1])590        except:591            return 0.0592 593    @staticmethod594    def _calculate_volume_change(data: pd.DataFrame, window: int = 20) -> float:595        """Calculate volume trend"""596        try:597            volume_change = data['volume'].pct_change()598            return float(volume_change.rolling(window=window).mean().iloc[-1])599        except:600            return 0.0601 602    @staticmethod603    def _calculate_volatility(data: pd.DataFrame, window: int = 20) -> float:604        """Calculate price volatility"""605        try:606            returns = data['close'].pct_change()607            return float(returns.rolling(window=window).std().iloc[-1])608        except:609            return 0.0610 611class MarketRegimeClassifier:612    """Classifier for market regimes using machine learning"""613    614    def __init__(self):615        self.model = GaussianMixture(n_components=3, random_state=42)616        self.scaler = StandardScaler()617        self.regimes = ['bear', 'neutral', 'bull']618        619    def extract_features(self, market_data: pd.DataFrame) -> np.ndarray:620        """Extract relevant features for regime classification"""621        features = []622        623        # Price-based features624        returns = market_data['close'].pct_change()625        features.extend([626            returns.mean(),             # Mean return627            returns.std(),              # Volatility628            returns.skew(),             # Asymmetry629            returns.kurt(),             # Kurtosis630            self._calculate_momentum(market_data),  # Momentum631            self._calculate_rsi(market_data),       # RSI632            self._calculate_volatility_regime(returns)  # Volatility regime633        ])634        635        return np.array(features).reshape(1, -1)636 637    def predict_regime(self, market_data: pd.DataFrame) -> str:638        """Predict current market regime"""639        features = self.extract_features(market_data)640        scaled_features = self.scaler.transform(features)641        regime_idx = self.model.predict(scaled_features)[0]642        return self.regimes[regime_idx]643 644    def _calculate_momentum(self, data: pd.DataFrame, window: int = 63) -> float:645        """Calculate price momentum"""646        returns = data['close'].pct_change()647        return returns.rolling(window=window).mean().iloc[-1]648 649    def _calculate_rsi(self, data: pd.DataFrame, periods: int = 14) -> float:650        """Calculate RSI indicator"""651        delta = data['close'].pct_change()652        gain = (delta.where(delta > 0, 0)).rolling(window=periods).mean()653        loss = (-delta.where(delta < 0, 0)).rolling(window=periods).mean()654        rs = gain / loss655        return 100 - (100 / (1 + rs.iloc[-1]))656 657    def _calculate_volatility_regime(self, returns: pd.Series, window: int = 21) -> float:658        """Calculate volatility regime indicator"""659        vol = returns.rolling(window=window).std() * np.sqrt(252)660        return vol.iloc[-1]661 662class MLEnhancedAnalyzer:663    """Enhanced market analyzer with machine learning capabilities"""664    def _setup_logger(self) -> logging.Logger:665        """Configuration du système de logging"""666        logger = logging.getLogger('Deepvest')667        logger.setLevel(logging.INFO)668        handler = logging.StreamHandler()669        formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')670        handler.setFormatter(formatter)671        logger.addHandler(handler)672        return logger673    674    def __init__(self):675        self.regime_classifier = MarketRegimeClassifier()676        self.sentiment_analyzer = self._initialize_sentiment_model()677        678    def _initialize_sentiment_model(self):679        return GaussianMixture(n_components=2, random_state=42)680        681    def predict_market_regime(self, market_data: pd.DataFrame) -> str:682        """Predict market regime"""683        return self.regime_classifier.predict_regime(market_data)684        685    def analyze_market_sentiment(self, 686                               market_data: pd.DataFrame, 687                               news_data: Optional[List[str]] = None) -> float:688        """Analyze market sentiment"""689        market_features = self._extract_market_features(market_data)690        sentiment_score = self.sentiment_analyzer.predict_proba(market_features)691        if news_data:692            news_sentiment = self._analyze_news_sentiment(news_data)693            sentiment_score = 0.7 * sentiment_score + 0.3 * news_sentiment694        return float(sentiment_score.mean())695 696    def _extract_market_features(self, market_data: pd.DataFrame) -> np.ndarray:697        """Extract features for sentiment analysis"""698        if market_data.empty:699            return np.array([[0]])700            701        features = []702        returns = market_data['close'].pct_change().dropna()703        704        # Basic features705        features.extend([706            returns.mean(),707            returns.std(),708            returns.skew(),709            returns.kurt()710        ])711        712        # Technical features713        features.extend([714            self._calculate_macd(market_data),715            self._calculate_rsi(market_data),716            self._calculate_bollinger_bands(market_data)717        ])718        719        return np.array(features).reshape(1, -1)720 721    @staticmethod722    def _calculate_macd(data: pd.DataFrame) -> float:723        """Calculate MACD indicator"""724        if 'close' not in data.columns or len(data) < 26:725            return 0.0726        exp1 = data['close'].ewm(span=12, adjust=False).mean()727        exp2 = data['close'].ewm(span=26, adjust=False).mean()728        macd = exp1 - exp2729        return float(macd.iloc[-1])730 731    @staticmethod732    def _calculate_bollinger_bands(data: pd.DataFrame) -> float:733        """Calculate Bollinger Bands position"""734        if 'close' not in data.columns or len(data) < 20:735            return 0.0736        ma = data['close'].rolling(window=20).mean()737        std = data['close'].rolling(window=20).std()738        upper = ma + (std * 2)739        lower = ma - (std * 2)740        position = (data['close'] - lower) / (upper - lower)741        return float(position.iloc[-1])742 743    def _analyze_news_sentiment(self, news_data: List[str]) -> float:744        """Simple sentiment analysis of news data"""745        # Placeholder - would normally use NLP model746        return 0.5747 748class MLEnhancedAnalyzer(MLAnalyzerProtocol):749    """ML-enhanced market analysis implementation"""750    751    def __init__(self):752        # Modèles pour différentes tâches d'analyse753        self.regime_classifier = RandomForestClassifier(n_estimators=100, random_state=42)754        self.risk_predictor = GradientBoostingRegressor(n_estimators=100, random_state=42)755        self.scaler = StandardScaler()756        757        # Modèle de sentiment758        self.sentiment_tokenizer = AutoTokenizer.from_pretrained("nickmuchi/finbert-tone-finetuned-finance-text-classification")759        self.sentiment_model = AutoModelForSequenceClassification.from_pretrained("nickmuchi/finbert-tone-finetuned-finance-text-classification")760        761    async def analyze_market_conditions(self,762                                     market_data: pd.DataFrame,763                                     news_data: Optional[List[str]] = None,764                                     alternative_data: Optional[Dict] = None) -> Dict[str, Any]:765        """Analyse complète des conditions de marché utilisant ML"""766        try:767            # Préparer les features768            features = self._prepare_features(market_data)769            scaled_features = self.scaler.transform(features)770            771            # Analyse du régime de marché772            regime = self._predict_market_regime(scaled_features)773            774            # Analyse des risques775            risk_metrics = self._analyze_risk_factors(market_data)776            777            # Analyse technique778            technical_metrics = self._analyze_technical_factors(market_data)779            780            # Analyse du sentiment si des données sont disponibles781            sentiment = {}782            if news_data:783                sentiment = await self._analyze_sentiment(news_data)784            785            # Analyse des données alternatives si disponibles786            alt_insights = {}787            if alternative_data:788                alt_insights = self._analyze_alternative_data(alternative_data)789            790            return {791                'regime': regime,792                'risk_metrics': risk_metrics,793                'technical_metrics': technical_metrics,794                'sentiment': sentiment,795                'alternative_insights': alt_insights,796                'timestamp': datetime.now()797            }798            799        except Exception as e:800            print(f"Error in ML market analysis: {str(e)}")801            return self._get_default_analysis()802 803    def _prepare_features(self, market_data: pd.DataFrame) -> np.ndarray:804        """Prépare les features pour l'analyse ML"""805        try:806            # Calculer les rendements si nécessaire807            if 'returns' not in market_data.columns:808                returns = market_data.pct_change().dropna()809            else:810                returns = market_data['returns'].dropna()811            812            features = []813            814            # Features basées sur les rendements815            features.extend([816                returns.mean(),817                returns.std(),818                returns.skew(),819                returns.kurtosis(),820                (returns < 0).mean()821            ])822            823            # Features basées sur le volume si disponible824            if 'volume' in market_data.columns:825                volume = market_data['volume']826                features.extend([827                    volume.mean(),828                    volume.std() / volume.mean(),829                    (volume.pct_change() > 0).mean()830                ])831            832            # Features techniques si disponibles833            if 'close' in market_data.columns:834                close_prices = market_data['close']835                features.extend(self._calculate_technical_features(close_prices))836            837            return np.array(features).reshape(1, -1)838            839        except Exception as e:840            print(f"Error preparing features: {str(e)}")841            return np.zeros((1, 10))  # Features par défaut842 843    def _predict_market_regime(self, features: np.ndarray) -> str:844        """Prédit le régime de marché actuel"""845        try:846            prediction = self.regime_classifier.predict(features)[0]847            regimes = ['BULL_MARKET', 'BEAR_MARKET', 'HIGH_VOLATILITY', 'LOW_VOLATILITY']848            return regimes[prediction] if isinstance(prediction, (int, np.integer)) else 'LOW_VOLATILITY'849        except Exception as e:850            print(f"Error predicting regime: {str(e)}")851            return 'LOW_VOLATILITY'852 853    def _analyze_risk_factors(self, market_data: pd.DataFrame) -> Dict[str, float]:854        """Analyse des facteurs de risque"""855        try:856            returns = market_data.pct_change().dropna()857            858            risk_metrics = {859                'volatility': float(returns.std() * np.sqrt(252)),860                'tail_risk': self._calculate_tail_risk(returns),861                'var_95': float(np.percentile(returns, 5)),862                'skewness': float(returns.skew()),863                'kurtosis': float(returns.kurtosis())864            }865            866            return risk_metrics867            868        except Exception as e:869            print(f"Error analyzing risk factors: {str(e)}")870            return {871                'volatility': 0.15,872                'tail_risk': 0.05,873                'var_95': -0.02,874                'skewness': 0.0,875                'kurtosis': 3.0876            }877 878    async def _analyze_sentiment(self, news_data: List[str]) -> Dict[str, float]:879        """Analyse du sentiment des nouvelles"""880        try:881            sentiments = []882            for text in news_data:883                # Tokenization et préparation884                inputs = self.sentiment_tokenizer(text, return_tensors="pt", padding=True, truncation=True)885                886                # Analyse avec le modèle887                with torch.no_grad():888                    outputs = self.sentiment_model(**inputs)889                    logits = outputs.logits890                    probs = torch.softmax(logits, dim=1)891                    sentiments.append(probs.tolist()[0])892            893            # Agrégation des sentiments894            avg_sentiment = np.mean(sentiments, axis=0)895            return {896                'positive': float(avg_sentiment[2]),  # Indice 2 pour le sentiment positif897                'neutral': float(avg_sentiment[1]),   # Indice 1 pour le sentiment neutre898                'negative': float(avg_sentiment[0])   # Indice 0 pour le sentiment négatif899            }900            901        except Exception as e:902            print(f"Error analyzing sentiment: {str(e)}")903            return {'positive': 0.33, 'neutral': 0.34, 'negative': 0.33}904 905    def _analyze_technical_factors(self, market_data: pd.DataFrame) -> Dict[str, float]:906        """Analyse des facteurs techniques"""907        try:908            close_prices = market_data['close']909            910            return {911                'rsi': self._calculate_rsi(close_prices),912                'macd': self._calculate_macd(close_prices),913                'momentum': self._calculate_momentum(close_prices),914                'trend_strength': self._calculate_trend_strength(close_prices)915            }916            917        except Exception as e:918            print(f"Error analyzing technical factors: {str(e)}")919            return {920                'rsi': 50.0,921                'macd': 0.0,922                'momentum': 0.0,923                'trend_strength': 0.0924            }925 926    def _analyze_alternative_data(self, alternative_data: Dict) -> Dict[str, Any]:927        """Analyse des données alternatives"""928        insights = {}929        930        try:931            # Analyse des données sociales si disponibles932            if 'social_media' in alternative_data:933                insights['social'] = self._analyze_social_data(alternative_data['social_media'])934                935            # Analyse des données de trafic web si disponibles936            if 'web_traffic' in alternative_data:937                insights['traffic'] = self._analyze_web_traffic(alternative_data['web_traffic'])938                939            # Analyse des données satellite si disponibles940            if 'satellite' in alternative_data:941                insights['satellite'] = self._analyze_satellite_data(alternative_data['satellite'])942                943        except Exception as e:944            print(f"Error analyzing alternative data: {str(e)}")945            946        return insights947 948    @staticmethod949    def _calculate_rsi(prices: pd.Series, periods: int = 14) -> float:950        """Calcul du RSI"""951        try:952            delta = prices.diff()953            gain = (delta.where(delta > 0, 0)).rolling(window=periods).mean()954            loss = (-delta.where(delta < 0, 0)).rolling(window=periods).mean()955            rs = gain / loss956            return float(100 - (100 / (1 + rs.iloc[-1])))957        except Exception:958            return 50.0959 960    @staticmethod961    def _calculate_macd(prices: pd.Series) -> float:962        """Calcul du MACD"""963        try:964            exp1 = prices.ewm(span=12, adjust=False).mean()965            exp2 = prices.ewm(span=26, adjust=False).mean()966            macd = exp1 - exp2967            signal = macd.ewm(span=9, adjust=False).mean()968            return float(macd.iloc[-1] - signal.iloc[-1])969        except Exception:970            return 0.0971 972    @staticmethod973    def _get_default_analysis() -> Dict[str, Any]:974        """Retourne une analyse par défaut en cas d'erreur"""975        return {976            'regime': 'LOW_VOLATILITY',977            'risk_metrics': {978                'volatility': 0.15,979                'tail_risk': 0.05,980                'var_95': -0.02981            },982            'technical_metrics': {983                'rsi': 50.0,984                'macd': 0.0,985                'momentum': 0.0986            },987            'sentiment': {988                'positive': 0.33,989                'neutral': 0.34,990                'negative': 0.33991            },992            'alternative_insights': {},993            'timestamp': datetime.now()994        }