
    i?                        d Z ddlZddlZddlZddl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ej"                  j%                  ej"                  j'                  e            Zej"                  j-                  edd      ZdZd	d
ddddddddddddddddddddddddddddd dd!d"d#dd$Zg d%Z G d& d'      Zdad( Zd:d)efd*Zed+k(  r ej@                  ejB                  ,        e"d-        e"d.        e"d-        e       Z# e"d/       ejI                         D ]<  \  Z%Z& e"d0e% d1        e"d2e&d3            e"d4e&d5            e"d6e&d7    d8       >  e"d9       yy);u  
Market Regime Detection Module
==============================
Analyse le marché global (BTC + Top Altcoins) pour détecter le régime actuel
et ajuster automatiquement l'exposition du bot.

Régimes:
- BULL_STRONG: Marché très haussier, exposition maximale
- BULL_WEAK: Marché haussier modéré
- NEUTRAL: Marché latéral
- CORRECTION: Correction en cours, réduire l'exposition
- BEAR: Marché baissier, exposition minimale
    N)datetime	timedelta)DictOptionalTupleListMarketRegimedatazspy_regime_state.jsonzhttps://api.binance.com/api/v3   2   d   g333333?u,   🚀 Marché BULL FORT - Exposition maximale)max_positions	min_scoreposition_size_pcttake_profit_multiplierdescription
   A   U   g      ?u0   📈 Marché BULL MODÉRÉ - Exposition élevée   H   ?uH   ➡️ Marché NEUTRE - Exposition MODÉRÉE (creux-rebonds de qualité)   R   (   g      ?u0   ⚠️ CORRECTION en cours - Exposition MINIMALE?   K   uC   🔄 REPRISE EN COURS - Exposition ACTIVE (opportunités de rebond)            ?u*   🔴 Marché BEAR - Trading quasi-arrêté)BULL_STRONG	BULL_WEAKNEUTRAL
CORRECTIONEARLY_RECOVERYBEAR)ETHUSDTBNBUSDTSOLUSDTXRPUSDTADAUSDTDOGEUSDTAVAXUSDTDOTUSDTLINKUSDT	MATICUSDTLTCUSDTATOMUSDTUNIUSDTETCUSDTXLMUSDTNEARUSDTAPTUSDTFILUSDTARBUSDTOPUSDTAAVEUSDTICPUSDTVETUSDTFTMUSDTALGOUSDTSANDUSDTMANAUSDTAXSUSDTGALAUSDTROSEUSDTc                      e Zd ZdZd%dZd Zd Zd Zd&deded	e	d
e
e   fdZd&deded	e	d
e
e   fdZded
efdZdej"                  de	d
efdZd'dej"                  de	d
efdZd'dej"                  dej"                  dej"                  de	d
ef
dZd
efdZd
efdZd(ded
eeef   fdZd
eeef   fdZd
e	fdZd
e	fdZd
efdZd
efdZd e	d!e	d
eeef   fd"Z d)d#ed
efd$Z!y)*MarketRegimeDetectoruU   
    Détecte le régime de marché actuel en analysant BTC et les top altcoins.
    Nc                 &   || _         d| _        t        | j                     | _        d| _        d| _        d| _        g | _        i | _        d| _	        g | _
        d| _        d| _        d| _        | j                          t        j!                  d       y)	u   
        Initialise le détecteur de régime.
        
        Args:
            binance_client: Client Binance pour récupérer les données
        r#   N   -   r   F        u%   🎯 MarketRegimeDetector initialisé)clientcurrent_regimeREGIME_CONFIGregime_configlast_updateupdate_intervalmax_cache_timeregime_historymarket_data
last_scorescore_history
_fast_mode_fast_mode_until_bear_detected_at_try_load_stateloggerinfoselfbinance_clients     0/home/ubuntu/crypto_trading_bot/market_regime.py__init__zMarketRegimeDetector.__init__e   s     %'*4+>+>?!     #!$ 	;<    c                 d   	 t         j                  j                  t              syt	        t        d      5 }t        j                  |      }ddd       t        j                         j                  dd      z
  }d}||kD  rt        j                  d|dd| d	       y|j                  d
