
    i;:                     t    d Z ddlZddlmZmZmZ ddlZ ej                  d      Z	 G d d      Z
dade
fdZy)u   
Risk-Adjusted Scorer - Ajustement des scores par le risque
Intègre des métriques Sharpe-like pour favoriser le meilleur rapport rendement/risque
    N)DictListOptionalRiskAdjustedScorerc            
          e Zd ZdZ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ee   d	edefd
Z	dee   defdZ
d dee   dee   defdZdededededef
dZdedefdZd dedededefdZdededefdZdee   dee   fdZy)!r   uF   Calcule des scores ajustés par le risque (Sharpe-like, Sortino, etc.)c                 X    d| _         d| _        i | _        t        j	                  d       y )N               @u$   ✅ Risk-Adjusted Scorer initialisé)risk_free_ratetarget_sharpevolatility_cacheloggerinfo)selfs    ./risk_adjusted_scorer.py__init__zRiskAdjustedScorer.__init__   s)    !  !#:;    returnsr   returnc                     |rt        |      dk  ryt        j                  |      }t        j                  |      }t        j                  |      }|dk(  ry||z
  |z  }|S )uv  
        Calcule le Sharpe Ratio
        
        Sharpe = (Moyenne des rendements - Taux sans risque) / Écart-type des rendements
        
        Args:
            returns: Liste des rendements (%)
            risk_free_rate: Taux sans risque (défaut: 0%)
            
        Returns:
            Sharpe Ratio (plus élevé = meilleur rapport rendement/risque)
           r	   r   lennparraymeanstd)r   r   r   returns_array
avg_return
std_returnsharpes          r   calculate_sharpe_ratioz)RiskAdjustedScorer.calculate_sharpe_ratio   s]     #g,*)WW]+
VVM*
?~-;r   target_returnc                     |rt        |      dk  ryt        j                  |      }t        j                  |      }|||k     }t        |      dk(  ryt        j                  |      }|dk(  ry||z
  |z  }|S )uc  
        Calcule le Sortino Ratio (comme Sharpe mais ne pénalise que la volatilité baissière)
        
        Sortino = (Moyenne des rendements - Target) / Downside Deviation
        
        Args:
            returns: Liste des rendements (%)
            target_return: Rendement cible
            
        Returns:
            Sortino Ratio
        r   r	   r   g      $@r   )r   r   r#   r   r   downside_returnsdownside_stdsortinos           r   calculate_sortino_ratioz*RiskAdjustedScorer.calculate_sortino_ratio6   s     #g,*)WW]+
 ))FG A%vv./1-=r   max_drawdownc                 f    |r|dk(  ryt        j                  |      }|dz  }|t        |      z  }|S )u   
        Calcule le Calmar Ratio (rendement annualisé / max drawdown)
        
        Args:
            returns: Liste des rendements
            max_drawdown: Drawdown maximum (en %)
            
        Returns:
            Calmar Ratio
        r   r	   im  )r   r   abs)r   r   r)   r   annualized_returncalmars         r   calculate_calmar_ratioz)RiskAdjustedScorer.calculate_calmar_ratioX   s@     ,!+WWW%
 ',"S%66r   pricesc                     |rt        |      dk  ryt        j                  |      }t        j                  j	                  |      }||z
  |z  dz  }t        j
                  |      }|S )z
        Calcule le drawdown maximum
        
        Args:
            prices: Liste de prix
            
        Returns:
            Max drawdown en %
        r   r	   d   )r   r   r   maximum
accumulatemin)r   r/   prices_arraycummax	drawdownsmax_dds         r   calculate_max_drawdownz)RiskAdjustedScorer.calculate_max_drawdowno   sc     Vqxx' &&|4 "F*f4s:	 	"r   Nvolumesc                    |rt        |      dk  r	dddddddS t        j                  |      }t        j                  |      |dd z  dz  }| j	                  |j                               }| j                  |j                               }| j                  |      }t        j                  |      }|dk7  r | j                  |j                         |      nd}	| j                  ||||      }
t        j                  |      }t        |      dkD  r t        ||dkD           t        |      z  dz  nd}t        |      d	k\  rt        j                  |d
      nd}t        |d      t        |d      t        |	d      t        |d      t        |d      t        |d      t        |d      t        |d      t        |
