
    Dig                     x   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mZmZ ddlZ ej"                  ej$                          ej&                  d      ZdZd	Zd
ZdZ	 ddlZddlmZ ddlmc mZ  ej<                  d       	  ej>                  d       ejB                  jE                         r4dZejB                  jG                  d      ZdZejI                  de        ndZejI                  d       dZ&dZ'dZ(dZ)e G d d             Z*ere G d dejV                        Z,n
 G d d      Z, G d d      Z-da.de-fdZ/e0dk(  r< e/       Z1 e2d        e2d e         e2d!e         e2d"e(         e2d#e)        yy# e $ r Y w xY w# e%$ r ejI                  d       dZY w xY w)$u,  
AI OPPORTUNITY SELECTOR - Sélection intelligente des meilleures opportunités
==============================================================================

Utilise PyTorch + GPU (RTX) pour analyser les 58 cryptos de la watchlist et
sélectionner les 15-20 meilleures opportunités basées sur:
- Volatilité prédictive (mouvements attendus)
- Potentiel de gain dans les 6-24h
- Qualité des patterns actuels
- Momentum AI-prédit

Architecture:
1. Feature extraction: 50+ features techniques par crypto
2. Volatility prediction: Réseau neuronal prédit amplitude future
3. Gain prediction: Prédit variation prix dans 6h/24h
4. Opportunity scoring: Score final 0-100 pour chaque crypto
5. Selection: TOP 15-20 cryptos avec meilleur score

Mise à jour: Toutes les 30 min (balance performance/réactivité)
    N)datetime	timedelta)DictListTupleOptional)	dataclassfield)levelAIOpportunitySelectorFcpuCPU      cudaTu2   ✅ GPU RTX activé pour AI Opportunity Selector: u2   ⚠️ PyTorch disponible mais sans GPU - Mode CPUu<   ℹ️  PyTorch non installé - Sélection basique utiliséezai_opportunities.json      7   c                   |   e Zd ZU dZeed<    eej                        Z	eed<   dZ
eed<   dZeed<   dZeed<   dZeed	<   d
Zeed<   dZeed<   dZeed<   dZeed<   dZeed<   dZeed<   dZeed<   dZeed<   dZeed<   dZeed<   dZeed<   dZeed<    ee      Zee   ed<    ee      Z ee   ed<   de!fdZ"y)OpportunityProfileu%   Profil d'opportunité pour une cryptosymbol)default_factory	timestamp        predicted_volatility_6hpredicted_volatility_24hpredicted_move_6hpredicted_move_24hNEUTRALpredicted_directionvolatility_scoremomentum_scorepattern_scoretrend_scoreentry_timing_scorerisk_reward_scoreopportunity_scoregain_potential
confidencer   rankFselectedreasonswarningsreturnc                 ,   | j                   | j                  j                         t        t	        | j
                  d            t        t	        | j                  d            t        t	        | j                  d            t        t	        | j                  d            t        | j                        dt        t	        | j                  d            t        t	        | j                  d            t        t	        | j                  d            t        t	        | j                  d            t        t	        | j                  d            t        t	        | j                   d            dt        t	        | j"                  d            t        t	        | j$                  d            t        t	        | j&                  d            t)        | j*                        t-        | j.                        t1        | j2                        t1        | j4                        dS )uK   Convertit en dictionnaire - Force conversion float pour compatibilité JSONr   )volatility_6hvolatility_24hmove_6hmove_24h	directionr   )
