
    iy                        d Z ddlZej                  j                  dd       ej                  j                  dd       ej                  j                  dd       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mZ ddlZ ej*                  ej,                  d
d        ej.                  d      Z	 ddlZddlmZ ddlmZmZ dZdZ ejB                  jE                         rTejB                  jG                  d      Z 	  ejH                  d      jC                         Z%[%dZejM                  de         nejM                  d       ejM                  de         ejV                  d        ejX                  d       ejM                  d       ddl0m1Z1m2Z2 dZ3 ee4      jj                  dz  Z6 ee4      jj                  d z  Z7 ee4      jj                  d!z  d"z  Z8d#Z9d$Z:d%Z;d&Z<d'Z=d(Z>d)ee)   fd*Z? ee4      jj                  d+z  Z@dNd,e)d-e)d.eAd)efd/ZBdOd,e)d-e)d)ee   fd0ZCd1ej                  d2eAd)ej                  fd3ZE	 	 	 dPd4ej                  d5ej                  d6ej                  d7ej                  d8eAd)ej                  fd9ZFdQd4ej                  d:eAd;eGd)eAfd<ZHd4ej                  d5ej                  d6ej                  d7ej                  d8eAd=eAd;eGd)eeef   fd>ZIdRd?ee)   d@eAd)eej                  ej                  f   fdAZJ G dB dCej                        ZLdSdDej                  dEej                  dFeAdGeAd)ef
dHZMdIej                  dJefdKZNdL ZOePdMk(  r eO        yy# e'$ rIZ(d e)e(      v s
d e)e(      v r)ejU                  de  d       ejU                  d       dZn Y dZ([(adZ([(ww xY w# e-$ r' ej]                  d        ej^                  d       Y Kw xY w)Tu  
🎓 Script d'entraînement du modèle IA
=====================================
Utilise les données historiques de Binance pour entraîner le modèle LSTM
sur GPU (RTX 5060 Ti) pour prédire les mouvements de prix.

Usage:
    python train_ai_model.py                    # Entraînement standard
    python train_ai_model.py --epochs 100       # Plus d'epochs
    python train_ai_model.py --symbols 20       # Limiter le nombre de symboles
    NOMP_NUM_THREADS2MKL_NUM_THREADSOPENBLAS_NUM_THREADS)datetime	timedelta)Path)ListDictTuplez)%(asctime)s | %(levelname)s | %(message)sz%H:%M:%S)levelformatdatefmt	AITrainer)
DataLoaderTensorDatasetcpu   cudau!   ✅ GPU détecté et compatible: zno kernel imageznot compatibleu   ⚠️ GPU u+    détecté mais non compatible avec PyTorchu2      Architecture trop récente - Utilisation du CPUu*   ℹ️ Pas de GPU CUDA, utilisation du CPUu   🔧 Device sélectionné:    uB   🔧 Threads PyTorch limités à 2 (économie CPU/RAM, pas de GPU)u   ❌ PyTorch non installé!)get_ai_predictorTORCH_AVAILABLEzhttps://api.binance.com/api/v3zwatchlist.jsonzai_training_stats.jsonmodelszpredictor.pt   @   2            ?i:  returnc                      t         j                         rAt        t         d      5 } t        j                  |       }|j                  dg       cddd       S g dS # 1 sw Y   g dS xY w)zCharge la liste des symbolesrsymbolsN)BTCUSDTETHUSDTSOLUSDT)WATCHLIST_FILEexistsopenjsonloadget)fdatas     train_ai_model.pyload_watchlistr/   g   sZ    .#& 	+!99Q<D88Ir*	+ 	+ -,	+ -,s   'AA&historical_datasymbolintervallimitc                     	 t          d}| ||d}t        j                  ||d      }|j                  dk(  r|j	                         S 	 g S # t
        $ r&}t        j                  d|  d|        Y d}~g S d}~ww xY w)	u$   Récupère les klines depuis Binancez/klines)r1   r2   r3   
   )paramstimeout   zErreur fetch : N)BINANCE_APIrequestsr+   status_coder)   	Exceptionloggerwarning)r1   r2   r3   urlr6   responsees          r.   fetch_klinesrC   s   s    6W%"5I<<FB?3&==?" ' I  6vhb455I6s   AA 	A:A55A:c                    t         |  dz  }|j                         sg S 	 t        |d      5 }t        j                  |      }ddd       j                  di       }||vr"t        |j                               }|sg S |d   }||   j                  dg       }t        j                  dt        |       d| d	|         |S # 1 sw Y   xY w# t        $ r'}t        j                  d