d      }|dv r|| _        t        t        |         | _        |j                  dd      | _        |j                  dd      | _        |j                  dd      | _        t%        j&                         t)        d      z
  | _        t        j-                  d| d|dd       yt        j                  d| d       y# 1 sw Y   -xY w# t.        $ r"}t        j-                  d|        Y d}~yd}~ww xY w)u
  Charge l'état du régime depuis le fichier si récent (< 15 min).
        Permet au bot de reprendre en BEAR après un redémarrage au lieu de defaulter à NEUTRAL.
        Seuls les régimes restrictifs (BEAR/CORRECTION) sont restaurés — NEUTRAL est le défaut.Nrlast_update_tsr   i  u   📦 État régime expiré (.0fs > u   s) — démarrage en NEUTRALrL   r#   )r&   r$   r%   rV   FrW   rJ   rX   r   )secondsu   ♻️ Régime u!    restauré depuis fichier (âge: u   s) — refresh dans ~5su   📦 État régime u$    non restauré (NEUTRAL par défaut)u5   ⚠️ Impossible de charger le régime sauvegardé: )ospathexistsREGIME_STATE_FILEopenjsonloadtimegetrZ   r[   rL   dictrM   rN   rV   rW   rX   r   nowr   rO   warning	Exception)r]   fstateageMAX_AGEsaved_regimees          r_   rY   z$MarketRegimeDetector._try_load_state   s   	X77>>"34'- %		!%))+		*:A >>CGW}:3s)4yPlmn 99%5yALGG&2#%)-*E%F""'))L%"@(-		2Dc(J%).3F)L&#+<<>Ib4I#I >_`cdg_hh   A  B1,?cde'% %(  	XNNRSTRUVWW	XsA   #F F E7AF  B<F F 7F<F 	F/F**F/c                    	 | j                   | j                  | j                  | j                  t	        j                         t        j                         j                         d}t        dz   }t        |d      5 }t        j                  ||d       ddd       t        j                  |t               y# 1 sw Y   $xY w# t        $ r"}t        j!                  d|        Y d}~yd}~ww xY w)u   Persiste l'état du régime sur disque après chaque changement.
        Utilisé pour survivre aux redémarrages sans perdre le contexte BEAR/CORRECTION.)rL   rV   rW   rX   rd   saved_atz.tmpwr   )indentNu5   ⚠️ Impossible de sauvegarder l'état du régime: )rL   rV   rW   rX   ro   r   rr   	isoformatrk   rl   rm   dumprh   replacert   rZ   rs   )r]   rv   tmpru   rz   s        r_   _save_statez MarketRegimeDetector._save_state   s    	X"&"5"5"oo$($9$9%)%;%;"&))+$LLN446E $f,Cc3 .1		%1-.JJs-.. .  	XNNRSTRUVWW	Xs0   A8C :B6"C 6B?;C 	C-C((C-c                     || _         y)u   Définit le client Binance.N)rK   r\   s     r_   
set_clientzMarketRegimeDetector.set_client   s	    $ra   symbolintervallimitreturnc                 >   	 t          d}|||d}t        j                  ||d      }|j                  dk(  r|j	                         S t
        j                  d| d|j                          y# t        $ r%}t
        j                  d	| d|        Y d}~yd}~ww xY w)
u@   Récupère les klines directement depuis l'API publique Binance.z/klinesr   r   r   r   )paramstimeout   zErreur API Binance : Nu   Erreur requête klines )BINANCE_API_URLrequestsrp   status_coderm   rZ   debugrt   )r]   r   r   r   urlr   responserz   s           r_   _get_klines_from_apiz)MarketRegimeDetector._get_klines_from_api   s    	$%W-C $F
  ||CCH##s*}}&26("X=Q=Q<RST 	LL26("QC@A	s   AA. %A. .	B7BBc                 T   | j                   rY	 t        | j                   d      r| j                   j                  |||      }n| j                   j                  |||      }|r|S 	 | j                  |||      S # t        $ r%}t
        j                  d| d|        Y d}~<d}~ww xY w)u>   Récupère les klines pour un symbole (client ou API directe).get_klines_productionr   zErreur client klines r   N)rK   hasattrr   
get_klinesrt   rZ   r   r   )r]   r   r   r   klinesrz   s         r_   _get_klinesz MarketRegimeDetector._get_klines   s     ;;D4;;(?@![[>>fW_gl>mF![[336H\a3bF!M  ((5AA	  D4VHBqcBCCDs   AA9 9	B'B""B'r   c                 @   |rt        |      dk  ri S 	 t        j                  |D cg c]  }t        |d          c}      }t        j                  |D cg c]  }t        |d          c}      }t        j                  |D cg c]  }t        |d          c}      }t        j                  |D cg c]  }t        |d          c}      }| j	                  |d      }| j	                  |d      }t        |      dk\  r| j	                  |d      n|}	| j                  |d	      }
t        |      dk\  r|d
   |d   z
  |d   z  dz  }nd}t        |      dk\  r|d
   |d   z
  |d   z  dz  }nd}t        |      dk\  r|d
   |d   z
  |d   z  dz  }nd}t        |      dk\  r|d
   |d   z
  |d   z  dz  }n|d
   |d   z
  |d   z  dz  }| j                  |||d	      }||d
   z  dz  }t        j                  |dd       }|d
   }|dkD  r||z  nd}||kD  }||	kD  }||k  }||	k  }d}|r|dz  }|r|dz  }|dz  |dz  z   |dz  z   |dz  z   }|dkD  r|dz  }n
|dkD  r|dz  }|r|dz  }|r|dz  }|d
k  r|dz  }n
|dk  r|dz  }|dk  r|dz  }n
|dk  r|dz  }|dk\  rd}n
|d k  rd!}nd"}|d
   }||z
  |z  dz  }||z
  |z  dz  }||||	||||
