
    i@h                     n   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
ddlZddlZddlZddlZddlmZ ddlZ ej$                  ej&                          ej(                  d      Z	 ddlmZmZ d	Z	 ddlmZ d	Z	 ddlm Z  d	Z! G d d      Z"da#de"fdZ$e%dk(  r	  e&d        e&d        e&d        e$       Z'e'jQ                         Z) e&d       e)jU                         D ]  \  Z+Z, e&de+ de,          e&d       e'j[                         \  Z.Z/ e&de.         e&de/        e.r+e'ja                         Z1 e&de1je                  d              yyy# e$ r d
Zej7                  d       Y w xY w# e$ r d
Zej7                  d       Y w xY w# e$ r d
Z!ej7                  d       Y .w xY w)u]  
AI Adaptive Retrainer - Réentraînement automatique des modèles GPU
Inspiré de FreqAI - Permet l'adaptation automatique aux changements de marché

Features:
- Retraining périodique (toutes les 24-48h)
- Détection changements de régime marché
- Retraining d'urgence si win rate < 30%
- Sauvegarde automatique des modèles
- Crash resilience
    N)datetime	timedelta)DictListTupleOptional)Path)levelAIAdaptiveRetrainer)get_advanced_scorerAdvancedScorerTF%   ⚠️ Advanced Scorer non disponible)get_opportunity_selector*   ⚠️ Opportunity Selector non disponibleMarketRegimeDetectoru#   ⚠️ Market Regime non disponiblec            	           e Zd ZdZ	 	 	 	 ddedededefdZd Zd Z	d	e
eef   fd
Zdded	ee   fdZd	ee   fdZdded	ee   fdZded	efdZded	eej(                     fdZded	efdZd	eeef   fdZd	efdZd	ee   fdZd	efdZy)AdaptiveRetraineru%  
    Gestionnaire de réentraînement adaptatif des modèles GPU
    
    Stratégies de retraining:
    1. Périodique - Tous les N jours (défaut: 2 jours)
    2. Performance-based - Si win rate < seuil (défaut: 30%)
    3. Regime-change - Si changement majeur de marché (BULL→BEAR)
    retrain_interval_hoursmin_samplesemergency_winrate_threshold
models_dirc                    t        |      | _        || _        || _        t	        |      | _        | j
                  j                  d       d| _        d| _        g | _	        | j                          t        j                  d       t        j                  d| d       t        j                  d|        t        j                  d	|d
z   d       y)u.  
        Args:
            retrain_interval_hours: Intervalle entre retrainings (heures)
            min_samples: Nombre minimum de trades pour retrain
            emergency_winrate_threshold: Win rate minimum avant retraining urgence
            models_dir: Dossier de sauvegarde des modèles
        )hoursT)exist_okNu"   ✅ Adaptive Retrainer initialiséu      • Intervalle: hu      • Min samples: u      • Emergency threshold: d   %)r   retrain_intervalr   emergency_thresholdr	   r   mkdirlast_retrainlast_market_regimeretrain_history_load_stateloggerinfo)selfr   r   r   r   s        8/home/ubuntu/crypto_trading_bot/ai_adaptive_retrainer.py__init__zAdaptiveRetrainer.__init__=   s     !*0F G&#>  z*t, !"&! 	89)*@)ACD*;-8923Ns3R2SSTUV    c                 
   | j                   dz  }|j                         r	 t        |d      5 }t        j                  |      }|j                  d      }|rt        j                  |      nd| _        |j                  d      | _	        |j                  dg       | _
        t        j                  d| j                          ddd       yy# 1 sw Y   yxY w# t        $ r"}t        j                  d|        Y d}~yd}~ww xY w)	u(   Charger l'état précédent du retrainerretrainer_state.jsonrr"   Nlast_regimehistoryu$   📂 État chargé: dernier retrain u    ⚠️ Erreur chargement état: )r   existsopenjsonloadgetr   fromisoformatr"   r#   r$   r&   r'   	Exceptionwarning)r(   
