
    i6                     x    d Z ddlZddlmZmZmZmZ ddlZ ej                  d      Z
 G d d      ZdadefdZy)u   
Ensemble Predictor - Combine plusieurs modèles ML pour améliorer la précision
Vote majoritaire entre LSTM, GBM, et autres modèles
    N)DictListOptionalTupleEnsemblePredictorc                      e Zd ZdZd Z	 	 ddee   dee   dededef
d	Z	d
ededefdZ
dej                  defdZdej                  defdZdej                  dej                  defdZdeeeef      deeef   fdZdej                  dedefdZddej                  dedefdZddej                  dedefdZdej                  defdZdej                  dej                  dej                  fdZdedefdZy)r   u   
    Combine plusieurs modèles de prédiction par vote
    
    Modèles:
    - LSTM (existant dans ai_predictor.py)
    - Gradient Boosting (simplifié)
    - Linear Regression
    - Moving Average Crossover
    c                 F    ddddd| _         t        j                  d       y )Ng?g      ?g?g333333?lstmtrendmomentumvolumeu/   ✅ Ensemble Predictor initialisé (4 modèles))models_weightsloggerinfo)selfs    ./ensemble_predictor.py__init__zEnsemblePredictor.__init__   s'    	
 	EF    Npricesvolumeslstm_predictionlstm_confidencereturnc                    |rt        |      dk  rdddi dS t        j                  |      }|rt        j                  |      nt        j                  t        |            }||| j	                  ||      }ndddd}| j                  |      }| j                  |      }	| j                  ||      }
| j                  || j                  d   f|| j                  d	   f|	| j                  d
   f|
| j                  d   fg      \  }}|d   | j                  d   z  |d   | j                  d	   z  z   |	d   | j                  d
   z  z   |
d   | j                  d   z  z   }|dk\  rd}n|dk\  rd}n
|dk\  rd}nd}|t        |d      |t        |d      |||	|
dt        d |df|df|	df|
dffD              t        d |df|df|	df|
dffD              t        d |df|df|	df|
dffD              ddS )us  
        Prédiction par ensemble de modèles
        
        Args:
            prices: Historique de prix
            volumes: Historique de volumes
            lstm_prediction: Prédiction LSTM (0=baisse, 1=neutre, 2=hausse)
            lstm_confidence: Confiance LSTM (0-100)
            
        Returns:
            Dict avec prédiction finale et détails
              2   WEAK)
prediction
confidence	consensusdetailsr   )voter!   weightr   r   r   r   r!   g333333?VERY_STRONGgffffff?STRONGg?MODERATE   r
   c              3   8   K   | ]  \  }}|d    dk(  sd  yw)r$   r   r   N .0v_s      r   	<genexpr>z5EnsemblePredictor.predict_ensemble.<locals>.<genexpr>p   5       GDAqwxy  xA  EF  xFa  G   c              3   8   K   | ]  \  }}|d    dk(  sd  yw)r$   r   Nr+   r,   s      r   r0   z5EnsemblePredictor.predict_ensemble.<locals>.<genexpr>q   r1   r2   c              3   8   K   | ]  \  }}|d    dk(  sd  yw)r$   r)   r   Nr+   r,   s      r   r0   z5EnsemblePredictor.predict_ensemble.<locals>.<genexpr>r   r1   r2   )baisseneutrehausse)r    r!   r"   consensus_strengthr#   votes_summary)lennparrayones
_lstm_vote_trend_model_momentum_model_volume_model_aggregate_votesr   roundsum)r   r   r   r   r   prices_arrayvolumes_array	lstm_vote
trend_votemomentum_votevolume_votefinal_predictionr8   weighted_confidencer"   s                  r   predict_ensemblez"EnsemblePredictor.predict_ensemble"   s    Vr) #	  xx'-4)"''#f+:N &?+FII!""BI &&|4
 ,,\: ((}E 04/D/D++F34,,W56D//
;<$--h78	F
 0,, l#d&9&9&&AA|$t':':7'CCD,'$*=*=j*IIJ %(;(;H(EEF 	 %%I4' I4'"II + 3Q7""'(:A">!#)%	   Gi^j!_}^_N`cnpqbr,s  G  G  Gi^j!_}^_N`cnpqbr,s  G  G  Gi^j!_}^_N`cnpqbr,s  G  G
 	
r   r    r!   c                     ||ddS )u   Vote du modèle LSTMLSTMr$   r!   modelr+   )r   r    r!   s      r   r>   zEnsemblePredictor._lstm_votev   s     $
 	
