
    iW              	          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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 ddlmZmZ  ee      j$                  Zej(                  dk(  redz  dz  d	z  Znedz  d
z  dz  Zedz  Zedz  Zedz  ZdddddZedz  edz  edz  dZddlZ ej8                  ej:                  j<                  dd      e_         ej8                  ej>                  j<                  dd      e_         ej@                  ejB                  dd ejD                  ed       ejF                  ej:                        g        ejH                  d      Z% G d  d!      Z&d"e'fd#Z(d$ Z)d% Z*e+d&k(  r e*        yy)'u  
🔄 Service de Mise à Jour Automatique
======================================
Ce service s'exécute en arrière-plan et maintient automatiquement :
1. Les données historiques à jour (toutes les 6 heures)
2. Le modèle IA entraîné avec les dernières données (toutes les 24 heures)
3. La watchlist synchronisée

Usage:
    python auto_updater_service.py              # Mode normal
    python auto_updater_service.py --once       # Exécuter une seule fois
    python auto_updater_service.py --daemon     # Mode démon (arrière-plan)
    N)datetime	timedelta)Path)DictOptionalwin32z.venvScriptsz
python.exebinpython3zauto_updater_status.jsonzauto_updater.pidzauto_updater.logi`T  iQ   i@8  )historical_dataai_training
quick_syncadaptive_retrainzfetch_historical_data.pyztrain_ai_model.pyzhistorical_data_updater.py)fetch_historicaltrain_aihistorical_updaterutf-8replace)encodingerrorsz)%(asctime)s | %(levelname)s | %(message)sz%Y-%m-%d %H:%M:%S)r   )levelformatdatefmthandlersAutoUpdaterc                       e Zd ZdZd ZdefdZd Zddede	d	e
d
ede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fdZd Zd ZdefdZde	dedee	   fdZy)AutoUpdaterService#   Service de mise à jour automatiquec                     d| _         | j                         | _        t        j                         | _        t        j                         s2t        j                  dt                t        j                  d       y y )NFu   ❌ Python venv non trouvé:    )running_load_statusstatus	threadingLocklockVENV_PYTHONexistsloggererrorsysexitselfs    ./auto_updater_service.py__init__zAutoUpdaterService.__init__W   sY    '')NN$	 !!#LL8FGHHQK $    returnc                     dddddg dd}t         j                         rB	 t        t         d      5 }t        j                  |      }ddd       |j                         |S |S # 1 sw Y   xY w#  Y |S xY w)u?   Charge le statut précédent avec valeurs par défaut garantiesNr   )last_historical_updatelast_ai_traininglast_quick_synctotal_updatestotal_trainingsr   
started_atr)STATUS_FILEr)   openjsonloadupdate)r/   defaultsfsaveds       r0   r#   zAutoUpdaterService._load_statusa   s    
 '+ $# 
 +s+ )q IIaLE) & x) )s"   A/ A#A/ #A,(A/ /A4c                     | j                   5  t        t        d      5 }t        j                  | j
                  |dt               ddd       ddd       y# 1 sw Y   xY w# 1 sw Y   yxY w)zSauvegarde le statutw   )indentdefaultN)r'   r=   r<   r>   dumpr$   str)r/   rB   s     r0   _save_statuszAutoUpdaterService._save_statusz   sc    YY 	Ak3' A1		$++qC@A	A 	AA A	A 	As"   A#(AA#A 	A##A,Nscript_pathdescriptionargstimeoutc                 H   |j                         st        j                  d|        yt        t              dt        |      g}|r|j                  |       t        j                  d|        t        j                  ddj                  |              	 t        j                         }t        j                  j                         }d|d<   d	|d
<   d	|d<   d	|d<   d}t        j                  dk(  rt        j                  }t        j                   |t        t"              dd|dd||	      }	t        j                         |z
  }
g d}|	j$                  xs dj'                         |	j(                  dk(  xs t+        fd|D              }|rt        j                  d| d|
dd       yt        j                  d| d|	j(                   d|
dd       |	j,                  xs dg d}t+        fd|D              xr dv}|rt        j                  d       yr|st        j/                  d d!d"         | j0                  d#   j3                  t5        j6                         j9                         t        |j:                        rd!d$ nd%d&       | j0                  d#   d'd! | j0                  d#<   y# t        j<                  $ r)}t        j/                  d(| d)|d*z   d+       Y d!}~yd!}~wt>        $ r%}t        j/                  d,| d-|        Y d!}~yd!}~ww xY w).u   Exécute un script Pythonu   ⚠️ Script non trouvé: Fz-uu   🔄 Exécution: z   Commande:  r   PYTHONIOENCODING1
PYTHONUTF8PYTHONUNBUFFERED FOR_DISABLE_CONSOLE_CTRL_HANDLERr   r   Tr   )cwdcapture_outputtextrO   r   r   envcreationflags)u   terminé	completedsuccessu   sauvegardérC    c              3   &   K   | ]  }|v  
 y wN ).0pstdout_lowers     r0   	<genexpr>z1AutoUpdaterService._run_script.<locals>.<genexpr>   s     6cQqL7H6c   u   ✅ u    terminé en z.1fsu   ⚠️ u    terminé avec code z en )UserWarningFutureWarningDeprecationWarningc              3   &   K   | ]  }|v  
 y wr`   ra   )rb   rc   stderrs     r0   re   z1AutoUpdaterService._run_script.<locals>.<genexpr>   s     %Kaa6k%Krf   Erroru      (Warnings ignorés)z   Erreur: N,  r      Unknown)timescriptr+   iu   ⏰ u    timeout après <   minu   ❌ Erreur : ) r)   r*   warningrJ   r(   extendinfojoinrq   osenvironcopyr,   platform
subprocessCREATE_NO_WINDOWrun
SCRIPT_DIRstdoutlower
returncodeanyrl   r+   r$   appendr   now	isoformatnameTimeoutExpired	Exception)r/   rL   rM   rN   rO   cmd
start_timerZ   creation_flagsresultelapsedsuccess_patterns
is_successignore_patternsis_just_warningerl   rd   s                   @@r0   _run_scriptzAutoUpdaterService._run_script   s   !!#NN8FG;s;'78JJt'}56mCHHSM?34G	J **//#C&-C"# #C&)C"#69C23 N||w&!+!<!<^^
O#  ,
F iikJ.G  \"MM/R668L
  **a/c36cRb6c3cJd;-}WSMKL5I&J[J[I\\`ahil`mmnop," #Y"%%K?%K"K"ePW_ePe"KK 89/LL;vds|n!=>H%,,$LLN446!+"2"23-3VDS\.  )-H(=cd(CH%(( 	LL4},<Wb[MMN 	LL;{m2aS9:	s3   DJ9 .A/J9 BJ9 9L!K00L!<LL!c                 f   t         j                  d       t         j                  d       t         j                  d       | j                  t        d   d      }|rVt	        j
                         j                         | j                  d<   | j                  dxx   dz  cc<   | j                          |S )u/   Met à jour les données historiques complètes<============================================================u*   📊 MISE À JOUR DES DONNÉES HISTORIQUESr   u%   Téléchargement données historiquesr5   r8   r!   	r*   rx   r   SCRIPTSr   r   r   r$   rK   r/   r]   s     r0   update_historical_dataz)AutoUpdaterService.update_historical_data   s    H@AH""&'3

 4<LLN4L4L4NDKK01KK(A-(r2   c                 z   t         j                  d       t         j                  d       t        d   j                         r| j	                  t        d   ddg      }n| j	                  t        d   ddd	g      }|r?t        j                         j                         | j                  d