||||||d#S c c}w c c}w c c}w c c}w # t        $ r$}t        j                  d$|        i cY d}~S d}~ww xY w)%u   
        Calcule les indicateurs techniques à partir des klines.
        
        Returns:
            Dict avec EMA, RSI, momentum, etc.
              r   r      	      r      r   r      i   iN   皙?      ?皙?333333?333333?r    333333ӿ            BULLISHBEARISHr#   )priceema9ema21ema50	ema_trend	ema9_dist
ema21_distrsimomentum_3hmomentum_5hmomentum_12hmomentum_24hatr_pct	vol_ratiozErreur calcul indicateurs: )lennparrayfloat_ema_rsi_atrmeanrt   rZ   error)r]   r   kcloseshighslowsvolumesr   r   r   r   r   r   r   r   atrr   vol_avgvol_currentr   ema9_above_21ema21_above_50ema9_below_21ema21_below_50trend_scoreweighted_trend_momr   r   r   r   rz   s                                  r_   _calculate_indicatorsz*MarketRegimeDetector._calculate_indicators   s    Vr)I|	XXF;quQqT{;<FHH6:aeAaDk:;E88&9QU1Q4[9:DhhV<ad<=G 99VQ'DIIfb)E-0[B->DIIfb)EE ))FB'C 6{a &r
VBZ 76":EL 6{a &r
VBZ 76":EL 6{b !'fSk!9VC[ HCO  6{b !'fSk!9VC[ HCO!'fQi!76!9 DK ))E44CVBZ'3.G gggcdm,G!"+K181g-!I
 !5LM"U]N 5LM"U]N
 Kq q  #."4t9K!LP\_cPc!dhtw{h{!|!A%q #c)s"q q !B&q #d*s" d"q $s" a%	"%	%	 2JE$,$.#5I 5=E1S8J &&(** , ,"& Q <:9<l  	LL6qc:;I	sR   K0 KK0 K!+K0 K&K0 4K+	HK0 K0 0	L9LLLr
   periodc                     t        |      |k  rt        |d         S d|dz   z  }|d   }|dd D ]  }||z
  |z  |z   } t        |      S )zCalcule l'EMA.r   r   r   r   N)r   r   )r]   r
   r   
multiplieremar   s         r_   r   zMarketRegimeDetector._emaa  se    t9vb?"&1*%
1g!"X 	3E3;*,s2C	3Szra   c                 \   t        |      |dz   k  ryt        j                  |      }t        j                  |dkD  |d      }t        j                  |dk  | d      }t        j                  || d       }t        j                  || d       }|dk(  ry||z  }t        ddd|z   z  z
        S )zCalcule le RSI.r   g      I@r   N      Y@r   )r   r   diffwherer   r   )	r]   r
   r   deltasgainslossesavg_gainavg_lossrss	            r_   r   zMarketRegimeDetector._rsil  s    t9vz!!VQ/&1*vgq1775&?+7766'(+,q= SC1r6N+,,ra   r   r   r   c                    t        |      |dz   k  r!t        t        j                  ||z
              S g }t	        dt        |            D ]S  }t        ||   ||   z
  t        ||   ||dz
     z
        t        ||   ||dz
     z
              }|j                  |       U t        t        j                  || d             S )zCalcule l'ATR.r   N)r   r   r   r   rangemaxabsappend)r]   r   r   r   r   tr_listitrs           r_   r   zMarketRegimeDetector._atr~  s    v;!#.//q#f+& 	Aa47"E!Hvac{*+DGfQqSk)*B
 NN2	 RWWWfWX./00ra   c                 
   | j                  ddd      }|sdddS | j                  |      }|sdddS d}|d   dk(  r|d	z  }n|d   d
k(  r|d	z  }|d   }|dk\  r|dz  }nA|dk\  r|dz  }n6|dk\  r|dz  }n+|dk  r|dz  }n |dk  r|dz  }n|dk  r|dz  }n
|dk  r|dz  }|j                  dd      }|j                  dd      }|dk  r|d	z  }n+|dk  r|dz  }n |dk  r|dz  }n|dk  r|dz  }n
|dk\  r|dz  }|dk  r|d	z  }n |dk  r|dz  }n|dk  r|dz  }n
|dk\  r|dz  }|j                  d d      }|dk  r|d	z  }n+|d!k  r|dz  }n |dk  r|dz  }n|dk\  r|dz  }n
|dk\  r|d"z  }|d#   }d$|cxk  rd%k  r	n n|dz  }n_d%|cxk  rd&k  r	n n|dz  }nK|d&kD  r|dz  }n@|dk  r|dk  r|dk  r|d	z  }n+|dz  }n%|d'k  r|dk\  s|dk\  r|dz  }n|dz  }n
|d(k  r|dz  }|d)   dkD  r|dz  }n|d)   dk  r|dz  }d}	d*}
d*}d*}	 | j                  dd+d,      }|rt	        |      d-k\  rt        j                  |D cg c]  }t        |d"          c}      }t	        |      dk\  r|d   |d   z
  |d   z  d.z  nd}