state_filefstatelast_retrain_stres         r)   r%   zAdaptiveRetrainer._load_state^   s    __'==
	G*c* \a IIaLE',yy'@$Td(>(>?O(PjnD%.3ii.FD++099Y+CD(KK"FtGXGXFY Z[\ \ \ \  G!A!EFFGs5   C BCC CC C 	D C==Dc                 x   | j                   dz  }	 | j                  r| j                  j                         nd| j                  | j                  dd d}t        |d      5 }t        j                  ||d       ddd       y# 1 sw Y   yxY w# t        $ r"}t        j                  d|        Y d}~yd}~ww xY w)	u    Sauvegarder l'état du retrainerr-   Ni)r"   r/   r0   w   indentu   ❌ Erreur sauvegarde état: )r   r"   	isoformatr#   r$   r2   r3   dumpr7   r&   error)r(   r9   r;   r:   r=   s        r)   _save_statezAdaptiveRetrainer._save_statem   s    __'==
		>AEARAR 1 1 ; ; =X\#66//5E
 j#& .!		%1-. . . 	>LL8<==	>s6   AB  B9B BB B 	B9B44B9returnc                    | j                   yt        j                         | j                   z
  }|| j                  k\  rdd|j	                         dz  ddfS | j                         }|+|| j                  k  rdd|dz  dd	| j                  dz   d
fS t        rT| j                         }| j                  r8|| j                  k7  r)g d}| j                  |f|v rdd| j                   d| dfS y)u}   
        Déterminer si un retraining est nécessaire
        
        Returns:
            (should_retrain, reason)
        )TINITIAL_TRAINTz
PERIODIC (  .1fu   h écoulées)zEMERGENCY (win rate r   z% < %)))BULL_STRONGBEAR)	BULL_WEAKrN   )rN   rM   )rN   rO   zREGIME_CHANGE (u   →))FNO_RETRAIN_NEEDED)
r"   r   nowr   total_seconds_get_recent_winrater    MARKET_REGIME_AVAILABLE_get_current_market_regimer#   )r(   time_since_lastrecent_winratecurrent_regimemajor_changess        r)   should_retrainz AdaptiveRetrainer.should_retrain{   s    $(",,.4+<+<<d333:o&C&C&Ed&J3%O}]]] 113%.4;S;S*S/s0B3/GtDLdLdehLhKiiklll #!<<>N&&>T=T=T+T! ++^<M?43J3J2K3~N^^_!```)r+   daysc                 <   	 t        d      }|j                         syt        |d      5 }t        j                  |      }ddd       t        j                         t        |      z
  }g }D ]>  }	 t        j                  |j                  dd            }||k\  r|j                  |       @ t        |      dk  ryt        d |D              }	|	t        |      z  S # 1 sw Y   xY w#  Y xY w# t        $ r"}
t        j                  d	|
        Y d}