d      | j                  |
      d
}|S )u  
        Analyse complète des métriques de risque
        
        Args:
            prices: Historique de prix
            volumes: Historique de volumes (optionnel)
            
        Returns:
            Dict avec toutes les métriques de risque
        
   r	   2   )sharpe_ratiosortino_ratior)   
volatility
risk_scorerisk_adjusted_scoreNr1   r         r      )
r>   r?   calmar_ratior)   r@   r   win_ratevar_95rA   risk_quality)r   r   r   diffr"   tolistr(   r9   r   r.   _calculate_risk_scorer   
percentileround_classify_risk)r   r/   r:   r5   r   r!   r'   r8   r@   r-   rA   r   rH   rI   metricss                  r   analyze_risk_metricsz'RiskAdjustedScorer.analyze_risk_metrics   s    Vr) #!$ #! ')  xx' '',',s*;;cA ,,W^^-=> ..w~~/?@ ,,V4 VVG_
 KQTU+,,W^^-=vF[\ //T
 WWW%
EH\TUEU3ww{+,s7|;cA[] /2'lb.@w*a "&!,"7A.!&!,!&!,
A.
A.h*FA&
A. //
;
 r   r!   r'   r8   r@   c                 4   |dk\  rd}n|dk\  rd}n|dk\  rd}n
|dk\  rd}nd}|dk\  rd}n|dk\  rd}n
|dk\  rd}nd}|d	kD  rd}n|d
kD  rd}n|dkD  rd}n
|dkD  rd}nd}|dk  rd}n|dk  rd}n
|dk  rd}nd}||z   |z   |z   }	t        dt        d|	            S )z
        Calcule un score de risque composite (0-100)
        
        100 = Excellent (faible risque, bon rendement)
        0 = Terrible (haut risque, mauvais rendement)
           (   r      rF   rD   r   r<   ii   rE         r1   )r4   max)
r   r!   r'   r8   r@   sharpe_pointssortino_points	dd_points
vol_pointstotal_scores
             r   rM   z(RiskAdjustedScorer._calculate_risk_score   s     Q;Mq[Mq[Mq[MM a<N\N\NN C<Ic\Ic\Ic\II >J!^J"_JJ#n4y@:M3A{+,,r   rA   c                 4    |dk\  ry|dk\  ry|dk\  ry|dk\  ryy	)
zClassifie le niveau de risqueP   u   TRÈS FAIBLE<   FAIBLErU   MOYENrD   u   ÉLEVÉu   TRÈS ÉLEVÉ )r   rA   s     r   rP   z!RiskAdjustedScorer._classify_risk  s1    !222"r   
base_scorerisk_metricssymbolc           
         g d}|r||v nd}|j                  dd      }|j                  dd      }|j                  dd      }d}	|d	k\  r|	d
z  }	n&|dk\  r|	dz  }	n|dk\  r|	dz  }	n|dk  r|rdnd}
|	|
z  }	|dk  r|rdnd}
|	|
z  }	n!|dk  r|rdnd}
|	|
z  }	n|dk  r|rdnd}
|	|
z  }	|dk\  r|	dz  }	n
|dk  r|	dz  }	t        dt        d|	            }	||	z  }t        dt        d|            }||z
  }t        |d      t        |	d      t        |d      t        |d      ||j                  dd      | j	                  |	|      dS )ud  
        Ajuste un score de base par les métriques de risque
        
        Args:
            base_score: Score de base (0-100)
            risk_metrics: Métriques de risque (de analyze_risk_metrics)
            symbol: Symbole de la crypto (pour identifier TOP 20)
            
        Returns:
            Dict avec score ajusté et détails
        )BTCUSDTETHUSDTBNBUSDTXRPUSDTADAUSDTDOGEUSDTSOLUSDTDOTUSDT	MATICUSDTLTCUSDTAVAXUSDTLINKUSDTATOMUSDTUNIUSDTXLMUSDTETCUSDTFILUSDTAPTUSDTNEARUSDTARBUSDTFr>   r   rA   r=   r)   g      ?g      @g?r
   g333333?g      ?g?ggig333333ÿrY   rX   gQrc   rV   ffffff?r1   rF   r   rJ   UNKNOWN)rh   risk_multiplieradjusted_scoreabsolute_adjustmentr>   rJ   recommendation)getr\   r4   rO   _get_recommendation)r   rh   ri   rj   TOP_20_SYMBOLSis_top20r!   rA   r8   r   penaltyr   r   s                r   adjust_score_by_riskz'RiskAdjustedScorer.adjust_score_by_risk  s   
 066^+5 !!.!4!%%lB7
