
    iL4                     8   d Z ddlZddlmZmZmZmZ ddlZddl	m
Z
  ej                  ej                          ej                  d      ZdZ	 ddlmZ d	Zej%                  d
       e
 G d d             Z G d d      ZdadefdZedk(  ro	  ed        ed        ed        e       Z ed       g dZg dZej=                  deedd      Z edej@                           edejB                           ed       g dZ"ej=                  dee"dd      Z edej@                           edejF                           edejB                           ed        g d!Z$ej=                  de$edd      Z edej@                           edejF                           edejB                           ed"       g d#Z%g d$Z&ejO                  de%e&      \  Z(Z! ed%e(         ede!        yy# e$ r ej)                  d       Y w xY w)&u   
Outlier Detection - Détection des données aberrantes
Inspiré de FreqAI - Évite les faux signaux sur pumps/dumps artificiels

Méthodes:
- Isolation Forest (sklearn)
- Z-Score (statistique)
- IQR (Interquartile Range)
    N)DictListTupleOptional)	dataclass)levelOutlierDetectorF)IsolationForestTu1   ✅ Sklearn disponible - Isolation Forest activéuM   ⚠️ Sklearn non disponible - utilisation méthodes statistiques uniquementc                   D    e Zd ZU dZeed<   eed<   eed<   eed<   eed<   y)OutlierAnalysisu!   Résultat de l'analyse d'outliers
is_outliermethod
confidencereasonscoreN)__name__
__module____qualname____doc__bool__annotations__strfloat     ./outlier_detection.pyr   r      s     +KKLr   r   c                      e Zd ZdZ	 	 	 ddededefdZ	 	 ddedee   d	ee   d
ee   dee   de	fdZ
dee   defdZd	ee   defdZddee   dedefdZddee   dedefdZ	 ddedee   d	ee   dedeeef   f
dZy)r	   u   
    Détecteur d'outliers multi-méthodes
    
    Détecte:
    - Pumps artificiels (volume explosif + price spike)
    - Flash crashes (chute brutale isolée)
    - Données corrompues (NaN, valeurs aberrantes)
    contaminationz_score_thresholdvolume_spike_thresholdc                 4   || _         || _        || _        t        rt	        |dd      | _        nd| _        t        j                  d       t        j                  d|dz   d       t        j                  d|        t        j                  d	| d
       y)z
        Args:
            contamination: % d'outliers attendus (Isolation Forest)
            z_score_threshold: Seuil Z-Score pour outliers
            volume_spike_threshold: Multiplicateur volume pour spike
        *   d   )r   random_staten_estimatorsNu    ✅ Outlier Detector initialiséu      • Contamination: %u      • Z-Score threshold: u      • Volume spike threshold: x)r   z_thresholdvolume_thresholdSKLEARN_AVAILABLEr
   isolation_forestloggerinfo)selfr   r   r    s       r   __init__zOutlierDetector.__init__2   s     +, 6 $3+ %D! %)D!67,]3->,?qAB01B0CDE56L5MQOPr   Nsymbolpricesvolumesrsibb_positionreturnc                     t        |      dk  st        |      dk  rt        ddddd      S t        j                  |d         st        j                  |d         rt        dd	d
dd
      S | j	                  |      }t        |      | j                  kD  r>t        ddt        t        |      | j                  z  d
      d|ddt        |            S | j                  |      }|| j                  kD  r,t        ddt        || j                  z  d
      d|dd|      S t        rB|?|<t        j                  |d   |d   ||| j                  |d      | j                  |d      gg      }g }	t        dd      D ]]  }
|
t        |       k\  s|	j                  ||
   ||
   ||| j                  |d|
dz    d      | j                  |d|
dz    d      g       _ t        |	      dk\  r|| j                  j!                  |	       | j                  j#                  |      d   }|dk(  r>| j                  j%                  |      d   }t        |      }|dk\  rt        dd|d|      S t        |      dk\  r|d   |d    z
  |d    z  d!z  nd}t        |      dkD  r4t        dd"t        t        |      dz  d
      d#|d$d%t        |            S | j'                  |      rt        dd&d'd(d)      S t        dd*dd+d      S ),u  
        Détecter si les données actuelles sont des outliers
        
        Args:
            symbol: Symbole crypto
            prices: Historique des prix (dernier = actuel)
            volumes: Historique des volumes
            rsi: RSI actuel (optionnel)
            bb_position: Position Bollinger (0-1, optionnel)
        
        Returns:
            OutlierAnalysis avec résultat
           FINSUFFICIENT_DATA        u!   Pas assez de données historiques)r   r   r   r   r   TNAN_DETECTIONg      ?u   Données NaN détectéesZ_SCORE_PRICEzPrix aberrant (Z-Score=z.2f)VOLUME_SPIKEzVolume explosif (.1fz	x normal)N   )periods      
   r   gffffff?ISOLATION_FORESTu.   Pattern anormal détecté par Isolation Forest   r#   PRICE_SPIKEzSpike brutal (z+.1fz% en 1 bougie)FLASH_CRASHg?u.   Flash crash détecté (chute brutale + rebond)g      $@NORMALu   Données normales)lenr   npisnan_calculate_zscoreabsr(   min_calculate_volume_spiker)   r*   array_calculate_momentumrangeappendr+   fitpredictscore_samples_is_flash_crash)r.   r0   r1   r2   r3   r4   price_zscorevolume_ratiofeatureshistorical_featuresi