r   c           	      :   t        |      dk  rddddS | j                  |d      }| j                  |d      }||kD  rd}n
||k  rd	}nd}| j                  |      }|d
kD  rd}n|dkD  rd}n
|dkD  rd}nd
}||dt        |d      t        |d      t        |d      dS )u~   
        Modèle de tendance (EMA crossovers + ADX)
        
        Returns:
            Dict avec vote et confiance
        r   r   r   TrendrP   	      r)   r   (   U      F      7      )r$   r!   rQ   adx	ema_shortema_long)r:   _ema_simple_adxrC   )r   r   r^   r_   trend_directionr]   r!   s          r   r?   zEnsemblePredictor._trend_model~   s     v;R'BB IIfa(	99VR( xO!OO v& 8J2XJ2XJJ $$a=y!,h*
 	
r   c           	         t        |      dk  rddddS | j                  |d      }| j                  |d      }| j                  |d      }||z
  }| j                  |d	d
       }d}d}|dk  r|dz  }n
|dkD  r|dz  }|dkD  r|dz  }n
|dk  r|dz  }|dk  r|dz  }n
|dkD  r|dz  }||kD  rd}	d|dz  z   }
n||kD  rd}	d|dz  z   }
nd}	d}
|	t	        d|
      dt        |d      t        |d      t        |d      dS )u<   
        Modèle momentum (RSI + MACD + Stochastic)
        r   r   r   MomentumrP            iNr      rY   P   r)   <   
   _   r\   )r$   r!   rQ   rsimacd
stochastic)r:   _calculate_rsir`   _stochasticminrC   )r   r   rm   ema12ema26rn   stochbullish_signalsbearish_signalsr$   r!   s              r   r@   z!EnsemblePredictor._momentum_model   sg    v;R*EE !!&"- 		&"%		&"%u}   .  8q O2Xq O !8q OAXq O 2:q ORZq O _,D34J.D34JDJ b*-a=$Nq/
 	
r   c                    t        |      dk  st        |      dk  rddddS | j                  ||      }|d   |d   kD  rdnd	}t        j                  |d
d       }t        j                  |dd
       }||dz  kD  }|d   |d   z
  |d   z  }|dk(  r|dkD  r	d}	|rdnd}
n5|d	k(  r|dk  r	d}	|rdnd}
n"|dk(  r
|dk  rd}	d}
n|d	k(  r
|dkD  rd}	d}
nd}	d}
|	|
d||dS )u;   
        Modèle volume (OBV + Volume Price Trend)
        r   r   r   VolumerP   iUPDOWNNig333333?r   r)   K   A   rY   )r$   r!   rQ   	obv_trendvolume_increasing)r:   _calculate_obvr;   mean)r   r   r   obvr   
recent_vol	older_volvol_increasingprice_trendr$   r!   s              r   rA   zEnsemblePredictor._volume_model   s6    v;s7|b0R(CC !!&'2Gc#h.DF	 WWWRS\*
GGGCO,	#i#o5 bzF3K/6#;> qD-2J& [1_D-2J$;?DJ& [1_DJDJ $"!/
 	
r   weighted_votesc                     dddd}|D ]"  \  }}|d   }|d   dz  }||xx   ||z  z  cc<   $ t        ||j                        }t        |j                               }|dkD  r||   |z  nd}	||	fS )	u|   
        Agrège les votes pondérés
        
        Returns:
            (prediction finale, force du consensus)
        g        )r   r   r)   r$   r!   d   )keyr   gQ?)maxgetrD   values)
r   r   scores	vote_dictr%   r$   r!   rK   total_scorer8   s
             r   rB   z"EnsemblePredictor._aggregate_votes  s     SS)!/ 	0IvV$D"<036J 4LFZ//L	0 v6::6 &--/*GRUVV$45C\`!333r   periodc                     t        |      |k  rt        j                  |      S d|dz   z  }t        j                  |d|       }||d D ]  }||z  |d|z
  z  z   } |S )zCalcule EMAr)   r   N)r:   r;   r   )r   r   r   
multiplieremaprices         r   r`   zEnsemblePredictor._ema.  sr    v;776?"&1*%
ggfWfo&FG_ 	BE:%#Z*@AC	B
r   c                    t        |      |dz   k  ryg }g }t        dt        |            D ]X  }||   ||dz
     z
  }||dz
     ||   z
  }|j                  ||kD  r|dkD  r|nd       |j                  ||kD  r|dkD  r|nd       Z t        j                  || d       }t        j                  || d       }	||	z   dk(  ryt        ||	z
        ||	z   z  dz  }