~
yd}
~
ww xY w)
z)Calculer le win rate des N derniers jourstrade_history.jsonNr.   r\   
entry_time 
   c              3   L   K   | ]  }|j                  d d      dkD  sd  ywpnlr      Nr5   .0ts     r)   	<genexpr>z8AdaptiveRetrainer._get_recent_winrate.<locals>.<genexpr>   s!     GQ155?Q3FqG   $$u   ⚠️ Erreur calcul win rate: )r	   r1   r2   r3   r4   r   rR   r   r6   r5   appendlensumr7   r&   r8   )r(   r\   
trade_filer:   tradescutoffrecent_tradestrader`   winsr=   s              r)   rT   z%AdaptiveRetrainer._get_recent_winrate   s   	23J$$&j#& &!1& \\^iT&::FM !)!7!7		,PR8S!TJ!V+%,,U3	 =!B&G-GGD#m,,,%& &  	NN<QC@A	sQ   C0 C0 C 0C0 1;C),C0 =C0 C&"C0 )C-+C0 0	D9DDc                     	 ddl m}  |       }|j                         \  }}|S # t        $ r"}t        j                  d|        Y d}~yd}~ww xY w)u$   Obtenir le régime de marché actuelr   r   u"   ⚠️ Erreur détection régime: N)market_regimer   get_current_regimer7   r&   r8   )r(   r   detectorregime_r=   s         r)   rV   z,AdaptiveRetrainer._get_current_market_regime   sP    	:+-H 335IFAM 	NN?sCD	s   !$ 	AA

Ac                    	 t         j                  d| d       t        d      }|j                         st         j	                  d       yt        |d      5 }t        j                  |      }ddd       t        j                         t        |      z
  }g }D ]>  }	 t        j                  |j                  dd	            }||k\  r|j                  |       @ t        |      | j                  k  r/t         j	                  d
t        |       d| j                          yt         j                  dt        |       d       i }	|D ]3  }|j                  d      }
|
s|
|	vrg |	|
<   |	|
   j                  |       5 i }|D ]g  }|j                  dd      }||vr	dddd||<   ||   dxx   dz  cc<   |j                  dd      dkD  r||   dxx   dz  cc<   X||   dxx   dz  cc<   i |j!                         D ]  \  }}|d   dkD  s|d   |d   z  |d<    ||	|t        |      |dS # 1 sw Y   xY w#  Y xY w# t"        $ r"}t         j%                  d|        Y d}~yd}~ww xY w)u   
        Charger les données d'entraînement des N derniers jours
        
        Returns:
            {
                'trades': [...],
                'prices': {...},
                'patterns': {...}
            }
        u#   📥 Chargement données training (z
 jours)...r^   u%   ⚠️ trade_history.json introuvableNr.   r_   r`   ra   u   ⚠️ Pas assez de trades: z < u   ✅ u    trades chargéssymbolpatternUNKNOWNr   )ru   lossestotalr   rf   re   ru   r   win_rate)rq   trades_by_symbolpatterns_statstotal_tradesperiod_daysu    ❌ Erreur chargement données: )r&   r'   r	   r1   r8   r2   r3   r4   r   rR   r   r6   r5   rm   rn   r   itemsr7   rE   )r(   r\   rp   r:   