predictionanomaly_scoreoutlier_confidenceprice_change_pcts                  r   detect_outlierzOutlierDetector.detect_outlierO   s   & v;s7|b0" *:  88F2J288GBK#8"&1  --f5|t///"&s<043C3CCSI0c0B!D,'  33G<$///"%|d.C.CCSI*<*<IF"  [5Lxxr
(((;(((;" ! H #%3^ 	V$'..q	
#001q0I001q0I0 	 &'2-%%))*=>!22::8DQG
#$($9$9$G$G$QRS$TM),]);& *T1.'+#5'9#S"4   NQQW[\]M]VBZ&*4r
BcIcd 2%"$s#34r93?'(8'>nM*+  '"$G  &
 	
r   valuesc                     t        |      dk  ryt        j                  |dd       }t        j                  |dd       }|dk(  ry|d   |z
  |z  S )u*   Calculer le Z-Score de la dernière valeurrG   r9   Nr:   r   )rL   rM   meanstd)r.   re   rg   rh   s       r   rO   z!OutlierDetector._calculate_zscore   sV    v;?wwvcr{#ffVCR[!!8r
T!S((r   c                 l    t        |      dk  ryt        j                  |dd       }|dk(  ry|d   |z  S )z.Calculer le ratio volume actuel / volume moyenr7   r9   rC   r:   r   )rL   rM   rg   )r.   r2   
avg_volumes      r   rR   z'OutlierDetector._calculate_volume_spike   s>    w<"WWWS_-
?r{Z''r   rA   c                 ^    t        |      |dz   k  ry|d   || dz
     z
  || dz
     z  dz  S )u!   Calculer momentum sur N périodesrD   r9   r:   r#   )rL   )r.   r1   rA   s      r   rT   z#OutlierDetector._calculate_momentum   sD    v;1$fgXaZ00FG8A:4FF#MMr   	thresholdc                     t        |      dk  ryt        dd      D ]X  }|dz   dk\  r||dz      ||   z
  ||   z  dz  }||dz      ||dz      z
  ||dz      z  dz  }||k  sF|t        |      d	z  kD  sX y
 y)um   
        Détecter un flash crash
        Critères: Chute > 5% suivie d'un rebond > 50% de la chute
        rB   Fr:   rG   r   rD   r#         ?T)rL   rU   rP   )r.   r1   rl   r_   drop_pctrecovery_pcts         r   rZ   zOutlierDetector._is_flash_crash   s    
 v;? r2 		A1uz!vay0F1I=DH#AaC[6!A#;6&1+ELL )#s8}s7J(J		 r   lookbackc                 d   t        |      |k  st        |      |k  ry|| d }|| d }t        j                  |d|        }t        |      }|dkD  r||z  nd}	t        |      }
t	        |d|dz         }|
|z
  |z  dz  }|d   }||
z
  |
z  dz  }|	dkD  r|d	kD  r|d
k  rdd|dd|dd|	ddfS y)u   
        Détecter un pump&dump artificiel
        
        Critères:
        - Volume explosif (>5x normal)
        - Price spike >15%
        - Suivi d'une chute rapide
        
        Returns:
            (is_pump_dump, reason)
        )Fu   Données insuffisantesNir   rG   r#   r:         @   iTu   Pump&Dump détecté: +r?   z% puis z% (vol xr=   )FNormal)rL   rM   rg   maxrQ   )r.   r0   r1   r2   rr   recent_pricesrecent_volumesrj   max_recent_volumer\   	max_price	min_priceprice_spikecurrent_price
price_drops                  r   detect_pump_dumpz OutlierDetector.detect_pump_dump  s     v;!S\H%<2yz* (, WWWS(34
/9Ca(:5Q &	lx{34	!I-:cA &b)$y0I=D
 3"1+c1B'*UXIYYabnorasstuuur   )g?g      @rt   )NN)r@   )g      )rE   )r   r   r   r   r   r/   r   r   r   r   rd   rO   rR   intrT   r   rZ   r   r   r   r   r   r	   r	   (   sL    )-,/14Q %Q$)Q */QB /36:E
"E
#E{E
 !%UE
 %UO	E

 %-UOE

 @OE
N)U ) )
(tE{ 
(u 
(N$u+ N NE Nd5k e t 4 *,	*!$*!%e* #'u+* $'	* 16dCi0@	*r   r5   c                  .    t         
t               a t         S )u*   Obtenir l'instance singleton du détecteur)_outlier_detector_instancer	   r   r   r   get_outlier_detectorr   <  s     ")%4%6"%%r   __main__z<============================================================u   🧪 TEST OUTLIER DETECTORu   
1️⃣ Test prix normal:)r#   e         Y@f        `Y@g        Y@h   )  L      r     r   r   TESTUSDT2   ro   )r3   r4   z   Outlier: z   Raison: u   
2️⃣ Test volume spike:)r   r   r   r   r   r   r   '  u      Méthode: u   
3️⃣ Test price spike:)r#   r   r   r   r   r   r      u   
4️⃣ Test pump&dump:)
r#   i   s            n   r   r   r#   )
r     i  r   i.  i@  i  r   i  r   z   Pump&Dump: ))r   numpyrM   typingr   r   r   r   loggingdataclassesr   basicConfigINFO	getLoggerr,   r*   sklearn.ensembler
   r-   ImportErrorwarningr   r	   r   r   r   printdetectornormal_pricesnormal_volumesrd   resultr   r   spike_volumesr   spike_pricespump_pricespump_volumesr   is_pumpr   r   r   <module>r      sk    . .  !   ',, '			,	-  d0
KKCD
   N Nd " &o & z'	&M	
&'	&M#%H 

'(BMDN$$ZTVdg$hF	L**+
,-	K
'( 

()DM$$ZSUcf$gF	L**+
,-	M&--
)*	K
'( 

'(AL$$Z~SUcf$gF	L**+
,-	M&--
)*	K
'( 

%&DKQL//
KVOGV	N7)
$%	Kx
 !M U	  d
NNbcds   G? ?HH