t	        |      d"k\  r|d   |d/   z
  |d/   z  d.z  nd}t	        |      d-k\  r|d   |d0   z
  |d0   z  d.z  nd}| j                  |t        dt	        |                  }| j                  |t        d1t	        |                  }t	        |      dkD  r+| j                  |d2d t        dt	        |      dz
              n|}t	        |      d1kD  r+| j                  |d2d t        d1t	        |      dz
              n|}||k  xr ||kD  }||k\  xr ||k  }|d3k  }|
d4kD  }|xr |}|d5kD  }|
d6k  }|xr |}|r$|	dz  }	t        j                  d7|d8d9|
d8d:       nG|r |	d;z  }	t        j                  d<|
d8d:       n%|
d=kD  r|d4kD  r|	dz  }	n|
d4kD  r|	dz  }	n
|
d*kD  r|	dz  }	|r$|	d>z  }	t        j                  d?|d8d9|
d8d:       n<|r |	d,z  }	t        j                  d@|
d8d:       n|
dk  r|d6k  r|	dz  }	n
|
d6k  r|	dz  }	t        j                  dA|
d8dB|d8dC|d8dD|	dE       ||	z   }t        dt        d.|            |dG<   |	|dH<   t        |
d      |dI<   t        |d      |dJ<   t        |d      |dK<   dL|dM<   |S c c}w # t        $ r"}t        j                  dF|        Y d2}~d2}~ww xY w)Nu   
        Analyse BTC comme baromètre du marché.
        
        Returns:
            Dict avec les indicateurs BTC et un score de sentiment
        BTCUSDT1hr   NO_DATA)sentiment_scorestatus
CALC_ERRORr   r   r   r   r   r   r   r      r   r   r   #   r      r   r   r   r   r   r   r   r      r   r         r   r   7   F   P   rH   r   r   rJ   5mr      r   ir   Ng      пr   r   g333333ÿu4      🔄 FAST SENSOR: Retournement haussier BTC (30m:+.2fu
   % → 10m:%)r   u3      📈 FAST SENSOR: EMA cross UP 5min BTC (mom10m:r      u4      🔄 FAST SENSOR: Retournement baissier BTC (30m:u5      📉 FAST SENSOR: EMA cross DOWN 5min BTC (mom10m:u      ⚡ 5min BTC: mom10m=z	% mom20m=z	% mom30m=z% adj=z+dzFast sensor 5min indisponible: r   fast_signal_adj	mom_10min	mom_20min	mom_30minOKr   )r   r   rp   r   r   r   r   r   r   minrZ   r[   rt   r   r   round)r]   r   
indicatorsscoremomentumr   r   r   r   r  r  r	  r
  	klines_5mr   c5ema5_nowema9_now	ema5_prev	ema9_prevcross_up
cross_downwas_falling
now_risingreversal_up
was_risingnow_fallingreversal_downrz   s                                r_   analyze_btcz MarketRegimeDetector.analyze_btc  s    !!)T26')Y??//7
')\BB  k"i/RKE$	1RKE n-q=RKE]RKE]RKE_RKE^RKE^RKE^RKE !nn]A6 nn]A6 "RKEBRKED QJE1_QJEAQJE "RKEBQJED QJEAQJE
 "~~na82RKET!RKET!QJEQQJEQQJE ??RKE#^^QJE2XQJE2X Q;?
2Xa;!#3