|  d|        g cY d}~S d}~ww xY w)u   Charge les données historiques locales (historical_data/) pour un symbole.
    Retourne une liste de dicts avec keys: open, high, low, close, volume.z_historical.jsonr!   N	intervalsr   klinesu       📂 Local: z	 candles z pour z Erreur lecture historique local r9   )HISTORICAL_DIRr'   r(   r)   r*   r+   listkeysr>   infolenr=   r?   )	r1   r2   	hist_filer,   r-   rE   	availablerF   rB   s	            r.   load_local_historicalrN      s    F8+;!<<I	)S! 	 Q99Q<D	 HH["-	9$Y^^-.I	 |H8$((26&s6{m9XJfVHUV	  	   9&A3GH	s;   C C :C =AC  C	C 	C<C71C<7C<arrperiodc                 @   t        j                  | t         j                        }t        |       |k  r|S t        j                  | d|       ||dz
  <   d|dz   z  }t        |t        |             D ]  }| |   |z  ||dz
     d|z
  z  z   ||<    ||dz
     |d|dz
   |S )u;   Calcule l'EMA sur un array (retourne array de même taille)dtypeNr   g       @)np
zeros_likefloat64rK   meanrange)rO   rP   ema
multiplieris        r.   _emar\      s    
--2::
.C
3x&
GGCL)CqM
#J63s8$ CQ*$s1Q3x1z>'BBAC ]C	NJ    pricesvolumeshighslowslookbackc                 8   t        |       |k  ry| | d }t        j                  |      }t        j                  |      }|dk(  ry||z
  |z  }|at        |      |k\  rS|| d }	t        j                  |	      }
