
    iMD                         d Z ddlZddlmZmZ ddlmZmZmZm	Z	 ddl
Z
 e
j                  d      Z G d d      Zdad	dZy)
u   
Long-Term Trend Analyzer
========================
Détecte les tendances baissières prolongées (Dead Cat Bounce)
et les faux rebonds dans une chute continue

Cas typique: FET 12/01 - Tendance baissière 6h+ puis rebond temporaire avant rechute
    N)datetime	timedelta)DictListTupleOptionalLongTermTrendc                   t    e Zd ZdZddZddedee   defdZ	dee   defd	Z
d
edeeef   fdZd
edefdZy)LongTermTrendAnalyzeruH   Analyse les tendances sur plusieurs heures pour éviter les faux rebondsNc                 .    || _         i | _        d| _        y )Ni,  )clientcachecache_duration)selfbinance_clients     ./long_term_trend_analyzer.py__init__zLongTermTrendAnalyzer.__init__   s    $
!    symbolcurrent_pricesreturnc           
      	   | d}|| j                   v rF| j                   |   \  }}t        j                         |z
  j                         | j                  k  r|S ddddddddg d	}	 | j
                  s#|rt        |      dk\  r| j                  |      }|S | j
                  j                  |dd	
      }|rt        |      dk  rt        j                  d| d       |S |D cg c]  }t        |d          }	}|D cg c]  }t        |d          }
}|	d   }t        |	      dk\  r|	d   }||z
  |z  d	z  |d<   t        |	      dk\  r|	d   }||z
  |z  d	z  |d<   t        |	      dk\  r|	d   }||z
  |z  d	z  |d<   |d   dk  r!d|d<   |d   j                  d|d   dd       |d   d k  r!d|d<   |d   j                  d!|d   dd       |d   d"k  r!d|d<   |d   j                  d#|d   dd       |d   r|	d$d% }|
d$d% }|d   |d   z
  |d   z  d	z  }t        j                  |      }t        j                  |
d&d%       }|dkD  r||z  nd'}|d(kD  r7|d)k  r2|d*k  r-|d   d+k  r%d|d,<   |d   j                  d-|dd.|d	z  d/d       |d   rd}t        t        |	      d'z
  dd      D ][  }|	|   |	|d'z
     k  r|d'z  }|dkD  r?|d0kD  r:|	|t!        |d1z   t        |	             }t        |      d0k\  r|d   |d   k  r|d'z  }[ n |d2z  d3z  |d4<   d}|d,   r|d5z  }n.|d   r)|d   d6k  r|d7z  }n|d   d+k  r|d5z  }n|d   d k  r|d2z  }|d4   d8kD  r|d2z  }n|d4   dkD  r|d9z  }|d   d)kD  r|d:z  }n|d   d;kD  r|d9z  }t#        dt!        d	|            |d<<   |d,   r"|d<   d5k  rd=|d><   |d   j                  d?       n]|d   r*|d<   d:k  r"d=|d><   |d   j                  d@|d4   ddA       n.|d<   d7k  r!dB|d><   |d   j                  dC|d<    dD       nd|d><   |t        j                         f| j                   |<   |S c c}w c c}w # t$        $ r'}t        j'                  dE| dF|        |cY d%}~S d%}~ww xY w)Gu  
        Analyse la tendance sur 4h, 8h et 12h
        Détecte les "dead cat bounce" (rebonds temporaires dans une chute)
        
        Returns:
            {
                'trend_4h': -2.5,  # % de variation sur 4h
                'trend_8h': -5.2,  # % de variation sur 8h
                'trend_12h': -7.8, # % de variation sur 12h
                'is_prolonged_downtrend': True,  # Baisse continue > 2h
                'is_dead_cat_bounce': True,  # Rebond temporaire dans chute
                'downtrend_duration_hours': 6,  # Durée de la baisse
                'risk_score': 15,  # 0-100 (0=très risqué, 100=sûr)
                'recommendation': 'AVOID',  # AVOID, CAUTION, OK
                'reasons': []
            }
        	_longterm        Fr   2   OK	trend_4htrend_8h	trend_12his_prolonged_downtrendis_dead_cat_bouncedowntrend_duration_hours