<   | j                          |S )u-   Synchronisation rapide des données récentes(----------------------------------------u   ⚡ Synchronisation rapider   u   Sync incrémentale--oncer   zSync rapidez--daysrS   r7   )
r*   rx   r   r)   r   r   r   r   r$   rK   r   s     r0   r   zAutoUpdaterService.quick_sync   s    H01 '(//1&&,-$
G &&*+3G -5\\^-E-E-GDKK)*r2   c                 p   t         j                  d       t         j                  d       t         j                  d       | j                  t        d   dddgd      }|rVt	        j
                         j                         | j                  d	<   | j                  d
xx   dz  cc<   | j                          |S )u3   Entraîne le modèle IA avec les nouvelles donnéesr   u    🧠 ENTRAÎNEMENT DU MODÈLE IAr   u   Entraînement IAz--epochs50i   )rO   r6   r9   r!   r   r   s     r0   train_ai_modelz!AutoUpdaterService.train_ai_model  s    H67H""J	 # 
 .6lln.F.F.HDKK*+KK)*a/*r2   c                    t         j                  d       t         j                  d       	 ddlm}  |       }|j	                         \  }}|sgt         j                  d|        t        j                         j                         | j                  d<   || j                  d<   | j                          yt         j                  d	|        |j                         }|j                  d
d      }t         j                  d|        t        j                         j                         | j                  d<   || j                  d<   || j                  d<   | j                          d|v r%t         j                  d       | j                          |dv S # t        $ r t         j                  d       Y yt        $ r"}t         j!                  d|        Y d}~yd}~ww xY w)u   Vérifie si un retraining adaptatif est nécessaire (régime marché, win rate).
        Appelle ai_adaptive_retrainer.py pour évaluer et exécuter si besoin.
        r   u'   🧠 Vérification Retraining Adaptatifr   )get_adaptive_retraineru'      ℹ️  Pas de retrain nécessaire: last_adaptive_retrainlast_adaptive_reasonTu      🚨 Retrain déclenché: r$   UNKNOWNu&      ✅ Retraining adaptatif terminé: last_adaptive_result	EMERGENCYuJ      🚨 Emergency retrain détecté → relance entraînement LSTM complet)SUCCESSPARTIALu+   ⚠️ ai_adaptive_retrainer non disponibleFu!   ❌ Erreur retraining adaptatif: N)r*   rx   ai_adaptive_retrainerr   should_retrainr   r   r   r$   rK   retrain_allgetr   ImportErrorrv   r   r+   )r/   r   	retrainershould_trainreasonr   
status_strr   s           r0   check_adaptive_retrainz)AutoUpdaterService.check_adaptive_retrain  s    	H=>$	D.0I#,#;#;#= L&EfXNO7?||~7O7O7Q346<23!!#KK7x@A**,FHi8JKK@MN3;<<>3K3K3MDKK/028DKK./2<DKK./ f$hi##%!777 	NNHI 	LL<QC@A	s%   BF 5CF G1G9GGtaskintervalc                     d| }| j                   j                  |      }|sy	 t        j                  |      }t        j                         |z
  j                         }||k\  S #  Y yxY w)u,   Vérifie si une mise à jour est nécessairelast_T)r$   r   r   fromisoformatr   total_seconds)r/   r   r   last_update_keylast_updatelast_dtr   s          r0   _should_updatez!AutoUpdaterService._should_updateC  sh    !$.kkooo6	,,[9G||~/>>@Gh&&	s   >A$ $A(c                     t         j                  d       | j                          | j                          | j	                          t         j                  d       y)u*   Exécute toutes les tâches une seule foisu(   🚀 Exécution unique des mises à jouru   ✅ Mises à jour terminéesN)r*   rx   r   r   r   r.   s    r0   run_oncezAutoUpdaterService.run_onceR  sF    >? 	##% 	 	##%23r2   c                 @    d _         t        j                         j                          j                  d<    j                          t        t        d      5 }|j                  t        t        j                                      ddd       t        j                  d       t        j                  d       t        j                  d       t        j                  dt        j                                 t        j                  dt        d	   d
z   d       t        j                  dt        d   d
z   d       t        j                  dt        d   d
z   d       t        j                  dt        d   d
z   d       t        j                  d        fd}t        j                  t        j                   |       t        j                  t        j"                  |       d}t        j                  d|dz   d       t%        |      D ]%  } j                   s nt'        j(                  d       '  j                   r) j+                  dt        d	         r j-                           j                   r) j+                  dt        d         r j/                          d} j                   r	  j+                  dt        d         r j1                           j+                  dt        d	         r j-                           j+                  dt        d         r j/                           j+                  dt        d         r j3                          t%        |      D ]%  } j                   s nt'        j(                  d       '  j                   rt        j9                         rt        j;                          t        j                  d       y# 1 sw Y   MxY w# t4        $ r7}t        j7                  d|        t'        j(                  d       Y d}~d}~ww xY w)u"   Exécute le service en mode démonTr:   rE   Nr   u#   🔄 AUTO-UPDATER SERVICE DÉMARRÉz   PID: u%      Mise à jour données: toutes les r   r   hz   Sync rapide: toutes les r   u       Entraînement IA: toutes les r   z!   Retrain adaptatif: toutes les r   c                 >    t         j                  d       d_        y )Nu(   🛑 Signal d'arrêt reçu, fermeture...F)r*   rx   r"   )signumframer/   s     r0   signal_handlerz5AutoUpdaterService.run_daemon.<locals>.signal_handlerv  s    KKBC DLr2   iX  u   ⏳ Délai démarrage rs   u(   min (chargement modèles TF en cours)...r!   historical_updatern   u&   ❌ Erreur dans la boucle principale: u%   👋 Auto-updater arrêté proprement)r"   r   r   r   r$   rK   r=   PID_FILEwriterJ   rz   getpidr*   rx   UPDATE_INTERVALSsignalSIGINTSIGTERMrangerq   sleepr   r   r   r   r   r   r+   r)   unlink)r/   rB   r   STARTUP_DELAY_check_intervalr   s   `      r0   
run_daemonzAutoUpdaterService.run_daemona  sF   $,LLN$<$<$>L! (C  	&AGGC		$%	& 	H9:Hhryy{m,-;<LM^<_ae<e;ffghi12B<2PRV2V1WWXYZ67G7VX\7\6]]^_`78HI[8\^b8b7ccdefH	! 	fmm^4fnnn5 ,]B->,??ghi}% 	A<<JJqM	 <<D//0CEUVgEhi'')<<D//?OP]?^_! ll&&|5El5STOO% &&':<LM^<_`//1 &&}6F}6UV'') &&'9;KL^;_`//1 ~. "A<<JJqM"' ll: ??OO;<Q	& 	&@  EaSIJ

2s%   -O.CO O	P&-PPc           
          i | j                   | j                  | j                  dt        d         | j                  dt        d         | j                  dt        d         | j                  dt        d         dS )z$Retourne le statut actuel du servicer   r   r   r   r   )r"   next_historical_updatenext_ai_trainingnext_quick_syncnext_adaptive_retrain)r$   r"   _get_next_runr   r.   s    r0   
get_statuszAutoUpdaterService.get_status  s    
kk
||&*&8&89LN^_pNq&r $ 2 2=BRS`Ba b#11,@PQ]@^_%)%7%78JL\]oLp%q
 	
r2   c                    d| }| j                   j                  |      }|sy	 t        j                  |      }|t	        |      z   }|t        j
                         k  ry|t        j
                         z
  }t        |j                         dz        }t        |j                         dz  dz        }	d| d|	 dS #  Y y	xY w)
u   Calcule la prochaine exécutionr   u	   Immédiat)secondsr   rs   zDans zh rt   Inconnu)r$   r   r   r   r   r   intr   )
r/   r   r   r   r   r   next_dt	remaininghoursminutess
             r0   r   z AutoUpdaterService._get_next_run  s    !$.kkooo6	,,[9G	( ;;G(,,.("(,,.0I	//1T9:E9224t;BCG5'G9C00	s   ;B< !AB< <C )Nr   )__name__
__module____qualname____doc__r1   r   r#   rK   r   rJ   listr   boolr   r   r   r   r   r   r   r   r   r   r   ra   r2   r0   r   r   T   s    -d 2ATt T# TT T[^ Tjn Tl $D 4 (+ +Z3 # $ 4O=b	
D 	
#  # r2   r   r3   c                      t         j                         sy	 t        t         d      5 } t        | j	                         j                               }ddd       ddl}|j                        S # 1 sw Y   xY w#  Y yxY w)u7   Vérifie si le service est déjà en cours d'exécutionFr;   Nr   )r   r)   r=   r   readstrippsutil
pid_exists)rB   pidr   s      r0   
is_runningr     sk    ??(C  	(Aaffhnn&'C	( 	  %%	( 	(s"   A8 (A,A8 ,A51A8 8A<c            
         t         j                         rTt        t         d      5 } t        j                  |       }ddd       t        d       t        d       t        dj                  dd              t        d|j                  d	d
              t        d|j                  dd
              t        d|j                  dd
              t        d|j                  dd              t        d|j                  dd              |j                  d      rJt        d       |d   dd D ]3  }t        d|j                  dd       d|j                  dd              5 yyt        d       y# 1 sw Y   <xY w)zAffiche le statut du servicer;   Nu   
📊 STATUT AUTO-UPDATERz2==================================================u      Démarré: r:   zN/Au      Dernière sync données: r5   Jamaisu      Dernier entraînement IA: r6   u      Dernière sync rapide: r7   u      Total mises à jour: r8   r   u      Total entraînements: r9   r   u   
⚠️ Dernières erreurs:z   - rq   ru   rr   u:   
⚠️ Aucun statut disponible (service jamais exécuté))r<   r)   r=   r>   r?   printr   )rB   r$   errs      r0   show_statusr     si   +s# 	"qYYq\F	" 	*+hvzz,>?@A,VZZ8PRZ-[,\]^-fjj9KX.V-WXY*6::6G+R*STU(OQ)G(HIJ)&**5F*J)KLM::h02h', Tcggfe45R%8P7QRST  
 	KL#	" 	"s   E66F c                  v   t        j                  d      } | j                  ddd       | j                  ddd       | j                  d	dd
       | j                  ddd       | j                         }|j                  rt                y |j                  rt        j                         rt        t        d      5 }t        |j                         j                               }d d d        	 t        j                  t        j                          t#        d|        t        j%                          y t#        d       y t'               rt#        d       t                y t)               }|j*                  r|j-                          y |j/                          y # 1 sw Y   xY w#  t#        d        Y xY w)Nr   )rM   r   
store_trueu   Exécuter une seule fois)actionhelpz--daemonu   Mode démon (arrière-plan)z--statuszAfficher le statutz--stopu   Arrêter le servicer;   u*   🛑 Signal d'arrêt envoyé au processus u*   ⚠️ Impossible d'arrêter le processus u   ⚠️ Service non actifu?   ⚠️ Le service auto-updater est déjà en cours d'exécution)argparseArgumentParseradd_argument
parse_argsr$   r   stopr   r)   r=   r   r   r   rz   killr   r   r   r   r   r   oncer   r   )parserrN   rB   r   services        r0   mainr     sp   $$1VWF
<VW

<>[\

<>RS
<QRD{{yy??h$ ,!&&(..*+,JV^^,B3%HI OO 	 ,- |OP "Gyy 	1, ,
JB3%HIs   >(F/2F& F#&F8__main__),r   rz   r,   r>   rq   r   loggingr   r%   r~   r   r   pathlibr   typingr   r   __file__parentr   r}   r(   r<   r   LOG_FILEr   r   ioTextIOWrapperr   bufferrl   basicConfigINFOFileHandlerStreamHandler	getLoggerr*   r   r   r   r   r  r   ra   r2   r0   <module>r     s   
 
        (  ! (^""
<<7w&2\AKw&.:K 55****   	  #%??00$'CC 
Rcjj//')T
Rcjj//')T
   
,,6Hw7cjj)	 
		=	)~ ~BD  M6'T zF r2   