volatilitymomentumpatterntrendentry_timingrisk_rewardr   )r   r   predictionsscoresr'   r(   r)   r*   r+   r,   r-   )r   r   	isoformatfloatroundr   r   r   r   strr    r!   r"   r#   r$   r%   r&   r'   r(   r)   intr*   boolr+   listr,   r-   )selfs    ai_opportunity_selector.pyto_dictzOpportunityProfile.to_dicth   s    kk113!&uT-I-I1'M!N"'d.K.KQ(O"P t'='=q!AB!%(?(?"CD !9!9: $E$*?*?$CD!%(;(;Q"?@ t'9'91!=>uT%5%5q9: %eD,C,CQ&G H$U4+A+A1%EF "'uT-C-CQ'G!H#E$*=*=q$ABdooq 9:		NT]]+DLL)T]]+1
 	
    N)#__name__
__module____qualname____doc__r@   __annotations__r
   r   nowr   r   r>   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   rA   r+   rB   rC   r,   r   r-   r   rF    rG   rE   r   r   H   s    /K=Ix= &)U(&)e)"u" ##(( "e!NEM5K ##"u"  #u"NEJD#M Hdt4GT#Y45Hd3i5
 
rG   r   c                   *     e Zd ZdZd fd	Zd Z xZS )VolatilityPredictorNNu   
        Réseau neuronal pour prédire la volatilité future
        Input: 50 features techniques
        Output: [volatility_6h, volatility_24h, direction_prob]
        c                 r   t         t        |           t        j                  |d      | _        t        j                  d      | _        t        j                  d      | _	        t        j                  dd      | _
        t        j                  d      | _        t        j                  d      | _        t        j                  dd      | _        t        j                  d      | _        t        j                  dd      | _        t        j                  dd      | _        t        j                  dd      | _        y )N   333333?@   皙?    r   r   )superrP   __init__nnLinearfc1BatchNorm1dbn1Dropoutdropout1fc2bn2dropout2fc3bn3vol_6hvol_24hr4   )rD   