!!.!4  S=s"Os]t#Os]s"OaZ'eTGw&O C<&dEGw&Oc\'eTGw&Oc\'eUGw&O s"O"_s"O c3sO#<= $o5QC 89 -z9  
A.$_a8#NA6#()<a#@"(,,^YG"66O
 	
r   r   c                 >    |dk\  r|dk\  ry|dk\  ry|dk\  ry|dk\  ry	y
)u5   Génère une recommandation basée sur les métriquesg333333?r   u>   🔥 Excellent rapport risque/rendement - Opportunité premiumg?u    ✅ Bon rapport risque/rendementg?u   📊 Risque équilibrér   u-   ⚠️ Risque élevé - Prudence recommandéeu#   🚫 Risque très élevé - Éviterrg   )r   r   r!   s      r   r   z&RiskAdjustedScorer._get_recommendationa  s7    c!fkS#5#,#B8r   opportunitiesc                    g }|D ]  }|j                  dd      }|j                  dd      }|j                  dg       }|rt        |      dk  r|j                  |||dd       `| j                  |      }| j	                  ||      }|j                  |||d   |d	   |d
   |d   |d   |d   |d   d	        |j                  d d       |S )u  
        Compare plusieurs opportunités et les classe par risque ajusté
        
        Args:
            opportunities: Liste de dict avec 'symbol', 'score', 'prices'
            
        Returns:
            Liste triée par score ajusté au risque (décroissant)
        rj   r   scorer=   r/   r<   )rj   rh   r   rJ   r   r   r>   r?   r)   rJ   r   )	rj   rh   r   r   r>   r?   r)   rJ   r   c                     | d   S )Nr   rg   )xs    r   <lambda>z:RiskAdjustedScorer.compare_opportunities.<locals>.<lambda>  s    2B0C r   T)keyreverse)r   r   appendrR   r   sort)	r   r   scored_opportunitiesopprj   rh   r/   ri   adjusteds	            r   compare_opportunitiesz(RiskAdjustedScorer.compare_opportunitiesn  s     "  	CWWXy1F"-JWWXr*FS[2-$++$",&0$-	-    44V<L 00\JH '' ("*+;"<#+,=#> ,^ <!-o!> ,^ < ,^ <"*+;"<
) 
+	D 	!!&CT!R##r   )r	   )N)__name__
__module____qualname____doc__r   r   floatr"   r(   r.   r9   r   rR   rM   strrP   r   r   r   rg   r   r   r   r      sD   P<d5k 5 [` 8 tE{  5  [`  Dd5k  SX .T%[ U 4@4; @e @X\ @D6-E 6-E 6-%*6-8=6-BG6-p# #3 #O
u O
D O
RU O
ae O
b95 9% 9C 90$4: 0$$t* 0$r   r   c                  .    t         
t               a t         S )z3Retourne l'instance globale du risk-adjusted scorer)_risk_adjusted_scorerr   rg   r   r   get_risk_adjusted_scorerr     s     $ 2 4  r   )r   numpyr   typingr   r   r   logging	getLoggerr   r   r   r   rg   r   r   <module>r      sM   
  ' ' 			/	0Q$ Q$j  !"4 !r   