t        j                  |	      }|dkD  r|	|
z
  |z  nt        j                  |      }nd}	t        j                  |      }|t        |      |k\  r|| d }n|}|t        |      |k\  r|| d }n|}t        |d      }t        |d      }t        |d      }t        |d      }d}t        j                  |      }t        j                  |      }t        j                  |      }||kD  rTddlm}  |||      d||z
   }|j                  d	
      }|j                  d	
      }|||d |d|z  z   ||d |d|z  z
  ||d t        j                  |      }t        j                  |d	d |d	d z
  t        j                  t        j                  |d	d |dd z
        t        j                  |d	d |dd z
                    |d	d t        |d      }t        j                  |dft        j                        }||dddf<   |dd |d|dz
   z
  dz  |ddd	f<   |dd |d|dz
   z
  dz  |dddf<   |dkD  r.ddlm}  ||d      d|dz
   }|j                  d	
      |dddf<   t        d|      D ]  }t        j                  ||dz
  |d	z          } t        j                  t        j                  | dkD  | d            }!t        j                  t        j                  | dk  |  d            }"|"dkD  s|!|"z  }#ddd	|#z   z  z
  dz  dz
  ||df<    t        j                  |dd      dz  |dddf<   ||z
  |z  |dddf<   ||z
  |z  |dddf<   t        |      D ]$  }||   dkD  s||   ||   z
  ||   z  dz  ||df<   & t        j                  |dddf   dd      dz  |dddf<   t        d|      D ]-  }||dz
     dkD  s||   ||dz
     z
  ||dz
     z  dz  ||df<   / t        j                  |dddf   dd      dz  |dddf<   t        ||      D ]  }|dkD  s	||   |z
  |z  ||df<    t        ||      D ]  }|dkD  s	||   |z
  |z  ||df<    t        ||      D ]$  }||   dkD  s||   ||   z
  ||   z  dz  ||df<   & t        j                  t        j                  |dddf               dkD  r/t        j                  t        j                  |dddf               nd	}$|dddfxx   |$z  cc<   t        ||      D ]&  }||   ||   z
  }%|%dkD  s||   ||   z
  |%z  ||df<   ( t        j                  |dddf   dd	      dz
  |dddf<   t        |      D ]  }|dkD  s	||   ||   z
  |z  dz  ||df<     t        j                  |dddf   dd      dz  |dddf<   t        |      D ]  }|dkD  s	||   |z  dz  ||df<    t        j                  |dddf         dkD  rt        j                  |dddf         nd	}&|dddfxx   |&z  cc<   |dd |d|dz
   z
  dz  |dddf<   |	~t        |	j!                  t        j"                        d      }'t        d|      D ]  }|'|   dkD  s|	|   |'|   z  d	z
  ||df<     t        j                  |dddf   dd      dz  |dddf<   t        |      D ]$  }||   dkD  s||   ||   z
  ||   z  dz  ||d f<   & t        j                  |ddd f         dkD  rt        j                  |ddd f         nd	}(|ddd fxx   |(z  cc<   t        |      D ]$  }||   dkD  s||   ||   z
  ||   z  dz  ||d!f<   & t        j                  |ddd!f   dd      dz  |ddd!f<   |S )"u  Crée un échantillon d'entraînement avec les 20 features complètes.
    
    Features (alignées avec ai_predictor.py PatternFeatures):
     0: Prix normalisé (z-score)
     1: Momentum 5 périodes
     2: Momentum 10 périodes
     3: Volatilité glissante (10 périodes)
     4: RSI normalisé (centré sur 0)
     5: Volume normalisé (z-score)
     6: EMA9 normalisée
     7: EMA21 normalisée
     8: EMA_diff (EMA9-EMA21 en % du prix, utile pour squeeze/creux)
     9: EMA_slope (pente EMA9 sur 5 périodes)
    10: Bollinger upper band normalisée
    11: Bollinger lower band normalisée
    12: Bollinger bandwidth (indicateur de squeeze)
    13: Position dans les Bandes de Bollinger (0-1)
    14: MACD normalisé (EMA12-EMA26)
    15: ATR normalisé (Average True Range)
    16: Momentum 3 périodes (court terme, crucial pour timing)
    17: Volume momentum (ratio volume courant / moyenne)
    18: High-Low range normalisé (mesure de volatilité intrabar)
    19: Price-EMA21 distance (tendance de fond)
    Nr   	      r         )sliding_window_viewr   )axisr      rR      r5      d         ?                                 )rK   rT   rW   stdzerosr\   numpy.lib.stride_tricksrh   maximumabsfloat32rX   diffwhereclipmaxastyperV   ))r^   r_   r`   ra   rb   prices_samplemean_pstd_pprices_norm
vol_samplevol_meanvol_stdvol_normhighs_samplelows_sampleema9_arr	ema21_arr	ema12_arr	ema26_arr	bb_periodbb_midbb_upperbb_lowerrh   _bb_wins	_bb_mid_v	_bb_std_vatr_arr
atr_smoothfeatures	_vol_winsr[   changesgainslossesrsbw_maxbb_rangeatr_maxvol_mahl_maxs)                                            r.   create_training_sampler      sx	   6 6{XH9:&MWW]#FFF=!Ez !6)U2K s7|x7hYZ(
77:&&&$8?!J)W4RZI[
88H%SZ83hYZ($CI1H9:&# M1%H]B'I]B'I]B'I IXXhFxx!Hxx!H)?&}i@AV(YBVWMMqM)	LLaL(	&yz(1y=8(1y=8 hhx G**QR;qr?*


FF<#mCR&889FF;qr?]3B%778	
GABK gr"J xx2bjj9H !HQTN #12]hl)CCqHHQRUO $BC(;~2+FF"LHRS!V "}?'R8(R-H	$==a=0a 2x  B''-"QqS121gq9:'A+x;<A:B!SAF^4;cAHQTNB WWXr1-1HQTN '50HQTN  &(E1HQTN 8_ OQ<!&qkIaL8IaLH3NHQTNO WWXad^R3a7HQTN 1h QAaC=1&qkHQqSM9Xac]JSPHQTNQ WWXad^R3a7HQTN 9h' =19'{V3u<HQUO=
 9h' =19'{V3u<HQUO=
 9h' L!9q='{Xa[8F1IEKHQUOL 13rvvhq"uo7N0ORS0SRVVBFF8ArE?+,YZFQUOvO 9h' JA;!,a<,Q/(1+=IHQUOJ gghq"uoq!4s:HQUO 8_ KA:(|il:fDsJHQUOK gghq"uor159HQUO 8_ ;A:(mf4s:HQUO; *,B)@1)DbffXae_%!GQUOwO $AB+mx!|*DDIHQRV j''

3R8r8$ 	BAay1}#-a=6!9#<"AB	B ''(1b5/2q9A=B 8_ Za+AQ?=QRCSSVYYHQUOZ )+x2(?!(CRVVHQUO$FQUOvO 8_ UQ<!,Q/)A,>)A,NQTTHQUOU gghq"uor159HQUOOr]   future_bars	thresholdc                 l    t        |       |dz   k  ry| d   }| |   }||z
  |z  dz  }||k\  ry|| k  ryy)ua   
    Détermine le label basé sur le mouvement futur
    0 = baisse, 1 = neutre, 2 = hausse
    r   r   rn   r   )rK   )r^   r   r   current_pricefuture_price
pct_changes         r.   determine_labelr   q  sY    
 6{[1_$1IM+&L.-?#EJY		z	!r]   futurec           
         g g }}t        |t        |       |z
        D ]j  }	t        | d|	dz    ||d|	dz    nd||d|	dz    nd||d|	dz    nd|      }
|
9t        | |	d ||      }|j	                  |
       |j	                  |       l ||fS )uA   Génère des échantillons glissants à partir de données OHLCV.Nr   )rX   rK   r   r   append)r^   r_   r`   ra   rb   r   r   X_outy_outr[   samplelabels               r.   _generate_samples_from_ohlcvr     s     r5E8S[612 '4AaCL7+>'$1Q3-D ,E$1Q3K$*D!A#J	
 >qr
FI>VU %<r]   r"   max_symbolsc                 P
   t         j                  d       g }g }| d| }t        |      }t        |      D ]2  \  }}t         j                  d|dz    d| d| d       d}t	        |d	      }	t        |	      d