2XQJE k"Q&QJE$r)QJE 			<	@11)T2FIS^q0XXI>quQqT{>? CFb'Q,bfr"voB73>TU	BEb'Q,bfr"voB73>TU	BEb'Q,bfr"voB73>TU	  99Rs1c"g?99Rs1c"g?GJ2wQR{DIIb"gs1c"gk/BCX`	GJ2wQR{DIIb"gs1c"gk/BCX`	 (94O8h;N'94O8h;N
 (%/'$.
)8j ($.
'%/ * :{#r)OKK #''0&6j4@PPR!T U#r)OKK"UV_`dUeeg hi%)d*:#r)O%#q(O_#q(O #r)OKK #''0&6j4@PPR!T U#r)OKK"WXabfWggi jk&9u+<#r)O&#q(O6y6F G%%.t$4Ii=M N##22"68 9 '(+As3(?
$%(7
$%"'	1"5
;"'	1"5
;"'	1"5
;#
8K ?p  	@LL:1#>??	@s+   
8T TIT T 	T=T88T=c                    d}d}d}d}d}d}d}t         D ]  }| j                  |dd      }	|	s| j                  |	      }
|
s-|dz  }||
j                  dd      z  }||
j                  dd      z  }||
j                  dd      z  }||
j                  dd      z  }|
j                  d	      d
k(  r|dz  }|
j                  d	      dk(  s|dz  } |dk(  rdddS ||z  dz  }||z  }||z  }||z  }||z  }d}|dz  |dz  z   |dz  z   |dz  z   }|dk\  r|dz  }nA|dk\  r|dz  }n6|dk\  r|dz  }n+|dk  r|dz  }n |dk  r|dz  }n|dk  r|dz  }n
|dk  r|dz  }|dk\  r|dz  }nm|dk\  r|dz  }nb|dk\  r|dz  }nW|dk\  r|dz  }nL|dk\  r|dz  }nA|dk  r|d z  }n6|d!k  r|d"z  }n+|d#k  r|dz  }n |d$k  r|dz  }n|d%k  r|dz  }n
|d&k  r|dz  }|d$k  r|dz  }n6|d%k  r|d'z  }n+|d(k  r|d)z  }n |d*k\  r|dz  }n|dk\  r|d'z  }n
|d+k\  r|d)z  }|d#k  r|dz  }n6|d,k  r|dz  }n+|d(k  r|dz  }n |dk\  r|dz  }n|dk\  r|dz  }n
|d+k\  r|dz  }|dk  r|dk  r|dz  }n|dkD  r|dkD  r
|d$k  r|dz  }t	        dt        d|            ||||z
  |z
  t        |d      t        |d      t        |d      t        |d      t        |d      t        |d      |d-d.S )/u   
        Analyse les top altcoins pour avoir une vue globale du marché.
        
        Returns:
            Dict avec stats agrégées des altcoins
        r   r   rH   r   r   r   r   r   r   r   r   r   r   altcoin_scorer   r   gffffff?r   r   r   r   r   r   r   r  r   r   r   r   r   r  r   r   r       r   r   r   r   r   r   r   g      ?r    r   r  )r"  bullish_countbearish_countneutral_countavg_momentumavg_momentum_3havg_momentum_5havg_momentum_12hweighted_momentumbullish_pctanalyzedr   )TOP_ALTCOINSr   r   rp   r   r  r  )r]   r$  r%  total_momentumtotal_momentum_3htotal_momentum_5htotal_momentum_12hr-  r   r   r  r,  r'  r(  r)  r*  r  r+  s                     r_   analyze_altcoinsz%MarketRegimeDetector.analyze_altcoinsP  s>    " 	#F%%fdB7F33F;JMHjnn^Q??Nq!AAq!AA*.."CC~~k*i7",	9"%	#( q=%'9==$x/36%0+h6+h6-8  -t3$8NOScfjSjko{  C  pC  D "RKEBRKEBQJEBRKEBRKEBRKE2QJE !RKE!#RKE!#RKE!#RKE#%QJE#%RKE"$RKE"$RKE"$RKE"$RKE$&QJE b RKE"QJE$QJE#RKE!QJE#QJE b RKE$QJE$QJE!RKE!QJE#QJE Q?Q#6RKEq _q%8\B=NRKE !CUO4**%5E!,2$_a8$_a8 %&6 :!&'8!!< a0 
 	
ra   force_updatec                 l   t        j                         }|s| j                  r|| j                  z
  j                         }| j                  xr! t        j
                         | j                  k  }|rdn| j                  }|rdn| j                  }|rt        j                  d| d       ||kD  r t        j                  d|dd| d       d	}na||k  r?t        j                  d
| j                   d|dd       | j                  | j                  fS t        j                  d|dd| d       t        j                  d       | j                         }|j!                  dd      }|j!                  dd      }	|j!                  dd      }
|j!                  dd      }|j!                  dd      }|j!                  dd      }|j!                  dd      }|dz  |dz  z   |
dz  z   |	dz  z   }|dk  rt        j                  d|dd|dd |
dd!       d	| _        t        j
                         d"z   | _        t        j
                         | _        d#}|| _        t%        t&        |         | _        || _        |d$d%d&d|j)                         d'| _        t        j-                  d(| j                  d)    d*       | j/                          | j                  | j                  fS | j1                         }|j!                  d+d      }|j!                  d,d      }|j!                  d-d      }|d.k  rt        j                  d/|dd0|d1d2       d#}|| _        t%        t&        |         | _        || _        ||d$|j)                         d'| _        t        j-                  d(| j                  d)    d3       | j/                          | j                  | j                  fS |dz  |dz  z   |
dz  z   |	dz  z   }|d4k  rBt        j                  d5|dd6       t        j                  d7|dd8|
dd9|	dd2       |d:z  }n|d;k  rHt        j                  d<|dd=       t        j                  d7|dd8|
dd9|	dd2       |d>z  |d?z  z   }nG|d@z  |dAz  z   }t        j                  dB|dd!       t        j                  d7|dd8|
dd9|	dd2       | j2                  |z
  }|dkD  r-t        j                  dC| j2                  d1dD|d1dE|d1dF       nK|| j2                  z
  dkD  r9t        j                  dG| j2                  d1dD|d1dH|| j2                  z
  d1dF       || _        |dk\  xs |d?kD  xr |dkD  }|dIk\  xr |d;k\  }|dJkD  xr |