all_tradesrr   rs   rt   r`   r   r}   r   r~   statsr=   s                  r)   load_training_dataz$AdaptiveRetrainer.load_training_data   s   B	KK=dV:NO 23J$$&FGj#& *!!YYq\
* \\^iT&::FM# !)!7!7		,PR8S!TJ!V+%,,U3	 =!D$4$44!=c->P=QQTUYUeUeTfghKK$s=122BCD  "& ;8,%5535(0$V,33E:;  N& 	;))Iy9.078APQ.RN7+w'0A5099UA&*"7+F3q83"7+H5:5	; #1"6"6"8 G>A%(-fg(FE*%G
 ($4"0 #M 2# _* *V  	LL;A3?@	sb   A	I I H-.0I ;H:AI #<I  B+I  I -H72I :H?<I 	I-I((I-training_datac                     t         st        j                  d       y	 t        j                  d       t	               }g }g }|d   D ]O  }| j                  |      }||j                  |       |j                  |j                  dd      dkD  rdnd       Q t        |      d	k  rt        j                  d
       yt        j                  |      }t        j                  |      }t        j                  d|j                          t        j                  dt        |       dt        |       dt        |      t        |      z  dz  dd       |j                  di       }t        |d      ry|j                         D ]f  \  }}	|	j                  dd      }
|	j                  dd      }|dk\  s0d|
z   }||j                  |<   t        j                  d| d|
dz  dd|d       h | j                   dz  }t#        |d      5 }t%        j&                  |j                         D ci c]'  \  }}|i |dt)        |j                  dd            i) c}}t        |      t)        t        |      t        |      z        t+        j,                         j/                         d|d !       ddd       | j                   d"t+        j,                         j1                  d#       d$z  }t#        |d%      5 }t3        j&                  ||       ddd       t        j                  d&|j4                          y'c c}}w # 1 sw Y   xY w# 1 sw Y   >xY w# t6        $ r"}t        j9                  d(|        Y d}~yd}~ww xY w))u8   Réentraîner le Advanced Scorer avec nouvelles donnéesr   Fu"   🔄 Retraining Advanced Scorer...rq   Nre   r   rf   2   u*   ⚠️ Pas assez de features pour trainingu      • Features shape: u      • Labels positifs: /z (r   rK   rL   r   pattern_weightsr         ?r      u	        • z: WR=z.0fu   % → weight=z.2fzscorer_performance.jsonr?   )patternstotal_featurespositive_rate
updated_atr@   rA   advanced_scorer_z%Y%m%d_%H%M%Sz.pklwbu-   ✅ Advanced Scorer retrained - sauvegardé: Tu   ❌ Erreur retraining scorer: )ADVANCED_SCORER_AVAILABLEr&   r8   r'   r   _extract_trade_featuresrm   r5   rn   nparrayshapero   hasattrr   r   r   r2   r3   rD   floatr   rR   rC   strftimepicklenamer7   rE   )r(   r   scorerfeatureslabelsrt   feature_vectorr   r~   r   wrr   weight	perf_pathr:   ps
model_pathr=   s                      r)   retrain_advanced_scorerz)AdaptiveRetrainer.retrain_advanced_scorer  s>   (NNBC<	KK<=(*F HF&x0 G!%!=!=e!D!-OON3MMuyy':Q'>!AFG 8}r!KLxx)HXXf%FKK1(..1ABCKK23v;-qVRPSTZP[\_`f\gPghkPkloOpprst +../?DNv01&4&:&:&< eNGU:s3B!IIgq1Ez!$r:@..w7iybfS\W]^aVb$cde *CCIi%  		-;-A-A-C!E%)Q "#$Rq$R*eAEE*a<P6Q$R!R !E&)(m%*3v;s6{+B%C"*,,.":":"< Q   -=hlln>U>UVe>f=ggk+llJj$' '1FA&' KKG
GXYZ!E   ' '  	LL9!=>	sp   >M AM <C3M 0AM #L:',L4AL:*AM 2M	*M 4L::M?M MM 	M=M88M=rt   c                 J   	 |j                  dd      }|j                  dd      }|j                  dd      }|dk(  r|dkD  r||z
  |z  dz  }|j                  dd      }g d}|D cg c]  }||k(  rd	nd
 }}|dkD  r|dz  n|dz  |dz  t        |j                  dd      d      dz  |j                  dd      dz  |j                  dd      dz  t        |j                  d|j                  di       j                  dd                  t        |j                  d|j                  di       j                  dd                  dz  g|z   }	t        j                  |	t        j
                        S c c}w # t        $ r"}
t        j                  d|
        Y d}