k\  rWt        j                  |	D 
cg c]  }
t        |
d          c}
      }t        j                  |	D 
cg c]  }
t        |
j                  dd             c}
      }t        j                  |	D 
cg c]   }
t        |
j                  d|
d               " c}
      }t        j                  |	D 
cg c]   }
t        |
j                  d|
d               " c}
      }d}d}t        ||||t        ||      \  }}|j                  |       |j                  |       |t        |      z  }t         j                  dt        |       d       t        |dd      }t        |      d
k\  r.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}
      }t        ||||t        t        t              \  }}|j                  |       |j                  |       |t        |      z  }t         j                  dt        |       d       |dk(  rt         j                  d|        nt         j                  d| d       t!        j"                  d       5 t        |      dk(  rt         j%                  d       yt        |      t&        kD  rvddl}t+        |j-                  t/        t        |            t&                    }|D cg c]  }||   	 }}|D cg c]  }||   	 }}t         j                  dt&         d        t        j                  |t
        j0                  !      }t        j                  |t
        j2                  !      }~~t5        j6                          t        j8                  |d"#      \  }} t         j                  d$       t;        ||       D ]=  \  }!}"g d%|!   }#|"t        |      z  d
z  }$t         j                  d&|# d'|" d(|$d)d*       ? ||fS c c}
w c c}
w c c}
w c c}
w c c}
w c c}
w c c}
w c c}
w c c}w c c}w )+u   Génère les données d'entraînement depuis l'historique local + API Binance.
    
    Priorité: données locales (historical_data/) pour volume plus important,
    puis API Binance (5m) pour données très récentes.
    u?   📊 Génération des données d'entraînement (local + API)...Nz  [r   /z] ...r   1hrn   closevolumehighlowrr   g      ?u       📂 Local 1h: u    échantillons5mi  rp   rl   r   rm   u       🌐 API 5m: u       ⚠️ Aucune donnée pour u       ✓ Total: g333333?u   ❌ Aucune donnée générée!)NNu      ↓ Dataset limité à u#    échantillons (économie mémoire)rR   T)return_countsu   