dKkD  xr |d;kD  xr | j                  dLv xs# |d?kD  xr |dMk  xr |dNk\  xr | j                  dOv }|dPk\  r|r|rdQ}n|dRk\  r|r|rdS}nv|dRk\  r<dT}|st        j                  dU|ddV       nR|sPt        j                  dW|d1d!       n5|dXk\  rdT}n-|r!dY}t        j                  dZ|d[d8|
d[d\       n
|d]k\  rd^}nd#}||t5        |d_      t5        |j!                  d`d      d_      |j!                  d`d      dakD  rdbn|j!                  d`d      d]k  rdcndd|j)                         de| _        || j                  k7  rt        j                  df| j                   dD| dg|d1dF       t        j                  dh| di|dd2       t        j                  dj| dk|d1dl|dd2       | j6                  j9                  | j                  |||j)                         dm       | j6                  dndo | _        n%t        j                  d(| dg|d1dp|ddq|dd!	       || _        t%        t&        |         | _        |j!                  d`d      }|dQk(  }| j                  dr   }|rt        j                  ds|d1dt       n|dukD  rt;        dvt=        |dwz              | j                  dr<   t?        du| j                  dx   dyz         | j                  dx<   t        j                  dz|d1d{| d|| j                  dr    d}| j                  dx           n|d~kD  rt;        dvt=        |d@z              | j                  dr<   t?        du| j                  dx   dyz         | j                  dx<   t        j                  dz|d1d| d|| j                  dr    d}| j                  dx           nf|dPkD  r{t;        dvt=        |dz              | j                  dr<   t?        du| j                  dx   dvz         | j                  dx<   t        j                  dz|d1d| d|| j                  dr           n|dakD  rRt;        dt=        |d>z              | j                  dr<   t        j                  dz|d1d| d|| j                  dr           n|dk  rt;        dvt=        |dwz              | j                  dr<   t?        du| j                  dx   dyz         | j                  dx<   t        j                  dz|d1d| d|| j                  dr    d}| j                  dx           |j!                  dd      }|dv r|dk\  r|dJkD  r|dYk(  rdyndv}|dYk(  rdndy}| j                  dr   } | j                  dx   }!t?        d| |z         | j                  dr<   t;        d|!|z
        | j                  dx<   | j                  r&|d?kD  r!d| _        t        j                  d|dd!       t        j                  d| d|dd|dd|  d|| j                  dr    d|! d|| j                  dx           n|d^k(  r|dk\  r|dkD  r| j                  dr   } | j                  dx   }!t?        d| dvz         | j                  dr<   t;        d|!dz
        | j                  dx<   t        j                  d|dd|dd|  d|| j                  dr    d|! d|| j                  dx           || _        | j/                          t        j                  d| j                  dr           t        j                  d| j                  dx           | j                  | j                  fS )u   
        Détecte le régime de marché actuel.
        
        Args:
            force_update: Force la mise à jour même si l'intervalle n'est pas écoulé
            
        Returns:
            Tuple (regime_name, regime_config)
        r   r   u   ⚡ FAST MODE actif: interval=u   s (marché en chute)u   ⚠️ Cache régime expiré (re   rf   u   s) - Mise à jour forcéeTu   📦 Cache régime valide: u    (âge: zs)u1   🔄 Rafraîchissement régime programmé (âge: u   s ≥ u%   🔍 Analyse du régime de marché...r   r   r   r   r   r   r  r
  r  r   r   r   g      u-   🚨 CRASH BTC détecté! Momentum pondéré=z.2fz% (3h=z% 5h=r  i,  r&   r   CRASH_DETECTEDr!  )btcaltcoinsglobal_score	timestampu   📊 Régime: r   z (score=15) [FAST MODE 5min]r"  r+  r,  g      u(   🚨 CRASH ALTCOINS! Momentum pondéré=z
% Bullish=z.1f%z (score=20)g      u   🚨 BTC EN CHUTE PONDÉRÉE (u   %) - Score altcoins ignoré!u      → Mom3h=z% Mom5h=z	% Mom24h=r   r   u!   ⚠️ BTC en baisse pondérée (u    %) - Pondération BTC augmentéeg?r   g333333?r   u$   ✅ BTC momentum pondéré positif (u   ⚠️ Chute de score: u    → z (-)u   📈 Hausse de score: z (+r   g?r   )r&   r$   gɿr   )r&   r$   r#   r   r!   <   r"   r#   u      → NEUTRAL: BTC momentum=u
   % négatifu*      → NEUTRAL: Altcoins faibles (Bullish=rI   r%   u#   🔄 REPRISE DÉTECTÉE: BTC Mom3h=r  u   % → EARLY_RECOVERYrH   r$   r   r   r   
OVERBOUGHTOVERSOLDNORMAL)r7  r8  r9  btc_rsirsi_warningr:  u   📊 CHANGEMENT: z (score=z   BTC: score=z
 momentum=z   Altcoins: score=z	 bullish=z% momentum=)fromtor  r:  iNz, BTC=z%, Alt=r   u      ✅ BULL_STRONG: RSI u#    — aucune réduction (trend fort)Z   r   r    r   r   u      ⚠️ BTC RSI u    EXTRÊME → max_positions u   →z, min_score=r   u    SURACHETÉ → max_positions g?u    suracheté → max_positions r   u'    suracheté modéré → max_positions r   u    SURVENDU → max_positions )r#   r%   r      r   Fu:      ✅ FAST MODE désactivé: reprise confirmée (mom_10m=z+.3fu      ⚡ BOOST REPRISE (regime=z, fast_adj=z+.0fz
, mom_10m=u   %) → max_pos z, min_score r  D   u,      ⚡ BOOST CORRECTION→REPRISE (fast_adj=u      → Max positions: u      → Score IA min: ) r   rr   rO   total_secondsrV   ro   rW   rP   rQ   rZ   r   rs   rL   rN   r[   r  rp   rX   rq   rM   r   rS   r   r   r3  rT   r  rR   r   r   intr  )"r]   r4  rr   elapsed_fast_mode_activeeffective_intervaleffective_max_cachebtc_data	btc_scorebtc_momentum_24hbtc_momentum_5hbtc_momentum_3hbtc_mom_10minbtc_mom_30minbtc_fast_adjbtc_weighted_crash
new_regimealtcoin_datar"  altcoin_weighted_momentumaltcoin_bullish_pctbtc_weighted_momentumr9  
score_dropbtc_allows_bullaltcoins_allow_bullis_recoveringrA  is_strong_bulloriginal_max	boost_posboost_scorecur_max	cur_scores"                                     r_   detect_regimez"MarketRegimeDetector.detect_regime  sO    lln  0 0T---<<>G "&!XTYY[4CXCX5X'8d>R>R(9"t?R?R =>P=QQefg,,!?}DQdPee~  A#--:4;N;N:OxX_`cWddfgh**D,>,>>>OPWX[}\bcubvvxyz;< ##%LL!2B7	#<<:#<<q9#<<q9#<<Q7#<<Q7#<<(91= T!t#%t#% $& 	 $NNJK]^aJbbhixy|h}  ~C  DS  TW  CX  XZ  [  \"DO$(IIK#$5D!%)YY[D"J",D!%mJ&?!@D"D.0<LM " ]]_	 D LL>$*<*<]*K)LLhij&&(:(::: ,,.$(("=$0$4$45H!$L!*..}bA %t+NNEF_`cEddn  pC  DG  oH  HI  J  KJ",D!%mJ&?!@D"D( " ]]_	 D LL>$*<*<]*K)LKXY&&(:(:::
 T!t#%t#% $& 	 !4'NN;<QRU;VVrstNN]?3*?xX[G\\efvwze{{|}~$s?L"T)NN>?TUX>YYyz{NN]?3*?xX[G\\efvwze{{|}~%O0CDL &O0CDLKK>?TUX>YY[\]KK-'<H_UXDYYbcstwbxxyz{ __|3