input_size	__class__s     rE   rX   zVolatilityPredictorNN.__init__   s    '79yyS1DH~~c*DHJJsODMyyb)DH~~b)DHJJsODMyyR(DH~~b)DH ))B*DK99R+DLYYr1-DNrG   c                 j   t        j                  | j                  | j                  |                  }| j	                  |      }t        j                  | j                  | j                  |                  }| j                  |      }t        j                  | j                  | j                  |                  }t        j                  | j                  |            dz  }t        j                  | j                  |            dz  }t        j                  | j                  |      d      }|||fS )N
      r   dim)Frelur]   r[   r_   ra   r`   rb   rd   rc   torchsigmoidre   rf   softmaxr4   )rD   xre   rf   r4   s        rE   forwardzVolatilityPredictorNN.forward   s    txx,-Aa Atxx,-Aa Atxx,-A]]4;;q>2R7FmmDLLO4r9G		$.."3;I7I--rG   )2   )rH   rI   rJ   rK   rX   rt   __classcell__)rh   s   @rE   rP   rP      s    	
	.$	.rG   rP   c                       e Zd Zy)rP   N)rH   rI   rJ   rN   rG   rE   rP   rP      s    rG   c                       e Zd ZdZd Zd ZdefdZdede	j                  fdZde	j                  deeeef   fd	Zd
ede	j                  defdZdededefdZdee   dee   fdZdee   fdZdedee   fdZdee   fdZdee   fdZy)r   u;   Sélecteur intelligent d'opportunités basé sur IA PyTorchc                    d | _         d | _        i | _        d | _        t        | _        | j
                  rL	 t        j                   t              | _         | j                          t        j                  dt                y t        j                  d       y # t        $ r*}t        j                  d| d       d| _        Y d }~y d }~ww xY w)Nu,   ✅ AI Opportunity Selector initialisé sur u   ⚠️ Erreur init PyTorch: z - Mode fallbackFu-   ⚠️ Mode fallback CPU - Sélection basique)devicemodelopportunitieslast_updateTORCH_AVAILABLEtorch_availablerp   DEVICE_init_modelloggerinfo	Exceptionwarning)rD   es     rE   rX   zAIOpportunitySelector.__init__   s    
.-#ll62  "J6(ST
 NNJK	  -!=aS@PQR',$$-s   A
B 	C	 CC	c                    | j                   sy	 t        d      j                  | j                        | _        | j                  j                          d}t        j                  j                  |      rD| j                  j                  t        j                  |             t        j                  d       yt        j                  d       y# t        $ r)}t        j                  d|        d| _        Y d}~yd}~ww xY w)u$   Initialise le modèle de prédictionNru   )rg   zai_volatility_predictor.pthu#   ✅ Modèle pré-entraîné chargéuH   ℹ️ Modèle initialisé avec poids aléatoires (entraînement requis)u#   ❌ Erreur initialisation modèle: )r   rP   torz   r{   evalospathexistsload_state_dictrp   loadr   r   r   error)rD   
model_pathr   s      rE   r   z!AIOpportunitySelector._init_model   s    ##	."=@@MDJJJOO 7Jww~~j)

**5::j+ABABfg 	LL>qcBCDJJ	s   B(C 8C 	D C;;D r.   c                     | j                   syt        j                         | j                   z
  j                         dz  }|t        k\  S )u,   Vérifie si une mise à jour est nécessaireT<   )r}   r   rM   total_secondsUPDATE_INTERVAL_MINUTES)rD   minutes_since_updates     rE   should_updatez#AIOpportunitySelector.should_update   s@     (1A1A APPRUWW#'>>>rG   crypto_datac           	         g }	 |j                  dd      }|j                  d|      }|j                  d|      }|j                  d|      }|dkD  r<|j                  ||z
  |z  ||z
  |z  |dkD  r||z
  |z  nd|dkD  r||z
  |z  ndg       n|j                  g d       |j                  dd      }|j                  dd      }|j                  d	d      }	|j                  d
d      }
|j                  |||	|
g       |j                  d|      }|j                  d|      }|dkD  r||z
  |z  nd}|j                  dd      }|j                  |dkD  r||z
  |z  nd|dkD  r||z
  |z  nd||g       |j                  dd      }|dz
  dz  }|j                  dd      }|j                  dd      }|j                  |||g       |j                  dd      }|j                  dd      }|dk  rdnd}|j                  ||dz  |g       |j                  dd      }|j                  dd      }|dkD  rdnd}|j                  t        j                  |      ||g       |j                  dd      }|j                  dd      }|j                  dd      }|j                  |||g       |j                  dd       rdnd}|j                  d!d       rdnd}|j                  d"d       rdnd}|j                  |||g       |dkD  rdnd#}|j                  d$d      } |j                  d%d      }!|j                  || |!g       |dkD  r||z
  |z  nd}"|dkD  r||z
  |z  nd}#|j                  d&|      }$|j                  d'|      }%|dkD  r|$|z
  |z  nd}&|dkD  r||%z
  |z  nd}'||z
  dkD  r||z
  ||z
  z  nd}(|j                  |"|#|&|'|(g       |j                  d(d      })|dkD  r||z
  |z  nd}*|j                  d)d      }+|j                  d*d      },|j                  d+d      }-|j                  |)|*|+t        j                  |,      |-g       |j                  d,d      }.|j                  d-d      }/|j                  d.d      }0|j                  |.|/|0g       |j                  d/d      d0z  }1|j                  d1d      d0z  }2|j                  d2d      d0z  }3|j                  d3d      d0z  }4|j                  d4d      d0z  }5|j                  d5d      d0z  }6|j                  d6d      d0z  }7|j                  |1|2|3|4|5|6|7g       t	        |      dk(  sJ d7t	        |              t        j
                  |t        j                  8      S # t        $ rG}8t        j                  d9|8        t        j                  dt        j                  8      cY d:}8~8S d:}8~8ww xY w);u  
        Extrait 50 features techniques pour une crypto
        
        Features:
        - Prix: close, high, low, open (4)
        - Momentum: 3, 5, 10, 20 bougies (4)
        - EMA: 9, 21, diff, slope (4)
        - RSI + dérivées (3)
        - BB: position, bandwidth, squeeze (3)
        - Volume: ratio, trend, anomalies (3)
        - Volatilité historique: 1h, 6h, 24h (3)
        - Patterns: squeeze, breakout, reversal (3)
        - Tendance: short, medium, long (3)
        - Prix relatifs: distances EMA, BB, pivots (5)
        - Statistiques: std, range, ATR (5)
        - Cyclicité: périodicité, régularité (3)
        - Score IA existant + composants (7)
        = 50 features
        current_pricer   high_24hlow_24h
open_price)r   r   r   r   
momentum_3
momentum_5momentum_10momentum_20ema_9ema_21	ema_slopersiru   
rsi_changersi_divergencebb_position      ?bb_bandwidthr   r   rj   volume_ratio      ?volume_trend       @volatility_1hr0   r1   squeeze_activeFbreakout_detectedreversal_patterntrend_medium
trend_longbb_upperbb_lowerprice_std_20atravg_volume_20volume_std_20squeeze_frequencycycle_regularitytime_since_last_squeezeai_scored   technical_scorer"   r#   r$   entry_qualityr)   zAttendu 50 features, obtenu dtypeu    ❌ Erreur extraction features: N)getextendnplog1plenarrayfloat32r   r   r   zeros)9rD   r   featuresclosehighlowr   r   r   r   r   r   r   ema_diffr   r   rsi_normalizedrsi_velocityr   r   r   
bb_squeezer   r   volume_anomalyr   r0   r1   
is_squeezeis_breakoutis_reversaltrend_shortr   r   	dist_ema9
dist_ema21r   r   dist_bb_upperdist_bb_lowerprice_range_pos	price_stdprice_ranger   
avg_volume
volume_stdr   r   r   r   r   r"   r#   r$   r   r)   r   s9                                                            rE   extract_featuresz&AIOpportunitySelector.extract_features   s    ( s	2OOOQ7E??:u5D//)U3C$u=JqyE\U*S[E)4>NUZ'50,1AITCZ5(1	!  - %q9J$q9J%//-;K%//-;KOOZ[+NO  OOGU3E __Xu5F6<qj61aH#Q7IOO+019%'!,1AI5(1	  //%,C!Bh"_N&??<;L(__-=qANOO^\>JK &//-=K&??>1=L*Q.AJOO[,*;ZHI '??>3?L&??>1=L"."4Q!NOORXXl3\>RS (OOOQ?M'OOOQ?M(__-=qANOO]M>JK *oo.>FAJ*/BEJ!PQK*/A5I!qKOOZkBC  (!|!K&??>1=L$q9JOO[,
CD 4919%/!I5:QY%&.E1AJ"z59H"z59H:?!)X-6M:?!)UX-6M?CczQ>Nus{tcz:TWOOOY
M=Rabc $:I27!)4#:.K//%+C$!<J$!<JOOYS"((::NPZ[\ !,0CQ G*/A1E&1oo6OQR&S#OO.0@BYZ[ #z26<H)oo.?DsJO(__-=rBSHN'OOOR@3FM%//-<sBK'OOOR@3FM$r:S@JOOX&zC D x=B&V*Fs8}o(VV&88HBJJ77 	2LL;A3?@88Bbjj11	2s   U=V 	W<WWWr   c                 *   | j                   r| j                  =t        |d         dz  }t        |d         dz  }|d   dkD  rdn|d   dk  rdnd}|||fS 	 t        j                         5  t        j
                  |t        j                  	      j                  d      j                  | j                        }| j                  |      \  }}}|j                         }|j                         }t        j                  |d
      j                         }	g d|	   }|||fcddd       S # 1 sw Y   yxY w# t        $ rU}
t        j                  d|
        t        |d         dz  }t        |d         dz  }|d   dkD  rdnd}|||fcY d}
~
S d}
~
ww xY w)u   
        Prédit l'opportunité pour une crypto
        
        Returns:
            (volatility_6h, volatility_24h, direction)
        N   r      r   UPDOWNr   r   r   rl   )r   r   r   u   ❌ Erreur prédiction: )r   r{   absrp   no_gradtensorr   	unsqueezer   rz   itemargmaxr   r   r   )rD   r   r0   r1   r4   rs   re   rf   direction_probsdirection_idxr   s              rE   predict_opportunityz)AIOpportunitySelector.predict_opportunityp  s    ##tzz'9,s2M !-3N (aafU^I .);;	< @LL?II!LOOPTP[P[\ 48::a=0 !'!( !&_! D I I K5mD	$ni?@ @ @"  	<LL3A378,s2M !-3N (aVI .);;	<s>   D4 +B3D(	D4 (D1-D4 1D4 4	F=A
FFFprofilec                 
   	 |j                   }|j                  }d}d|cxk  rdk  rn nd}n>d|cxk  rdk  sn d|cxk  rdk  rn nd}n |dkD  rt        dd|dz
  dz  z
        }n|d	z  }d}d|cxk  rd
k  rn nd}n>d|cxk  rdk  sn d
|cxk  rdk  rn nd}n |dkD  rt        dd|dz
  dz  z
        }n|dz  }|dz  |dz  z   |_        |d   }|d   }|dkD  r|dkD  rdnd}	|dkD  r t	        |dz  d      }
|
dz  |	dz  z   |_        nt        dd	|dz  z         }
|
dz  |_        |d   }|d   }|d   dz  }|d   d	z  d	z   }|d   }d}d|cxk  xr dk  nc xr |dkD  xr |dkD  }|rK|dz  }|dk  r|dz  }|dkD  r|dz  }t        j                  d |j                   d!|d"d#|dz  d$d%|d$d&	       |r7|d'k  r2|d	z  }t        j                  d(t        j                  d)d*       d+       |r|dz  }|dk  r|dz  }|d,   }d-|cxk  rdk  rn n|dz  }t	        |d      |_        |d   }|d.   }|d/   }|j                  d0k(  r'|dkD  r|dkD  rd|_        n|d1kD  rd|_        nd2|_        nd|_        d}d|cxk  rdk  r	n n|d3z  }nNd|cxk  rd4k  r	n n|dz  }n:d4|cxk  rd	k  sn d5|cxk  rdk  r	n n|d	z  }nd	|cxk  rd5k  r	n n|dz  }n|dz  }|d-k  r|dz  }nd-|cxk  rdk  r	n n|d	z  }n|dz  }t	        |d      |_        |j                   }dt	        d-t        d6|dz              z   }d|z
  }||z  }||z  }||d7z   z  }t	        |dz  d      |_        |j                  d-z  |j
                  d8z  z   |j                  d8z  z   |j                  d9z  z   |j                  d:z  z   |j                  d;z  z   }	 dd<lm} t%        |d=d>      }t%        |d?d>      } d@}!| *t'        j(                         | z
  j+                         }"|"dAk  }!|X|!rV|dBk  r&|dCz  }|j,                  j/                  dD|dEdF       nh|dGk  rc|dHz  }|j,                  j/                  dI|dEdJ       n=|;|!s9|j,                  j/                  dKdLt1               v rt3        "dz        ndM dN       |j                   dz  |_        |j                  dkD  |j
                  dkD  |j                  dkD  |j                  dkD  |j                  dkD  g}#t9        |#      t;        |#      z  dz  |_        |S # t4        $ r Y w xY w# t4        $ r"}$t        j?                  dO|$        Y d>}$~$yPd>}$~$ww xY w)Qu  
        Calcule le score d'opportunité final (0-100)
        
        Pondération:
        - Volatilité prédite: 30%
        - Momentum actuel: 20%
        - Pattern quality: 20%
        - Trend alignment: 15%
        - Entry timing: 10%
        - Risk/Reward: 5%
        r   r   g      @r   r   g      @F   rj   ru   g       @r   g      $@      g?333333?r   r      ffffff?               r   -   gMbP?r   #   g      ?u   🎯 u   : CREUX_REBOUND détecté (RSI=z.0fz, Mom=.2fz%, Vol=)r   u   🔥 r   UNKu   : SQUEEZE_WAITING détectérk   rS         r   g(   P   *   r   gɿg{Gz?rU   g333333?g?g?)AIPredictor_btc_momentumN_last_market_checkFiX  g      g?zBTC crash (z+.2fu   %) — score pénalisé -45%g333333ӿg      ?zBTC faible (u   %) — score pénalisé -25%u   BTC data obsolète (>_btc_age?u   min) — pénalité ignoréeu%   ❌ Erreur calcul opportunity score: r   ) r   r   maxr!   minr"   r   r   r   r   r   r#   r    r$   r%   r&   ai_predictorr  getattrr   rM   r   r-   appenddirrA   r   r(   sumr   r)   r   )%rD   r   r   re   rf   vol_score_6hvol_score_24hr   r   momentum_alignmomentum_strengthr   r   r   r   r   r#   is_creux_reboundr   r   r   r   timing_scoreexpected_movereward_ratio
risk_ratioriskrewardrr_ratiofinal_score_AIP
_btc_mom_s_btc_last_check_btc_data_freshr  confidence_factorsr   s%                                        rE   calculate_opportunity_scorez1AIOpportunitySelector.calculate_opportunity_score  s   J	 44F66GLf##"$$f(;(;!#"1bFSLB+>&>?%{Mg$$ #%#%w)>$)> "4 #ArWt^q,@'@ A '"(4s(:]S=P(PG$ "!J!!J#->j1nQ1N A~$'
S(8#$>!):S)@>TVCV)V& %(2
S0@+@$A!):S)@& ""J"2,K#B<",L2,#b(C#B<LM cR #U"#s" 
  #"9!R'M#%!Q&MeGNN#33RSVWZR[[ablmpbpqtauu|  ~J  KN  }O  OP  Q  R lQ.#eKOOHe$D#EE`ab # a# #2,Kk(S(#$'s$;G!  |H"2,K#B<L**d2a<K!O*-G'%*,G'*,G'&(# L SB"cR"cR2??"cB"" S "*s*""),\3)?G&
 $;;MS#dJO*D!EEL|+J :-D"\1F-H(+HrM3(?G% ((4/&&-.%%,- ##d*+ **T1	2
 ))D01 <$T?DA