risk_scorerecommendationreasons15md   )intervallimitu   ⚠️ u   : Pas assez de données 15min         ir       ir   0   r           Tr!   r&   Baisse continue 4h (.1f%)      zBaisse continue 8h (g      zBaisse continue 12h (Ni   333333?       @g333333?      r"   zDead Cat Bounce: Rebond +u   % avec volume très faible (z.0f         <   r#      g       #      
      g      ?r$   AVOIDr%   uF   ⛔ ÉVITER: Dead Cat Bounce confirmé (rebond faible + volume faible)u+   ⛔ ÉVITER: Tendance baissière sévère (zh)CAUTIONu(   ⚠️ PRUDENCE: Risque modéré (score=)zErreur analyse long terme z: )r   r   nowtotal_secondsr   r   len_analyze_from_prices
get_klinesloggerwarningfloatappendnpmeanrangeminmax	Exceptionerror)r   r   r   	cache_keycached_datacached_timeresult
klines_15mk
prices_15mvolumes_15mcurrent_priceprice_4h_agoprice_8h_agoprice_12h_agorecent_pricesrecent_volumesmomentum_30mavg_volume_recentavg_volume_globalvolume_ratioconsecutive_downinext_candlesr$   es                             r   analyze_long_term_trendz-LongTermTrendAnalyzer.analyze_long_term_trend   si   & hi(	

"'+zz)'<$K,;;=@S@SS"" &+"'()"

e	;;!c.&9R&?!66~FF //c/RJZ2!50MNO/9:!%!+:J:0:;151;;K; 'rNM :"$)#'4|'C|&SWZ%Zz" :"$)#'4|'C|&SWZ%Zz" :"$ *3(5(E'VZ]&]{# j!D(37/0y!((+?z@RSV?WWY)Z[ j!D(37/0y!((+?z@RSV?WWY)Z[ k"T)37/0y!((+@ATUX@YY[)\] ./ *23!,RS!1 "/r!2]15E!EWXIY Y]`` %'GGN$;!$&GGK,=$>!HY\]H]03DDcd  #%,*<PSASX^_iXjmqXq37F/09%,,/HVYHZZv  xD  EH  xH  IL  wM  MO  .P  Q ./#$ s:2Ar: A!!}z!A#6(A-( ,a/AE+5aAaCZ8Q+RL"<0A5,r:J\Z[_:\ 0A 5 0 ( 7G6Kr5Q12 J *+b 
01*%,"$JJ'$."$JJ'$."$J 01A5b 
23a7b 
 j!C'b 

#c)b 
#&q#c:*>#?F<  *+|0Dr0I+2'(y!(()qr01f\6JR6O+2'(y!((+VW]^xWyz}V~  A  *B  C%*+4'(y!((+STZ[gThSiij)kl+/'( &,X\\^$<DJJy!Me ;;f  	LL5fXRsCDM	sJ   '.Q AQ Q #Q8Q >QL8Q 
Q 	RR;RRpricesc           
         ddddddddg d	}|d   }t        |      dk\  r|d	   }||z
  |z  d
z  |d<   t        |      dk\  r|d   }||z
  |z  d
z  |d<   |d   dk  r!d|d<   |d   j                  d|d   dd       t        |      dk\  rB|d   }||z
  |z  d
z  }|dkD  r-|d   dk  r%d|d<   |d   j                  d|dd|d   dd       d}t        t        |      dz
  t        dt        |      dz
        d      D ]"  }	|	dkD  r||	   ||	dz
     k  r|dz  }|dkD  s" n |d kD  r|d!z  dz  |d"<   d}
|d   rd }
d#|d$<   n?|d   r0|d   d%k  rd&}
d#|d$<   n*|d   d'k  rd(}
d)|d$<   n|d   dk  rd*}
d)|d$<   n
|d   d+kD  rd,}
|
|d-<   |S ).u9   Analyse approximative à partir des prix 5min disponiblesr   Fr   r   r   r   r-   r0   r1   r(   r   `   ir   r2   Tr!   r&   r3   r4   r5   r?   ir9   g      r"   zDead Cat Bounce: +z% mais trend 4h %r8   r=   rC   r,   r#   rE   r%   r;   r>   r6   r@   rF   rA   r:   F   r$   )rJ   rP   rS   rU   )r   ro   r[   r`   ra   rb   price_1h_agomomentum_1hrj   rk   r$   s              r   rK   z*LongTermTrendAnalyzer._analyze_from_prices   sz    &+"'()"

 r
 v;"!#;L#0<#?<"OSV!VF: v;"!#;L#0<#?<"OSV!VF: *$/3F+,9$$';F:<Ns;SSU%VW v;"!#;L)L8LHCOK S VJ%7$%>/3+,y!((+=k#=NN^_efp_qru^vvw)xy s6{QAs6{R/?(@"E 	A1uVAaC[0 A% !A%		 b 2BQ2F"1LF-. 
&'J'.F#$,-j!D(
+2'(
#d*
+4'(
#d*
+4'(J#%J)|r   analysisc                 r    |d   dk(  rddj                  |d         fS |d   ry|d   d	k  rdd
|d    dfS y)u   
        Détermine si l'achat doit être bloqué selon l'analyse long terme
        
        Returns:
            (should_block: bool, reason: str)
        r%   rE   Tz | r&   r"   )Tu9   Dead Cat Bounce - Rebond temporaire dans chute prolongéer$   rD   u   Risque trop élevé (score=rG   )F )joinr   rv   s     r   should_block_buyz&LongTermTrendAnalyzer.should_block_buy4  sb     $%0HY$7888()TL!B&6x7M6NaPPPr   c                     |d   dk(  ry|d   ry|d   r|d   dk  ry	|d   d
k  ry|d   dk  ry|d   dk  ry|d   dk  ryy)u   
        Calcule la pénalité à appliquer au score IA selon l'analyse long terme
        
        Returns:
            Pénalité (0-50 points)
        r%   rE   r   r"   (   r!   r   r;   rA   r6   r@   r2   r>   r$      rD   rC   r    rz   s     r   get_score_penaltyz'LongTermTrendAnalyzer.get_score_penaltyF  s     $%0(),-
#d**%,*%, L!B&l#b(r   N)__name__
__module____qualname____doc__r   strr   rO   r   rn   rK   r   boolr{   intr   r   r   r   r   r      sx    R"
Jc J4; JZ^ JXL4; L4 L\ %c	2B $$ 3 r   r   c                 v    t         t        |       a t         S | rt         j                  s| t         _        t         S )uC   Récupère l'instance globale de l'analyseur de tendance long terme)_long_term_analyzerr   r   )r   s    r   get_long_term_analyzerr   h  s:     "3NC  
 3 : :%3"r   r   )r   numpyrQ   r   r   typingr   r   r   r   logging	getLoggerrM   r   r   r   r   r   r   <module>r      sG     ( . . 			?	+P Ph
  r   