~
yd}
~
ww xY w)z*Extraire features d'un trade pour trainingentry_pricer   
exit_pricepnl_pctr   r~   r   )CREUX_REBOUNDSQUEEZE_BREAKOUTEARLY_BREAKOUTPULLBACKCROSSOVER_IMMINENTIMMEDIATE_DIPRSI_REVERSALBB_BREAKOUTg      ?g        i  i'  rb   	hold_timei  ai_scorer   volatility_scoreema_trend_bearishr   momentum_20r   )dtypezErreur extraction features: N)	r5   minr   r   r   float32r7   r&   debug)r(   rt   r   r   r   r~   patterns_listr   pattern_encodedr   r=   s              r)   r   z)AdaptiveRetrainer._extract_trade_features\  s   	))M15K<3Jii	1-G!|a%3{BSH ii	95G:M FSSgls;SOS (3T'9e#{S?P"EIIk1-t4t;		*b)C/		,b1C7eii 3UYYz25N5R5RSfhi5jkleiiuyyR/H/L/L]\]/^_`cdd	  	 H 88HBJJ77 T  	LL7s;<	s+   A%E7 'E27C:E7 2E7 7	F" FF"c                    t         st        j                  d       y	 t        j                  d       t	               }|d   }|j                         D cg c]$  \  }}|j                  dd      dkD  r
|d   d	k\  r|& }}}t        j                  d
|        i }|d   j                         D ]E  \  }}	t        |	      dk\  st        d |	D              }
|
t        |	      z  }t        |	      |d||<   G t        |j                         d d      dd }t        j                  d|D cg c]  }|d   	 c}        | j                  dz  }t        |d      5 }t        j                  ||t        j                         j!                         d|d       ddd       t        j                  d       yc c}}w c c}w # 1 sw Y   *xY w# t"        $ r"}t        j%                  d|        Y d}~yd}~ww xY w)u$   Réentraîner l'Opportunity Selectorr   Fu'   🔄 Retraining Opportunity Selector...r   r   r   r   r   r   u      • Patterns gagnants: r      c              3   L   K   | ]  }|j                  d d      dkD  sd  ywrd   rg   rh   s     r)   rk   zAAdaptiveRetrainer.retrain_opportunity_selector.<locals>.<genexpr>  s!     HQAEE%Oa4GqHrl   )rq   r   c                     | d   d   S )Nrf   r    )xs    r)   <lambda>z@AdaptiveRetrainer.retrain_opportunity_selector.<locals>.<lambda>  s    ad:. r+   T)keyreverseNrb   u      • Top 10 cryptos: zopportunity_stats.jsonr?   )r   symbolsr   r@   rA   u"   ✅ Opportunity Selector retrainedu    ❌ Erreur retraining selector: )OPPORTUNITY_SELECTOR_AVAILABLEr&   r8   r'   r   r   r5   rn   ro   sortedr   r2   r3   rD   r   rR   rC   r7   rE   )r(   r   selectorr   r   r   winning_patternssymbol_statsr}   rq   ru   r   top_symbolsr   
stats_pathr:   r=   s                    r)   retrain_opportunity_selectorz.AdaptiveRetrainer.retrain_opportunity_selector}  s    -NNGH1	KKAB/1H ++;<N #1"6"6"8 a99Z+d2uW~7J    
 KK45E4FGH L"/0B"C"I"I"K v;!#H&HHD#c&k1H"%f+$,,L(	 !""$. r	K KK12MA1Q42M1NOP +CCJj#&  !		 .+"*,,.":":"< Q	   KK<=I 0 3N     	LL;A3?@	sU   7G )F5>AG A'G *F;
6$G =G G 5G  G	G 	G7G22G7c                 \   t         j                  d       t         j                  d       t         j                  d       t        j                         }| j	                  d      }|t         j                  d       dd	d
S t         j                  d       t         j                  d|d    d       t         j                  d|d           t         j                  dt        |d                 t         j                  dt        |d                 t        d |d   D              }|d   dkD  r||d   z  nd}t         j                  d|dz  dd       i }| j                  |      |d<   | j                  |      |d<   |dk  r1t         j                  d|dz  dd        | j                         |d!<   n"d|d!<   t         j                  d"|dz  dd#       t        j                         | _        t        r| j                         | _        | j                  j!                  | j                  j#                         |d   || j                  |d$       | j%                          t        j                         |z
  j'                         }t        d% |j)                         D              }t         j                  d       t         j                  d&       t         j                  d       t         j                  d'|dd(       t         j                  d)| d*t        |       d+       t         j                  d,| j                  | j*                  z   j-                  d-              t/        |j)                               rd.nd/||| j                  | j*                  z   j#                         d0S )1uz   
        Réentraîner tous les modèles
        
        Returns:
            Dict avec status de chaque modèle
        z=