")$0Dd"K"'". ( @OOQH&.nO)o!D(#t+((//+j=NNj0kl#d*#t+((//,z$>OOk0lm+O$$++.CXbfifkXkCQSDTqtCu  vR  -S  T
 &-%D%Ds%JG" ((2-&&+%%*##b(**R/" "%%7!83?Q;R!RUX!XG!  $  	LL@DE	s>   N<T0 ?C%T! $A<T0 !	T-*T0 ,T--T0 0	U9UUr   c                 V   t        |      }	 | j                  |      }| j                  |      \  }}}||_        ||_        ||_        |dz  |_        |dz  |_        | j                  ||      }||_	        |j                  dkD  r |j                  j                  d|dd       |j                  dkD  r|j                  j                  d       |j                  dkD  r|j                  j                  d	       |j                  d
kD  r|j                  j                  d|        |dkD  r|j                   j                  d       |j"                  dk  r|j                   j                  d       |S # t$        $ r-}	t&        j)                  d| d|	        d|_	        Y d}	~	|S d}	~	ww xY w)u8   Analyse une crypto et génère son profil d'opportunitér   r   r   r   u!   Excellente volatilité prédite: .1fz% (6h)u   Momentum fort et cohérentu   Pattern favorable détectér  u   Tendance alignée g      @u)   Volatilité très élevée - Risque accruru   z*Confiance faible - Signaux contradictoiresu   ❌ Erreur analyse z: r   N)r   r   r   r   r   r    r   r   r&  r'   r!   r,   r  r"   r#   r$   r-   r)   r   r   r   )
rD   r   r   r   r   re   rf   r4   r'   r   s
             rE   analyze_cryptoz$AIOpportunitySelector.analyze_cryptop  s   $F3!	*,,[9H *.)A)A()K&FGY.4G+/6G,*3G'(.G%)03G& !% @ @( S(9G% ''",&&)J6RU,V\']^%%*&&'CD$$r)&&'DE""R'&&);I;'GH|  ''(ST!!B&  ''(TU 	  	*LL.vhb<=()G%%		*s   E"E2 2	F(;"F##F(	watchlistc                    t         j                  dt        |       d       t        j                         }g }|D ]I  }|j	                  dd      }|s| j                  ||      }|j                  |       || j                  |<   K |j                  d d       t        |d      D ]/  \  }}||_
        |t        k  xr |j                  t        k\  |_        1 t        d	 |D              }t!        j"                  |D 	cg c]  }	|	j                   c}	      }