📈 Distribution des labels:)BaisseNeutreHaussez   r9    (.1fz%))r>   rJ   rK   	enumeraterN   rT   arrayfloatr+   r   DEFAULT_LOOKBACKextendrC   DEFAULT_FUTUREGAIN_THRESHOLDr?   timesleeperrorMAX_TOTAL_SAMPLESrandomsortedr   rX   r   int64gccollectuniquezip)%r"   r   X_ally_allsymbols_to_usetotalidxr1   symbol_sampleslocal_klineskprices_localvolumes_localhighs_local
lows_locallocal_futurelocal_thresholdX_localy_localrF   
prices_apivolumes_api	highs_apilows_apiX_apiy_api_random_idxr[   Xyr   countsuc
label_namepcts%                                        r.   generate_training_datar     s[    KKQSEE\k*NE 0 0Vc#a%%6(#67 -VT:|#88$M1U1W:%6$MNLHH%VAeAEE(A,>&?%VWM((l#[E!%%'
*C$D#[\KL"Yq5uaj)A#B"YZJ L!O;m[* , GW LL!LL!c'l*NKK-c'l^>JK fdC0v;#"?151;"?@J((#@AE!A$K#@AKv!>!%!+!>?Ixxf =qt =>H7KH ..LE5 LLLLc%j(NKK+CJ<~FGQNN<VHEFKK/.)9HI 	

4a0d 5zQ56 5z%% gnnU3u:%68IJK#'(aq((#'(aq((01B0CCfgh
bjj)A
bhh'AuJJL YYq5NFF
KK13FF# :13A6
#a&j3c*Rs"SIR89:
 a4KI %N%V#["Y$ #@#@!> =6 )(s<   S6
="S;
9%T 
8%T
T

0T
T
T
T,T#c                   *     e Zd ZdZd fd	Zd Z xZS )PredictorLSTMu5   Modèle LSTM pour la prédiction de direction de prixc                     t         |           t        j                  |||dd      | _        t        j
                  |      | _        t        j                  |d      | _        t        j                  dd      | _	        y )NTg        )
input_sizehidden_size
num_layersbatch_firstdropout    rm   )
super__init__nnLSTMlstmDropoutr  Linearfc1fc2)selfr   r  r  r  	__class__s        r.   r  zPredictorLSTM.__init__  sc    GG!#!
	 zz'*99["-99R#r]   c                     | j                  |      \  }}|d d dd d f   }| j                  |      }t        j                  | j	                  |            }| j                  |      }|S )Nrj   )r
  r  torchrelur  r  )r  xlstm_out_last_outputs        r.   forwardzPredictorLSTM.forward
  sY    iil!q"ax(LL%JJtxx{#HHQKr]   )rg   r   r   g?)__name__