============================================================u    🔄 RETRAINING ADAPTATIF LANCÉ<============================================================   r_   Nu;   ❌ Impossible de charger les données - retraining annuléFAILEDNO_DATA)statusreasonu   
📊 Données training:u      • Période: r   z joursu      • Trades: r   u      • Symboles: r   u      • Patterns: r   c              3   L   K   | ]  }|j                  d d      dkD  sd  ywrd   rg   rh   s     r)   rk   z0AdaptiveRetrainer.retrain_all.<locals>.<genexpr>  s"     SqquuUAQR?RSrl   rq   r   u      • Win rate global: r   rK   r   advanced_scoreropportunity_selectorg?u   
🚨 Win rate u!   % < 40% → relance LSTM training
lstm_modelu      ℹ️  LSTM: win rate OK (z%), pas de retrain)	timestamptrades_countr   rz   resultsc              3   &   K   | ]	  }|sd   yw)rf   Nr   )ri   vs     r)   rk   z0AdaptiveRetrainer.retrain_all.<locals>.<genexpr>  s     =!1A=s   u   ✅ RETRAINING TERMINÉu   Durée: r   u
   Modèles: r   u	    réussisu   Prochain retrain prévu: z%Y-%m-%d %H:%MSUCCESSPARTIAL)r   r   durationnext_retrain)r&   r'   r   rR   r   rE   rn   ro   r   r   retrain_lstm_modelr"   rU   rV   r#   r$   rm   rC   rF   rS   valuesr   r   all)r(   
start_timer   
total_winsglobal_winrater   r   success_counts           r)   retrain_allzAdaptiveRetrainer.retrain_all  sO    	M"67F\\^
 //R/8 LLVW&)<< 	/1'm(D'EVLMomN&C%DEF'M:L,M(N'OPQ'M:J,K(L'MNO SM($;SS
GTUcGdghGhmN&CCno.~c/A#.FaHI %)%A%A-%P!"*.*K*KM*Z&' D KK*>#+=c*BBcde$($;$;$=GL!$(GL!KK89KC8PPbcd %LLN"&*&E&E&GD# 	##**446).9&--%
 	 	 LLNZ/>>@=w~~'7==M"-.FhxnA./jqWiHI/1B1BTEZEZ1Z0d0deu0v/wxy $'w~~'7#8ii !..1F1FFQQS	
 	
r+   c                    	 t         j                  d       t        t              j                  }t
        j                  dk(  r|dz  dz  dz  }n|dz  dz  dz  }|dz  }|j                         st         j                  d	|        y