|r|d
   j                  nd
}t        j                         |z
  }t         j                  d|dd       t         j                  d| dt        |       d       t         j                  d|
dd       t         j                  d|dd|r|d
   j$                  nd d       t'        j(                         | _        | j-                  |       |S c c}	w )u  
        Sélectionne les TOP opportunités de la watchlist
        
        Args:
            watchlist: Liste des cryptos avec leurs données
        
        Returns:
            Liste des OpportunityProfile triés par score (meilleurs en premier)
        u   🔍 Analyse de u)    cryptos pour sélection opportunités...r    c                     | j                   S )N)r'   )ps    rE   <lambda>z<AIOpportunitySelector.select_opportunities.<locals>.<lambda>  s    A$7$7 rG   T)keyreverser   c              3   :   K   | ]  }|j                   sd   yw)r   N)r+   ).0r/  s     rE   	<genexpr>z=AIOpportunitySelector.select_opportunities.<locals>.<genexpr>  s     ?1AJJQ?s   r   u   ✅ Sélection terminée en r   sz	   - TOP /u    cryptos sélectionnéesz   - Score moyen: r)  z/100z   - Meilleur score: z/100 (zN/Ar  )r   r   r   timer   r*  r  r|   sort	enumerater*   TOP_N_CRYPTOSr'   MIN_OPPORTUNITY_SCOREr+   r  r   meanr   r   rM   r}   _save_opportunities)rD   r+  