__module____qualname____doc__r  r  __classcell__)r  s   @r.   r   r     s    ?$r]   r   r   r   epochs
batch_sizec                 \   t         j                  dt        j                          d       t         j                  d|        t         j                  d|        t         j                  dt	        |               t        j                  | t
        j                        }t        j                  |t
        j                        }t        t	        |       dz        }|d| j                         }||d j                         }|d| j                         }	||d j                         }
~~t        j                          t         j                  d	t	        |       d
t	        |              t        ||	      }t        ||
      }t        ||d      }t        ||      }t               j!                  t              }t#        d |j%                         D              }t         j                  d|d       t        j&                  |	d      j)                         }|j#                         }|d|j+                  d      z  z  }||j-                         z  }|j!                  t              }t         j                  d|j/                         j1                                 t
        j2                  j5                  |j%                         dd      }t
        j2                  j6                  j9                  |ddd      }t;        j<                  |      }d}t)        d       }d}d}d!}g g g g d"}t?        j>                         }tA        |      D ]e  }|jC                          d}d} d}!|D ]  \  }"}#|"j!                  t              }"|#j!                  t              }#|jE                           ||"      }$ ||$|#      }%|%jG                          |jI                          ||%jK                         z  }t        jL                  |$jN                  d      \  }&}'|!|#jQ                  d      z  }!| |'|#k(  j#                         jK                         z  }  t
        j:                  jR                  jU                  |j%                         d#$       |t	        |      z  }| |!z  }(|jW                          d})d}*d}+t        jX                         5  |D ]  \  }"}#|"j!                  t              }"|#j!                  t              }# ||"      }$ ||$|#      }%|)|%jK                         z  })t        jL                  |$jN                  d      \  }&}'|+|#jQ                  d      z  }+|*|'|#k(  j#                         jK                         z  }* 	 ddd       |)t	        |      z  })|*|+z  },|jI                  |)       |,|kD  r"|,}|j[                         j]                         }d}|)|k  r|)}d}n|dz  }||k\  r&|d%kD  r!t         j                  d&|dz    d'| d(        n|d)   j_                  |       |d*   j_                  |(       |d+   j_                  |)       |d,   j_                  |,       |dz  dk(  s
||dz
  k(  st?        j>                         |z
  }-t         j                  d-|dz   d.d/| d0|d1d2|(d3d4|)d1d2|,d3d5|d3d6|-d7d8       h |ja                  |       t?        j>                         |z
  }.t         j                  d9|.d:d8       t         j                  d;|d3       ||||.t	        |       |d<S # 1 sw Y   xY w)=u!   Entraîne le modèle LSTM sur GPUu(   
🎓 Démarrage de l'entraînement sur r   z   Epochs: z   Batch size: u      Échantillons: rR   g?Nz
   Train: z, Val: T)r  shuffle)r  c              3   <   K   | ]  }|j                           y w)N)numel).0ps     r.   	<genexpr>ztrain_model.<locals>.<genexpr>4  s     =Qqwwy=s   u      Paramètres du modèle: ,rm   )	minlengthg      @r   )minz+   Poids de classe (baisse/neutre/hausse): gMbP?gh㈵>)lrweight_decayr)  rl   ro   )modepatiencefactor)weightr   infrt   )