?NN4T__S4I|\_N``cdnorcsstuvDOO+b0KK00EU<X[J\\_`loso~o~`~  @C  `D  DE  F  G ' "Q& 7S 5\A%5 	  3b8^=VZ^=^  #% >$&>)D0> ##'==	 # I$I"I ##'HH 	  2/6I&JRO8K$JR"J";<QRU;VV`ab(HI\]`HaacdeR"J *JNN@QU@VV^_nos^t  uI  J  KR%JJ $!,2X\\%4a8+3<<r+BR+G<\d\h\hinpr\svx\xj  G
 ,,,NN.t/B/B.C5T\]ijm\nnopqKK.:>STW=XXYZ[KK-m_IFYZ]E^^i  kD  EH  jI  IJ  K  L &&++ % ]]_	(  #'"5"5cd";DKK.H\#<NfUjknToov  xQ  RU  wV  VX  Y  Z(!-
";<
 ,,ub)$5))/:KK273-?bcdr\25a\C=O9P2QD/.1"d6H6H6UXY6Y.ZD{+NN/}<XYeXffijnj|j|  ~M  kN  jO  O[  \`  \n  \n  oz  \{  [|  }  ~r\25a\C=O9P2QD/.1"d6H6H6UXY6Y.ZD{+NN/}<Z[gZhhklpl~l~  @O  mP  lQ  Q]  ^b  ^p  ^p  q|  ^}  ]~    @r\25a\D=P9Q2RD/.1"d6H6H6UXY6Y.ZD{+NN/}<Z[gZhhklpl~l~  @O  mP  lQ  R  Sr\25a\D=P9Q2RD/KK,WSM9`am`nnqrv  sE  sE  FU  sV  rW  X  Yr\25a\C=O9P2QD/.1"d6H6H6UXY6Y.ZD{+NN/}<XYeXffijnj|j|  ~M  kN  jO  O[  \`  \n  \n  oz  \{  [|  }  ~  ||$5q9 66<1;LQ^aeQe'+;;I *.> >"AK((9G**;7I25b'I:M2ND/.1"i+6M.ND{+=4#7"'XYfgkXllnopKK7
|;|\`Naaklyz~k  @O  PW  OX  X[  \`  \n  \n  o~  \  [@  @L  MV  LW  WZ  [_  [m  [m  ny  [z  Z{  |  }<'LB,>=SWCW((9G**;7I25a12ED/.1"i"n.ED{+KKF|TXFYYcdqrvcw  xG  HO  GP  PS  TX  Tf  Tf  gv  Tw  Sx  xD  EN  DO  OR  SW  Se  Se  fq  Sr  Rs  t  u,T-?-?-P,QRS+D,>,>{,K+LMN""D$6$666ra   c                 2    | j                   | j                  fS )u7   Retourne le régime actuel sans forcer de mise à jour.)rL   rN   r]   s    r_   get_current_regimez'MarketRegimeDetector.get_current_regime  s    ""D$6$666ra   c                      | j                   d   S )u5   Retourne le nombre max de positions selon le régime.r   rN   rh  s    r_   get_max_positionsz&MarketRegimeDetector.get_max_positions  s    !!/22ra   c                      | j                   d   S )u.   Retourne le score IA minimum selon le régime.r   rk  rh  s    r_   get_min_scorez"MarketRegimeDetector.get_min_score  s    !!+..ra   c                 &    | j                   d   dz  S )z1Retourne le multiplicateur de taille de position.r   r   rk  rh  s    r_   get_position_size_multiplierz1MarketRegimeDetector.get_position_size_multiplier  s    !!"56>>ra   c                      | j                   d   S )z*Retourne le multiplicateur de Take Profit.r   rk  rh  s    r_   get_tp_multiplierz&MarketRegimeDetector.get_tp_multiplier  s    !!":;;ra   current_positionssignal_scorec                     | j                          | j                  d   }| j                  d   }||k\  rdd| j                   d| d| dfS ||k  rdd| j                   d| d	| dfS d
d| j                   dfS )u  
        Vérifie si une nouvelle position est autorisée selon le régime.
        
        Args:
            current_positions: Nombre de positions actuelles
            signal_score: Score du signal d'achat
            
        Returns:
            Tuple (allowed, reason)
        r   r   Fu   Régime z: Max positions atteint (/r<  z: Score insuffisant (z < Tu   : Position autorisée)rf  rN   rL   )r]   rs  rt  max_posr   s        r_   should_allow_new_positionz.MarketRegimeDetector.should_allow_new_position  s     	$$_5&&{3	'HT%8%8$99RSdReefgnfoopqqq)#HT%8%8$99N|n\_`i_jjklllx 3 344IJJJra   force_freshc                 :   |r	 | j                  d       | j                  | j
                  | j                  | j                  r| j                  j                         nd| j                  dd dS # t        $ r"}t        j                  d|        Y d}~d}~ww xY w)u  
        Retourne le statut complet pour le dashboard.
        
        Args:
            force_fresh: Si True, force une mise à jour des données avant de retourner le statut
        
        Returns:
            Dict avec toutes les infos du régime
        T)r4  u-   Erreur mise à jour régime dans get_status: Nr   )regimeconfigrS   rO   history)