start_timeprofilesr   r   r   iselected_countr/  	avg_score	top_scoreelapseds                rE   select_opportunitiesz*AIOpportunitySelector.select_opportunities  s    	&s9~&66_`aYY[
 $ 	1K __Xr2F))&+>GOOG$)0Dv&	1 	7F $Ha0 	kJAwGL !] 2 iw7P7PTi7iG	k
 ???GG(CQQ00CD	5=HQK111	))+
*273-qABi/qX?WXY(3t<=+Ic?&W_!ASASej@kklmn#<<>  * Ds   >G5c                     | j                   j                         D cg c]  \  }}|j                  s| c}}S c c}}w )u-   Retourne la liste des symboles sélectionnés)r|   itemsr+   )rD   r   r   s      rE   get_selected_symbolsz*AIOpportunitySelector.get_selected_symbols  s1    .2.@.@.F.F.H]?67GL\L\]]]s   ;;c                 8    | j                   j                  |      S )u0   Récupère le profil d'opportunité d'un symbole)r|   r   )rD   r   s     rE   get_opportunity_profilez-AIOpportunitySelector.get_opportunity_profile  s    !!%%f--rG   r@  c                    	 t        j                         j                         t        t        |D cg c]  }|j                          c}d}t        t        d      5 }t        j                  ||d       ddd       t        j                  dt                y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   Sauvegarde les opportunités)r}   top_n	min_scorer|   wr   )indentNu"   💾 Opportunités sauvegardées: u%   ❌ Erreur sauvegarde opportunités: )r   rM   r=   r;  r<  rF   openOPPORTUNITY_FILEjsondumpr   r   r   r   )rD   r@  r/  datafr   s         rE   r>  z)AIOpportunitySelector._save_opportunities  s    	F'||~779&27?!@!!))+!@	D &, -		$!,- KK<=M<NOP "A- -
  	FLL@DEE	Fs@   /B, B
B, B 6$B, B,  B)%B, ,	C5CCc                 8   t         j                  j                  t              sg S 	 t	        t        d      5 }t        j                  |      }ddd       g }j                  dg       D ]  }t        |d         }|j                  di       }|j                  dd      |_	        |j                  d	d      |_
        |j                  d
d      |_        |j                  dd      |_        |j                  dd      |_        |j                  di       }|j                  dd      |_        |j                  dd      |_        |j                  dd      |_        |j                  dd      |_        |j                  dd      |_        |j                  dd      |_        |j                  dd      |_        |j                  dd      |_        |j                  dd      |_        |j                  dd      |_        |j                  dd      |_        |j                  dg       |_        |j                  dg       |_        |j7                  |       || j8                  |j:                  <    t=        j>                  |j                  dt=        j@                         jC                                     | _"        tF        jI                  dtK        |       dt                |S # 1 sw Y   xY w# tL        $ r$}tF        jO                  d |        g cY d}~S d}~ww xY w)!u&   Charge les opportunités sauvegardéesrNr|   r   r(  r;   r0   r   r1   r2   r3   r4   r   r<   r5   r6   r7   r8   r9   r:   r'   r(   r)   r*   r+   Fr,   r-   r}   u   ✅ u     opportunités chargées depuis u%   ❌ Erreur chargement opportunités: )(r   r   r   rR  rQ  rS  r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r  r|   r   r   fromisoformatrM   r=   r}   r   r   r   r   r   )	rD   rV  rU  r@  opp_datar   predsr<   r   s	            rE   load_opportunitiesz(AIOpportunitySelector.load_opportunities  s   ww~~./I+	&, $yy|$ H HH_b9 =,HX4FG !]B727))OQ2O/3899=Mq3Q0,1IIi,C)-2YYz1-E*.3iiY.O+ "h3+1::lA+F()/J)B&(.

9a(@%&,jj!&<#-3ZZ-J*,2JJ}a,H),4LL9La,P))16F)J&%-\\,%B"'||FA6#+<<
E#B "*,,y""=#+<<
B#? (5<""7>>2;=>  (55dhh}hllnNfNfNh6ijDKK$s8}o-MN^M_`aOM$ $P  	LL@DEI	s5   K, KJK, K)$K, ,	L5LLLN)rH   rI   rJ   rK   rX   r   rB   r   r   r   ndarrayr   r   r>   r@   r   r   r&  r*  r   rF  rI  r   rK  r>  r\  rN   rG   rE   r   r      s   EL$*?t ?I2D I2RZZ I2V&<BJJ &<5sAR;S &<PV3E VQSQ[Q[ V`e Vp'S 't '@R 'R.d4j .TBT=U .`^d3i ^.c .h?Q6R .FD1C,D F$0D);$< 0rG   r.   c                  .    t         
t               a t         S )u=   Récupère l'instance singleton du sélecteur d'opportunités)_opportunity_selectorr   rN   rG   rE   get_opportunity_selectorr`    s     $ 5 7  rG   __main__u!   ✅ AI Opportunity Selector prêtz   - Device: z   - PyTorch disponible: z   - TOP N cryptos: z   - Score minimum: )3rK   numpyr   r   r   typingr   r   r   r   rS  r   loggingdataclassesr	   r
   r8  basicConfigINFO	getLoggerr   r~   r   GPU_NAMErY   rp   torch.nntorch.nn.functional
functionalrn   set_num_threadsset_num_interop_threadsRuntimeErrorr   is_availableget_device_namer   ImportErrorrR  r   r;  r<  r   ModulerP   r   r_  r`  rH   selectorprintrN   rG   rE   <module>rv     s  *  ( . .  	  (    ',, '			2	3 		##E!%%%a( zz ::--a0H
STHI +    :
 :
 :
z r~%.		 %.P `	 `	H  !"7 ! z')H	-/	M&
"#	%o%6
78	 
01	 !6 7
89 _    
KKNOOs7   +%F F #A!F FF FF F98F9