train_loss	train_accval_lossval_accr   )max_normrg   u"      ⏹️ Early stopping à epoch u    (pas d'amélioration depuis z epochs)r1  r2  r3  r4  z	   Epoch 3dr   z
 | Train: z.4fr   .1%z	) | Val: z
) | Best: z	 | Time: z.0fsu   
✅ Entraînement terminé en r   z"   Meilleure accuracy validation: )modelhistorybest_val_acc
total_timesamples_countr  )1r>   rJ   DEVICEupperrK   r  tensorr   longintcloner   r   r   r   r   tosum
parametersbincountr   clamprW   r   tolistoptimAdamlr_schedulerReduceLROnPlateaur  CrossEntropyLossr   rX   train	zero_gradbackwardstepitemr   r-   sizeutilsclip_grad_norm_evalno_grad
state_dictcopyr   load_state_dict)/r   r   r  r  X_tensory_tensor	split_idxX_trainX_valy_trainy_valtrain_datasetval_datasettrain_loader
val_loaderr9  total_paramsclass_countstotal_samplesclass_weights	optimizer	scheduler	criterionr;  best_val_lossbest_model_statepatience_counterearly_stop_patiencer:  
start_timeepochr1  train_correcttrain_totalbatch_Xbatch_youtputslossr  	predictedr2  r3  val_correct	val_totalr4  elapsedr<  s/                                                  r.   train_modelr~    s   
KK;FLLN;K3OP
KK+fX&'
KK/*./
KK$SVH-. ||AU]]3H||AUZZ0H CFSL!Iz	"((*Gyz"((*Ez	"((*Gyz"((*E(JJL
KK*S\N'#e*>? "'73Mu-Km
DQLKJ?J Ov&E =%*:*:*<==L
KK-l1-=>? >>'Q7==?L $$&M!S<+=+=!+=+D%DEM!M$6$6$88M!$$V,M
KK=m>O>O>Q>X>X>Z=[\]  !1!1!3D QI((::95[\eh:iI##=9I L%LMbbRPGJv U
 , 	AGWjj(Gjj(G!GnGWg.DMMONN$))+%J 99W\\15LAy7<<?*Ki72779>>@@M	A  	&&u'7'7'9C&Hc,''
!K/	 	

	]]_ 	C$. 
C !**V,!**V,. '2DIIK'$yyq99W\\!_,		W 499;@@BB
C	C 	C
O#	) 	x  \!"L$//1668 m#$M ! 22urzKK<U1WIEbcvbww  A  B 	$$Z0##I.
""8,	!!'* 19>Ufqj0iikJ.GKKE!GB<q 1$S)Ic? ; ~R} 5%c* + Q	(_Up 
*+z)J
KK2:c2B!DE
KK4\#4FGH $ Q y	C 	Cs   >B4\!!\+	r9  statsc                 X   t         j                  j                  d       t        j                  | j                         ddddddt                t        j                  d	t                 d
|d   |d   |d   d   d   |d   d   d   |d   dz  t        j                         j                         ddt        dk(  rt        ndt        dk(  |d   d}t        t        d      5 }t        j                   ||d       ddd       t        j                  dt                y# 1 sw Y   &xY w)u.   Sauvegarde le modèle et met à jour les statsT)exist_okr   rg   r   r  rm   )model_state_dictmodel_classr   hidden_size1hidden_size2output_sizeu   💾 Modèle sauvegardé: trainedr=  r  r:  r1  rj   r2  r;  rn   r   r   CPUr<  )statusr=  epochs_completed	last_losslast_accuracyvalidation_accuracylast_trainingpredictions_madecorrect_predictionsgpu_namegpu_availabletraining_time_secondswr   )indentNu   📊 Stats sauvegardées: )
MODEL_PATHparentmkdirr  saverY  r>   rJ   r   now	isoformatr>  GPU_NAMEr(   
STATS_FILEr)   dump)r9  r  training_statsr,   s       r.   
save_modelr    s-    T* 
JJ!,,.&  KK,ZL9: /!(O9%l3B7y)+6r:$^4s:!113  && 0He6)!&|!4N 
j#	 /!		.!A./ KK,ZL9:/ /s   "D  D)c                     t        j                  d      } | j                  dt        t        d       | j                  dt        t
        d       | j                  dt        d	d
       | j                         }t        dt        j                         ddt        dk(  rt        nddd|j                  dd|j                  dd	       t               }t        j                  dt!        |       d       t#        ||j$                        \  }}|t        j'                  d       y t        j                  d|j(                  d    d|j(                  d    d|j(                  d    d       t+        |||j                  |j                         }~~t-        j.                          t1        |d!   |       t        d"|d#   d$d%|d&   d'd(|d)   d*d+       y ),Nu   Entraînement du modèle IA)descriptionz--epochszNombre d'epochs)typedefaulthelpz--batch-sizezTaille des batchesz	--symbolsrx   zNombre max de symbolesu  
╔══════════════════════════════════════════════════════════════╗
║         🎓 ENTRAÎNEMENT DU MODÈLE IA - GPU ACCELERATED       ║
╠══════════════════════════════════════════════════════════════╣
║  Device: 6su8                                             ║
║  GPU: r   zN/A50su      ║
║  Epochs: 4du@                                              ║
║  Batch Size: u                                          ║
╚══════════════════════════════════════════════════════════════╝
u   📋 z symboles dans la watchlist)r   u$   Impossible de générer les donnéesu   
📦 Dataset: r   u    échantillons, r   z timesteps, r   z	 features)r  r  r9  u  
╔══════════════════════════════════════════════════════════════╗
║                    ✅ ENTRAÎNEMENT TERMINÉ                    ║
╠══════════════════════════════════════════════════════════════╣
║  Échantillons utilisés: r=  r'  u9                              ║
║  Accuracy validation: r;  r7  u2                               ║
║  Temps total: r<  r   u1  s                                    ║
║  Modèle sauvegardé: models/predictor.pt                      ║
╚══════════════════════════════════════════════════════════════╝
)argparseArgumentParseradd_argumentrB  DEFAULT_EPOCHSDEFAULT_BATCH_SIZE
parse_argsprintr>  r?  r  r  r  r/   r>   rJ   rK   r   r"   r   shaper~  r   r   r  )parserargsr"   r   r   results         r.   mainr    s   $$1NOF

nK]^
S:LSgh
#r@XYD	  llnR  !'8U3
7 8kk" //"% &	 	 G
KK%G~%@AB "'t||DDAqy;<
KK"1771:,.>qwwqzl,WXW^W^_`WaVbbklm AdkkdooNF	1JJL vg'	   &o6q9 :!.1#6 7,', -	 	r]   __main__)r   i  )r   )NNNr   )r   r   )r   )r   r  )Qr  osenviron
setdefaultsysr)   r   r   r  r;   numpyrT   r   r   pathlibr	   typingr
   r   r   loggingbasicConfigINFO	getLoggerr>   r  torch.nnr  torch.utils.datar   r   r>  r  r   is_availableget_device_namer   test_tensorrJ   RuntimeErrorrB   strr?   set_num_threadsset_num_interop_threadsImportErrorr   exitai_predictorr   r   r:   __file__r  r&   r  r  r  r  r   r   r   r   r/   rG   rB  rC   rN   ndarrayr\   r   r   r   r   r   Moduler   r~  r  r  r   r]   r.   <module>r     s~  
 
 

  ' - 

  ' - 

  ,c 2 
   	    (  $ $    
,,6
 
		;	'$: FHzz ::--a0	%%++a.--/KFKK;H:FG 	@A
KK-fX67E!!E!!!$
KKTU ; /h&&)99(^""%==
(^""X->
    -S	 - h&&)::
 
 
3 
$ 
#  T
 0bjj # "**  FJHL+-H2:: H

 H"$**H;=::H%(H24**HVBJJ S % Z] * bjj *,**<>JJ-0:=JOTYZ^`dZdTe(YDI YC Yrzz[][e[eOeIf Y@BII 4a2:: a"** ac aC aY] aH#;bii #; #;T/d zF u  	 CF*.>#a&.HXJ6abcST 		   
LL-.CHHQKs>   AO 7M2 AO 2O 7>N;5O ;O  O (O/.O/