rf  rt   rZ   rs   rL   rN   rS   rO   r   rR   )r]   ry  rz   s      r_   
get_statuszMarketRegimeDetector.get_status,  s     T"""5
 ))((++;?;K;K4++557QU**340
 	
  T!NqcRSSTs   A/ /	B8BB)N)r   r   )r   )F)T)"__name__
__module____qualname____doc__r`   rY   r   r   strrI  r   r   r   r   r   r   r   ndarrayr   r   r   r   r  r3  boolr   rf  ri  rl  rn  rp  rr  rx  r~   ra   r_   rF   rF   `   s   =6X<X&%3 # S ZbcgZh &B# B BC BQYZ^Q_ B"FD FT FP	 	S 	U 	- -S -% -$1"** 1BJJ 1

 1TW 1af 1 @T @DM
$ M
^^7$ ^75d;K ^7@	7E#t)$4 733 3/s /?e ?<5 <K3 Kc KV[\`be\eVf K2
d 
d 
ra   rF   c                      da y)uB   Réinitialise le singleton (utile pour les tests ou redémarrage).N)_market_regime_instancer  ra   r_   reset_market_regime_detectorr  I  s
     #ra   r   c                     |rda t         t        |       a t         S | r%t         j                  st         j                  |        t         S )u  
    Retourne l'instance singleton du détecteur de régime.
    
    Args:
        binance_client: Client Binance (optionnel, pour initialisation)
        force_new: Force la création d'une nouvelle instance
        
    Returns:
        MarketRegimeDetector instance
    N)r  rF   rK   r   )r^   	force_news     r_   get_market_regime_detectorr  N  sH     "&&"6~"F #" 
 7 > >**>:""ra   __main__)levelz<============================================================zTEST MARKET REGIME DETECTORu   
Configuration des régimes:z  :z    - Max positions: r   z    - Min score: r   z    - Position size: r   r;  u$   
✅ Module prêt à être intégré)NF)'r  rm   loggingrh   ro   r   r   r   typingr   r   r   r   numpyr   	getLoggerrZ   ri   dirnameabspath__file___MODULE_DIRjoinrk   r   rM   r.  rF   r  r  r  r  basicConfigINFOprintdetectoritemsr{  r|  r  ra   r_   <module>r     s     	   ( . . 			>	* ggoobggooh78GGLLf6MN  3  "%E "%I "&a "&I "%\ "%CI+\
c
 c
N  #
#H\ #2 zGgll+	(O	
'(	(O $%H	
)*'--/ F6(!n%f_&=%>?@!&"5!678%f-@&A%B!DE	F 

12# ra   