t        d|
      S )u   ADX simplifiér   r   r   Nr   )r:   rangeappendr;   r   absrr   )r   r   r   upsdownsiupdownavg_upavg_downr]   s              r   ra   zEnsemblePredictor._simple_adx8  s   v;!#q#f+& 	@AVAaC[(B!A#;*DJJR$Y26rq9LLtaxQ?		@ fWX'775&?+H!&8#$(9:S@3}r   c                    t        |      |dz   k  ryt        j                  |      }t        j                  |dkD  |d      }t        j                  |dk  | d      }t        j                  |d|       }t        j                  |d|       }t        |t        |            D ]$  }||dz
  z  ||   z   |z  }||dz
  z  ||   z   |z  }& |dk(  ry||z  }	ddd|	z   z  z
  }
|
S )zCalcule RSIr   r   r   Nr   )r:   r;   diffwherer   r   )r   r   r   deltasgainslossesavg_gainavg_lossr   rsrm   s              r   rp   z EnsemblePredictor._calculate_rsiN  s    v;!#!VQ/&1*vgq1775&>*776'6?+vs6{+ 	FA FQJ/%(:fDH FQJ/&);vEH	F q= SAF^$
r   c                     t        |      dk  ryt        j                  |      }t        j                  |      }|d   }||k(  ry||z
  ||z
  z  dz  S )zCalcule Stochasticr)   r   rz   r   )r:   r;   r   rr   )r   r   highlowcurrents        r   rq   zEnsemblePredictor._stochasticf  sU    v;?vvf~ffVn*3;34#:.#55r   c                    t        j                  t        |            }|d   |d<   t        dt        |            D ]M  }||   ||dz
     kD  r||dz
     ||   z   ||<   #||   ||dz
     k  r||dz
     ||   z
  ||<   C||dz
     ||<   O |S )zCalcule OBVr   r   )r;   zerosr:   r   )r   r   r   r   r   s        r   r   z EnsemblePredictor._calculate_obvq  s    hhs6{#Aq#f+& 	"Aay6!A#;&QqSGAJ.AVAaC[(QqSGAJ.AQqSA	" 
r   ensemble_resultc                 |    |j                  dd      }|j                  dd      }|dk7  ry|dk(  ry|d	k(  ry
|dk(  ryy)u   
        Calcule un bonus de score basé sur la force du consensus
        
        Args:
            ensemble_result: Résultat de predict_ensemble
            
        Returns:
            Bonus (0-20 points)
        r"   r   r    r   r)   r   r&   r   r'   rZ   r(   rk   )r   )r   r   r"   r    s       r   get_ensemble_bonusz$EnsemblePredictor.get_ensemble_bonus~  sX     $''V<	$((q9
 ?%("*$r   )NNN)re   )__name__
__module____qualname____doc__r   r   floatintr   rM   r>   r;   ndarrayr?   r@   rA   r   rB   r`   ra   rp   rq   r   r   r+   r   r   r   r      s   G LPNRR
tE{ R
T%[ R
),R
FKR
W[R
h
S 
e 
 
*
2:: *
$ *
X:
bjj :
T :
x*
BJJ *
 *
 *
X4tE$+4F/G 4ERUW\R\L] 482:: s u "** c 5 ,RZZ  e 0	6"** 	6 	6RZZ "**  $ 5 r   r   c                  .    t         
t               a t         S )z3Retourne l'instance globale de l'ensemble predictor)_ensemble_predictorr   r+   r   r   get_ensemble_predictorr     s     "/1r   )r   numpyr;   typingr   r   r   r   logging	getLoggerr   r   r   r   r+   r   r   <module>r      sM   
  . . 			.	/I IZ   1 r   