|j                         st         j                  d|        y
t        |      dt        |      ddg}t        j                  j                         }d|d<   d|d<   d}t
        j                  dk(  rt        j                  }t        j                  |t        |      ddddd||	      }|j                   dk(  xs  d|j"                  xs dj%                         v }|rVt         j                  d       	 ddlm}	  |	       }
t+        |
d      r%|
j-                          t         j                  d       |S |j2                  xs d}t         j                  d |dd!         |S # t.        $ r#}t         j1                  d|        Y d}~|S d}~ww xY w# t        j4                  $ r t         j                  d"       Y y
t.        $ r"}t         j                  d#|        Y d}~y
d}~ww xY w)$uE   Relance l'entraînement complet du modèle LSTM via train_ai_model.pyu1   🔄 Retraining LSTM model (train_ai_model.py)...win32z.venvScriptsz
python.exebinpython3ztrain_ai_model.pyu   ❌ Python venv non trouvé: Fu!   ❌ Script training non trouvé: z-uz--epochs50zutf-8PYTHONIOENCODING1
PYTHONUTF8r   Ti   replace)cwdcapture_outputtexttimeoutencodingerrorsenvcreationflagsu   terminéra   u%   ✅ LSTM model retrained successfully)get_ai_predictor
load_modelu'   ✅ Modèle rechargé dans ai_predictoru+   ⚠️ Impossible de recharger le modèle: Nu   ❌ LSTM training failed: i,  u   ⏰ LSTM training timeout (2h)u   ❌ Erreur LSTM retraining: )r&   r'   r	   __file__parentsysplatformr1   rE   strosenvironcopy
subprocessCREATE_NO_WINDOWrun
returncodestdoutlowerai_predictorr  r   r  r7   r8   stderrTimeoutExpired)r(   
script_dirvenv_pythontrain_scriptcmdr  creation_flagsresultsuccessr  	predictorr=   r  s                r)   r   z$AdaptiveRetrainer.retrain_lstm_model  sT   A	KKKLh..J||w&(72Y>M(72U:YF%(;;L%%'<[MJK&&(@OP{#T3|+<j$OC**//#C&-C"# #CN||w&!+!<!<^^
O#  ,
F ''1,[
v}}?RPR>Y>Y>[0[GCDV= 0 2Iy,7!,,.$MN N  ,"9&#,HIN ! VNN%PQRPS#TUU
 NV (( 	LL9: 	LL7s;<	s[   BH# (H# 1CH# >G4 H# ,H# 4	H =HH# H  H# #(I7I7I22I7c                     | j                         \  }}|st        j                  d|        yt        j                  d|        | j                         S )u   
        Vérifier si retraining nécessaire et l'exécuter si oui
        
        Returns:
            Résultats du retraining ou None si pas nécessaire
        u$   ℹ️  Retraining non nécessaire: Nu   🚨 Retraining déclenché: )r[   r&   r'   r   )r(   should_trainr   s      r)   check_and_retrainz#AdaptiveRetrainer.check_and_retrainJ  sT      $224fKK>vhGH3F8<=!!r+   c           	         | j                         \  }}d}| j                  r2t        j                         | j                  z
  j	                         dz  }| j                  r| j                  j                         nd|||| j                  | j                         t        | j                        | j                  r)| j                  | j                  z   j                         dS ddS )z%Obtenir le status actuel du retrainerNrJ   )r"   time_since_last_hoursr[   r   rY   rX   history_countnext_retrain_expected)r[   r"   r   rR   rS   rC   r#   rT   rn   r$   r   )r(   r   r   rW   s       r)   
get_statuszAdaptiveRetrainer.get_statusZ  s    #224f'||~0A0AAPPRUYYO >B=N=ND--779TX%4*"55"668 !5!56`d`q`qd&7&7$:O:O&O%Z%Z%\	
 		
 x|	
 		
r+   N)0   r   g333333?trained_models)   )r   )__name__
__module____qualname____doc__intr   r
  r*   r%   rF   r   boolr[   r   rT   rV   r   r   r   r   ndarrayr   r   r   r   r!  r&  r   r+   r)   r   r   3   s1    02$'6:#3	W),W!W /4W !	WBG>"*dCi 0 "*H HUO >	HSM 	Ms MHTN M^BT Bd BHT hrzz6J B7$ 74 7rM
T#t)_ M
^CD CJ"8D> " 
D 
r+   r   rG   c                  .    t         
t               a t         S )z)Obtenir l'instance singleton du retrainer)_retrainer_instancer   r   r+   r)   get_adaptive_retrainerr3  q  s     "/1r+   __main__r   u   🧪 TEST ADAPTIVE RETRAINERu   
📊 Status actuel:u      • z: u   
🔄 Test retraining...zShould retrain: zReason: u   
✅ Résultat: r   )3r-  numpyr   r   r   typingr   r   r   r   r3   r  r  r  loggingpathlibr	   r   basicConfigINFO	getLoggerr&   ai_advanced_scorerr   r   r   ImportErrorr8   ai_opportunity_selectorr   r   rw   r   rU   r   r2  r3  r*  print	retrainerr&  r   r   r   valuer[   r   r   r   r  r5   r   r+   r)   <module>rB     s  
  ( . .  	 
       ',, '			0	1<F $
A@%)"
:2"x
 x
x   1  z	&M	
()	&M&(I !!#F	
!"lln (
UuBug&'( 

%&$335L&	\N
+,	HVH
&&(!&**X"6!789 ) s  < %
NN:;<  A%*"
NN?@A  :#
NN89:s6   )
E 4E9 =F E65E69FFF43F4