
    iUl                        d 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
 ddlZddlZddlZddlZddlZddlmZ ddlmZmZmZmZmZmZmZ ddlmZ dd	l m!Z!m"Z"m#Z#  ejH                  d
e%       ejL                  jO                  ejL                  jP                          ee)      jT                  Z+e+dz  Z,e+dz  Z-e-dz  Z. G d d      Z/	 	 	 	 	 ddej`                  de1de1de1de1de2de3fdZ4y)u  
SPY Optimizer — Signal Classifier
Modèle ML qui prédit si un signal de surge détecté par le SPY sera rentable.

Architecture:
  - Ensemble LightGBM + XGBoost avec stacking
  - Optuna pour l'auto-tuning des hyperparamètres
  - Walk-forward validation (entraîne sur passé, valide sur futur)
  - Recalibration quotidienne adaptative

Le modèle apprend à filtrer les faux signaux (INSTANT_REVERSAL, HARD_SL)
en se basant sur les conditions de marché au moment de la détection.
    N)datetimetimezone)Path)Optional)TimeSeriesSplit)accuracy_scoreprecision_scorerecall_scoref1_scoreroc_auc_scoreclassification_reportconfusion_matrix)LabelEncoder)FEATURE_COLUMNSSURGE_TYPESbuild_dataset_from_tradesignore)categorymodelsdata	klines_1mc                       e Zd ZdZd Zd Zd%dej                  dede	j                  fdZ	 	 	 d&dej                  d	ed
ededef
dZd'dededefdZdee   dee   fdZdedefdZdedefdZde	j                  de	j                  dej                  defdZedefd       Zedefd       Zede	j                  de	j                  de	j                  dej                  def
d       Zded efd!Zd(d"ee   fd#Zed(d"ee   dd fd$       Zy))SignalClassifieru   
    Ensemble classifier qui prédit la probabilité qu'un signal SPY soit rentable.
    
    Combine LightGBM (rapide, bon sur tabular) + XGBoost (robuste, bonne généralisation)
    avec un méta-modèle logistique pour le stacking.
    c                     d | _         d | _        t        j                         | _        t               | _        d| _        i | _        d| _	        i | _
        d | _        y )NF      ?)	lgb_model	xgb_modelr   copyfeature_columnsr   surge_encoder
is_trainedtraining_statsoptimal_thresholdfeature_importancedeep_predictor)selfs    B/home/ubuntu/crypto_trading_bot/spy_optimizer/signal_classifier.py__init__zSignalClassifier.__init__6   sR    .335)^ !$"$"    c                     | j                   y	 ddlm}  |       | _         | j                   j                  sd| _         yy# t        $ r
 d| _         Y yw xY w)uI   Charge le modèle LSTM si disponible (entraîné sur GPU, inference CPU).Nr   )DeepPredictor)r%   deep_inferencer+   	is_loaded	Exception)r&   r+   s     r'   _load_deep_predictorz%SignalClassifier._load_deep_predictorA   sV    *	'4"//D&&00&*# 1 	'"&D	's   /A   AAdffit_encoderreturnc                 n   || j                      j                         }|j                  d      }|r#| j                  j	                  t
        dgz          |d   j                  d      }t
        D ]   }||k(  j                  t              |d| <   " |j                  |j                  j                         fS )u0   Prépare la matrice de features pour le modèle.r   UNKNOWN
surge_typesurge_)r   r   fillnar    fitr   astypeintvaluescolumnstolist)r&   r0   r1   X	surge_colsts         r'   _prepare_featuresz"SignalClassifier._prepare_featuresM   s    t##$))+HHQK "";)#<=|$++I6	 	=B )R77<Ardm	= xx))+++r)   datasetoptimize_hyperparamsn_optuna_trialsverbosec           	      
   t        |      dk  rt        dt        |       d      |j                  d      j                  d      }|d   j                  }| j                  |d      \  }}|| _        |r|j                         }t        |      |z
  }	t        d	d
        t        d       t        d
        t        dt        |       d| d|	 d       t        d|j                  d           t        d|t        |      z  dz  dd       t        t        |      dz        }
|d|
 ||
d }}|d|
 ||
d }}|rt        dt        |       dt        |              |d   j                  d|
 }|d   j                  |
d }t        dt        |j                  d         dd  dt        |j                  d         dd         t        dt        |j                  d         dd  dt        |j                  d         dd         t        d z  }|j                         rQ|sOt        j                   |j#                               }|d!   }|d"   }|r~t        d#|j%                  d$d%       d&       n^|r<|rt        d'| d(       | j'                  |||||      }| j)                  |||||      }n | j+                         }| j-                         }|rt        d)       t        |      |j                         z
  t/        |j                         d      z  }t1        j2                  ||      }t1        j2                  |||*      }i |d+d,d|d-d.}t1        j4                  d/      g}t1        j6                  ||d0|gt1        j8                  d      g|1      | _        t=        j>                  |||2      }t=        j>                  |||2      }i |d3d,|d-dd4}t=        j6                  ||d0|d5fgdd67      | _         | j:                  jC                  |      }| j@                  jC                  |      }d8|z  d8|z  z   }| jE                  |||j                  |
d       | _#        || jF                  k\  jI                  t              } | jK                  || ||j                  |
d       }!| j:                  jM                  d9:      }"tO        tQ        ||"            | _&        d| _)        tU        jV                  tX        jZ                        j]                         t        t        |            t        t        |            |!t_        | jF                        ||d;| _0        |r| jc                  |!|       |!S )<u  
        Entraîne l'ensemble avec walk-forward validation.

        Args:
            dataset: DataFrame issu de build_dataset_from_trades()
            optimize_hyperparams: utiliser Optuna pour tuner les hyperparamètres
            n_optuna_trials: nombre d'essais Optuna
            verbose: afficher la progression

        Returns:
            dict avec les métriques de performance
        2   u   Pas assez de données: z trades (min: 50)
entry_timeTdroptarget_profitable)r1   
<============================================================u      Signal Classifier — Trainingz  Samples:  (z profitable, z
 perdants)z  Features:    z  Balance: d   .1fz	% positif      ?N	  Train: z | Validation: z  Train period: r   
       → z  Valid period: zoptimized_params.json
lgb_params
xgb_paramsu)   
  🎮 Using GPU-optimized params (AUC: ensemble_auc?)u   
  🔍 Optuna optimization (z trials)...u#   
  🏋️ Training final models...	referencebinaryauc*   )	objectivemetric	verbosityscale_pos_weightseedperiodi  num_boost_round
valid_sets	callbacks)labelfeature_namesbinary:logistic)ra   eval_metricrd   re   rc   valFri   evalsearly_stopping_roundsverbose_evalr   gain)importance_type)
trained_attrain_samplesval_samplesmetricsr#   rW   rX   )2len
ValueErrorsort_valuesreset_indexr;   rA   final_feature_namessumprintshaper:   ilocstr
MODELS_DIRexistsjsonloads	read_textget_optimize_lgb_optimize_xgb_default_lgb_params_default_xgb_paramsmaxlgbDatasetlog_evaluationtrainearly_stoppingr   xgbDMatrixr   predict_optimize_thresholdr#   r9   _compute_metricsr$   dictzipr!   r   nowr   utc	isoformatfloatr"   _print_results)#r&   rB   rC   rD   rE   yr>   	col_namesposneg	split_idxX_trainX_valy_trainy_valtrain_dates	val_datesgpu_params_path
gpu_paramsbest_lgb_paramsbest_xgb_params
pos_weight	lgb_trainlgb_valrW   rk   dtraindvalrX   lgb_predxgb_predensemble_predy_predrz   lgb_imps#                                      r'   r   zSignalClassifier.train]   sv   & w<"6s7|nDUVWW %%l3??T?J'(//--g4-H9#, %%'Ca&3,CBvh- 46VHKAxr#mC5
KLL-.KCF
3s39=> Gt+,	:I)*:I)*Ic'l^?3u:,GH!,/44Zi@K-229:>I$S)9)9!)<%=cr%B$C5[M]M]^`MaIbcfdfIgHhij$S):%;CR%@$As9>>Z\K]G^_b`bGcFdef %'>>!!#,@O$=$=$?@J(6O(6OB:>>R`beCfBgghij!66G{ST"00'5%Q`aO"00'5%Q`aO"668O"668O 8: 'lW[[]2c'++-6KK
KK1	++eUi@

! *

 ''q12		 y))"-:	:	
 WG9M{{5YG

*  *

  %=/"$
 >>))%0>>))$/hx7 "&!9!9-PWP\P\]f]gPh!i  4#9#99AA#F''v}gllS\S]F^_ ..33F3K"&s9g'>"?",,x||4>>@ W.s5z?!&t'='=!>))
 3r)   Nfeaturestimestamp_msc                 8   | j                   sddddddS t        j                  |g      }| j                  |      \  }}| j                  j                  |      d   }t        j                  || j                        }| j                  j                  |      d   }	d|z  d|	z  z   }
| j                          d}| j                  r6|4|dkD  r/|j                  dd	      }| j                  j                  |||      }|r'|j                  d
      dk(  r|d   }d|
z  d|z  z   }d}n|
}d}|| j                  k\  rdnd}t        || j                  z
        | j                  z  dz  }t        |d      }t!        |      |t!        |      t!        | j                        |dS )u  
        Prédit si un signal est rentable.
        
        Si le modèle LSTM GPU est disponible ET que klines_df est fourni,
        combine LGB+XGB (tabular) avec LSTM (séquentiel) pour un ensemble hybride.

        Args:
            features: dict de features (output de compute_features_at_timestamp)
            klines_df: DataFrame klines 1m (optionnel, pour le modèle LSTM)
            timestamp_ms: timestamp en ms (requis si klines_df fourni)

        Returns:
            {
                "probability": float 0-1,
                "signal": "BUY" | "SKIP",
                "confidence": float 0-100,
                "threshold": float,
                "model_type": str,
            }
        r   BUYr   none)probabilitysignal
confidence	threshold
model_typerm   Nr5   r4   r   lstm_attentionr   g333333?g?hybrid_lgbxgb_lstmlgbxgbSKIPrP   )r!   pd	DataFramerA   r   r   r   r   r   r   r/   r%   r   r#   absminr   )r&   r   	klines_dfr   r0   r>   _r   dmatrixr   tabular_probdeep_resultr5   	deep_probprobr   r   r   s                     r'   r   zSignalClassifier.predict   s   * #&%qWZjpqq\\8*%%%b)1>>))!,Q/++at/G/GH>>))'215X~h6 	!!#9#8\A=M!lI>J--55izZK;??<8<LL#M2I%i7D-JD!J$"8"88f 6 667$:P:PPSVV
S)
 !;
+t556$
 	
r)   features_listc                 J    |D cg c]  }| j                  |       c}S c c}w )u*   Prédit pour une liste de signaux (batch).)r   )r&   r   fs      r'   predict_batchzSignalClassifier.predict_batch/  s    )67AQ777s    n_trialsc                     t              j                         z
  t        j                         d      z  fd}t        j                  d      }|j                  ||dd       |j                  S )NrO   c                    ddd| j                  dddd      | j                  d	d
d      | j                  ddd      | j                  ddd      | j                  ddd      | j                  ddd      | j                  dddd      | j                  dddd      | j                  ddd      d}t        j                  	      }t        j                  
|      }t        j                  ||d|gt        j
                  d      t        j                  d !      g"      }|j                        }t        
|      S )#Nr^   r_   rV   learning_rate{Gz?333333?Tlog
num_leaves      	max_depth      min_child_samples   rG   	subsampler         ?colsample_bytree	reg_alpha:0yE>      $@
reg_lambdamin_split_gain        )ra   rb   rc   rd   r   r   r   r   r   r   r   r   r   r\        r   rf   rh   )	suggest_floatsuggest_intr   r   r   r   r   r   r   )trialparams	train_setval_setmodelpredr   r   r   r   r   s         r'   ra   z1SignalClassifier._optimize_lgb.<locals>.objective8  sG   %$.!&!4!4_dCUY!4!Z#//b#F"..{ArB%*%6%67JAr%R"00c3G$)$7$78JCQT$U"00dDd0S#11,dPT1U"'"5"56FS"QF  GW5Ikk%)DGII	 ##9--b133E3EQ3OP	E =='D --r)   maximize	direction   Fr   n_jobsshow_progress_barr{   r   r   optunacreate_studyoptimizebest_params	r&   r   r   r   r   r   ra   studyr   s	    ````   @r'   r   zSignalClassifier._optimize_lgb5  f    'lW[[]2c'++-6KK
	. 	.: ##j9y8AQVW   r)   c                     t              j                         z
  t        j                         d      z  fd}t        j                  d      }|j                  ||dd       |j                  S )NrO   c                    ddd| j                  dddd      | j                  d	d
d      | j                  ddd      | j                  ddd      | j                  ddd      | j                  dddd      | j                  dddd      | j                  ddd      d}t        j                  	      }t        j                  
      }t        j                  ||d|dfgdd       }|j                  |      }t        
|      S )!Nrn   r_   r   r   r   r   Tr   r   r   rT   min_child_weightrO      r   r   r   r   r   r   r   r   gammar   g      @)ra   ro   rd   rc   r   r   r  r   r   r   r   r  )rl   r   rp   r   Frq   )r   r   r   r   r   r   r   )r   r   r   r   r   r   r   r   r   r   r   s         r'   ra   z1SignalClassifier._optimize_xgb.<locals>.objective\  s   .$$.!&!4!4_dCUY!4!Z"..{ArB$)$5$56H!R$P"00c3G$)$7$78JCQT$U"00dDd0S#11,dPT1U,,Wc3?F [[8F;;uE2DII #e}o&("E ==&D --r)   r   r   r   Fr   r  r  s	    ````   @r'   r   zSignalClassifier._optimize_xgbY  r	  r)   
pred_probay_trueval_dfc                 >   |d   j                   }d}t        d       }t        j                  ddd      D ]e  }||k\  }|j	                         dk(  r||   j	                         }	|j	                         t        |      z  }
|
dk  rQ|	dd|
z  z   z  }||kD  sb|}|}g |S )	u   
        Optimise le seuil de décision pour maximiser le PROFIT, pas l'accuracy.
        Un trade filtré (SKIP) = 0$ de gain. Un trade passé = son PnL réel.
        target_pnl_pctr   infr   rR   r   r   g333333?)r;   r   nparanger   r{   )r&   r  r  r  
pnl_valuesbest_thresholdbest_profitr   passedprofit
trade_ratescores               r'   r   z$SignalClassifier._optimize_threshold}  s     ,-44
U|m4t4 	+I9,Fzz|q '++-FF3JD cC*$445E{"#!*	+" r)   c            	          dddddddddS )	N皙?      r  皙?皙?r   )r   r   r   r   r   r   r   r    r$  r)   r'   r   z$SignalClassifier._default_lgb_params  s&     "!# #	
 		
r)   c            	          dddddddddS )Nr  r!  r   r"  r#  r   )r   r   r  r   r   r   r   r  r$  r$  r)   r'   r   z$SignalClassifier._default_xgb_params  s&     " ! #	
 		
r)   r   y_probac                    |d   j                   }|dk(  }|dk(  }|j                         r||   j                         nd}|j                         r||   j                         nd}|j                         }	| dk(  j                         }
| dk(  |z  j                         }| dk(  j                         }| dk(  |z  j                         }t        t	        | |            t        t        | |d            t        t        | |d            t        t        | |d            t        t        | |            t        |j                               t        |j                               t        |j                         t        |       z        t        |      t        |	      t        ||	z
        t        |t        |
d      z  dz        t        |t        |d      z  dz        t        |t        |j                         d      z  dz        dS )Nr  rO   r   )zero_divisionrP   )accuracy	precisionrecallf1auc_roctrades_passedtrades_filteredr  pnl_with_filterpnl_without_filterpnl_improvementbad_trades_filtered_pctgood_trades_kept_pctwin_rate_filtered)r;   anyr   r   r   r	   r
   r   r   r:   r{   r   )r  r   r&  r  r  r  filtered
pnl_passedpnl_filteredpnl_allbad_trades_totalbad_trades_filteredgood_trades_totalgood_trades_kepts                 r'   r   z!SignalClassifier._compute_metrics  s   
 ,-44
1Q; 28Z'++-1
5=\\^z(+//1.." #aK,,. &!x7<<>#q[--/#q[F2779 nVV<=vvQOPLqIJqAB]67;< ."8<<>2

s6{ :;$Z0"'.$Z'%9:',-@3GWYZC[-[^a-a'b$)*:SARTU=V*VY\*\$]!& 3vzz|Q#77#="
 	
r)   rz   rm   c           
         t        dd        t        d       t        d        t        d| j                  d       t        d|d   d       t        d	|d
   d       t        d|d   d       t        d|d   d       t        d|d   d       t                t        d       t        d|d    d|d   |d   z           t        d|d   d       t        d|d   dd       t        d|d   dd       t        d|d    d!d       t                t        d"       t        d#|d$   d%d       t        d&|d'   d%d       t        d(|d)   d%d       t        d*       t        | j                  j	                         d+ d,-      }|d.d/ D ]5  \  }}d0t        ||d1   d2   z  d3z        z  }t        d4|d5d6| d6|d       7 y.)7u+   Affiche les résultats de manière lisible.rL      ────────────────────────────────────────────────────────────u+     📊 Résultats Validation (walk-forward)z  Seuil optimal:        z.2fz  AUC-ROC:              r-  z.3fz  Accuracy:             r)  z.1%z  Precision:            r*  z  Recall:               r+  z  F1-Score:             r,  u     📈 Impact Trading:u     Trades passés:        r.  z / r/  z  Trade rate:           r  u     Mauvais trades filtrés: r3  .0f%u     Bons trades conservés:  r4  u     Win rate filtré:      r5  rQ   u     💰 PnL Simulation:z  Sans filtre:          r1  +.2fz  Avec filtre IA:       r0  u     Amélioration:         r2  u   
  🔑 Top 15 Features:c                     | d   S )NrO   r$  )xs    r'   <lambda>z1SignalClassifier._print_results.<locals>.<lambda>  s
    1Q4 r)   T)keyreverseNr   u   █r   rO   r  z    30s )r   r#   sortedr$   itemsr:   )r&   rz   rm   
sorted_impnameimpbars          r'   r   zSignalClassifier._print_results  s<   8*o;=
()?)?(DEF();C(@AB()<S(ABC()=c(BCD():3(?@A(s(;<=&()'/*B)C3wG_bij{b|G|F}~()>s(CDE+G4M,Ns+SSTUV+G4J,KC+PPQRS)'2E*Fs)K1MN&((1E)Ft(LANO(1B)CD(IKL)'2C*DT)J!LM 	)+D3399;Y]^
#CR 	5ID##cJqM!$44r9::CDc
!C5#c34	5r)   pathc           
         |)t         j                  dd       t        t         dz        }| j                  | j                  | j
                  | j                  | j                  | j                  | j                  | j                  | j                  d	}t        |d      5 }t        j                  ||       ddd       t        d|        y# 1 sw Y   xY w)u!   Sauvegarde le modèle entraîné.NT)parentsexist_oksignal_classifier.pkl)	r   r   r   r   r    r#   r"   r$   r!   wbu     💾 Modèle sauvegardé: )r   mkdirr   r   r   r   r   r    r#   r"   r$   r!   openpickledumpr   )r&   rQ  stater   s       r'   savezSignalClassifier.save   s    <TD9z$;;<D #33#'#;#;!//!%!7!7"11"&"9"9//

 $ 	"KKq!	",TF34	" 	"s   CCc                    |t        t        dz        }t        j                  j	                  |      st        d|       t        |d      5 }t        j                  |      }ddd        |        }d   |_	        |d   |_
        |d   |_        |d   |_        |d	   |_        |d
   |_        |d   |_        |d   |_        |d   |_        |S # 1 sw Y   lxY w)u   Charge un modèle sauvegardé.NrU  u   Modèle non trouvé: rbr   r   r   r   r    r#   r"   r$   r!   )r   r   osrQ  r   FileNotFoundErrorrX  rY  loadr   r   r   r   r    r#   r"   r$   r!   )clsrQ  r   r[  r   s        r'   ra  zSignalClassifier.load  s     <z$;;<Dww~~d##&;D6$BCC$ 	#KKNE	# ,, %&7 8$)*?$@!#O4"'(;"<$%56#()=#>  .	# 	#s   CC)F)TrP   T)Nr   )N) __name__
__module____qualname____doc__r(   r/   r   r   boolr  ndarrayrA   r:   r   r   r   listr   r   r   r   r   staticmethodr   r   r   r   r   r   r\  classmethodra  r$  r)   r'   r   r   .   s   	#
',BLL ,t ,PRPZPZ ,& &*"SS #S 	S
 S 
Sj;
 ;
C ;
PT ;
z84: 8$t* 8"!c "!d "!H"!c "!d "!H**.0jjBD,,	> 

 

 

 

 

 

 $


$
$&JJ$
9;$
$
 
$
 $
L5d 54 5B5# 5*  1C  r)   r   rB   
train_daysval_days	step_daysrD   rE   r2   c                    | j                  d      j                  d      } t        j                  | d         j                  j
                  | d<   t        | d   j                               }t        |      ||z   k  rt        dt        |       d| d|       g }g }g }	g }
|r^t        dd	        t        d
       t        d| d| d| d       t        d|d    d|d    dt        |       d       t        d	        t        |t        |      |z
  dz   |      D ]  }||dz
     }||   }|t        ||z   dz
  t        |      dz
           }|t        d||z
           }| d   |k\  | d   |k  z  }| d   |k\  | d   |k  z  }| |   }| |   }t        |      dk  st        |      dk  rt               }	 |j                  |d|d       |j#                  |      \  }}|j$                  j'                  |      }t)        j*                  ||j,                        }|j.                  j'                  |      }d|z  d|z  z   }|d    j0                  }||j2                  k\  j5                  t6              }|dk(  }|d!   j0                  }|j9                         r||   j;                         nd} |j;                         }!|j9                         r||   j=                         d"z  nd}"|
j?                  tA        |      t        |      t7        |j;                               tC        |       tC        |!      tC        |"      tC        |j2                        d#       |jE                  |jG                                |jE                  |jG                                |	jE                  |jG                                |s| |!z
  }#|#dk\  rd$nd%}$t        d&| d't        |      d(d)t7        |j;                               d(d*|"d+d,| d-d.|!d-d/|#d0d1|$         tI        jJ                  |	      }	tI        jJ                  |      }tI        jJ                  |      }t;        d2 |
D              }%t;        d3 |
D              }&t;        d4 |
D              }'t;        d5 |
D              }(t;        d6 |
D              })t        |
      |'|(tC        |%      tC        |&      tC        |&|%z
        tC        |)t        t        |
      d      z  d"z        |
d7}*|rt        dd8        t        d9       t        d8        t        d:t        |
              t        d;|' d|( d<|(t        |'d      z  d"z  d=d>       t        d?|%d@dA       t        dB|&d@dA       t        dC|&|%z
  d@dA       t        dD|) dEt        |
       d|*dF   d=d>       |*S # t         $ r}|rt        d| d| d       Y d}~d}~ww xY w)Gu   
    Backteste le modèle avec walk-forward rolling window.
    Simule le recalibrage quotidien: entraîne sur les N derniers jours,
    prédit le jour suivant, avance d'un jour.

    Returns:
        dict avec les résultats cumulés
    rH   TrI   
entry_datezPas assez de jours (z) pour train=z+val=rL   rM   z  Walk-Forward BacktestrS   z	j | Val: z
j | Step: ju     Période: r   rU   rV   rN   z jours)rO   r   r   F)rC   rD   rE   u     ⚠️ Window z: train failed (r[   Nr   r   rK   r  rP   )val_daten_tradesn_passedr0  r1  r5  r   u   ✅u   ❌z  z | 3du    trades → u    passés | WR: z5.1fz	% | PnL: z+6.1fz% vs u   % | Δ=z+5.1fz% c              3   &   K   | ]	  }|d      yw)r1  Nr$  .0ws     r'   	<genexpr>z(walk_forward_backtest.<locals>.<genexpr>  s     LA23L   c              3   &   K   | ]	  }|d      yw)r0  Nr$  rw  s     r'   rz  z(walk_forward_backtest.<locals>.<genexpr>  s     F!,-Fr{  c              3   &   K   | ]	  }|d      yw)rs  Nr$  rw  s     r'   rz  z(walk_forward_backtest.<locals>.<genexpr>       =q}=r{  c              3   &   K   | ]	  }|d      yw)rt  Nr$  rw  s     r'   rz  z(walk_forward_backtest.<locals>.<genexpr>  r~  r{  c              3   8   K   | ]  }|d    |d   k\  sd  yw)r0  r1  rO   Nr$  rw  s     r'   rz  z(walk_forward_backtest.<locals>.<genexpr>  s$     h:K8LPQRfPg8g1hs   )windowstotal_tradestotal_passedtotal_pnl_without_filtertotal_pnl_with_filterr2  positive_windows_pctwindow_detailsr@  u&     📊 Résultats Walk-Forward Globauxu     Windows testées:    z  Trades total:       u
    passés (rA  z%)z  PnL sans filtre:    rC  rB  z  PnL avec filtre IA: u     Amélioration:       z  Windows positives:  /r  )&r}   r~   r   to_datetimedtdaterK  uniquer{   r|   r   ranger   r   r   r   r.   rA   r   r   r   r   r   r   r;   r#   r9   r:   r6  r   meanappendr   r   extendr=   r  array)+rB   rl  rm  rn  rD   rE   datesall_predictionsall_actualsall_pnlswindow_resultsitrain_end_dateval_start_dateval_end_datetrain_start_date
train_maskval_masktrain_dfr  clfer   r   r   r   r   r   r   r   r  pnl_valspnl_withpnl_withoutwr_withdeltasigntotal_pnl_withouttotal_pnl_withr  r  positive_windowsresultss+                                              r'   walk_forward_backtestr  /  s%     !!,/;;;FGNN7<+@ADDIIGL7<(//12E
5zJ))/E
|=TYZbYcdeeOKHN6(m')	*Yxj
9+QOPU1XJeE"I;bUGLM:s5zH4q8)D >2q1uqSX!13u:>BC QJ!78 l+/??GLDY]kDkl
L)^;@UYe@ef:&"x=2Vq  	IIhT?diIj ((0q==((/{{50G0GH==((.hx7*+223#8#88@@E1*+22-3ZZ\8F#'')qlln06

%-$$&,!N+FFJJL)$X"'"4!&ws445
 	 	}33565<<>*)*{*E!QJ5EDB~&c#f+b)9c&**,FWXZE[ \#D>8E2B%TYGZ [ -r$1 2y>2B xx!Hhh/O((;'KL^LLF~FFN=n==L=n==Lhnhh ~&$$$)*;$<!&~!6 2C!CD %&6S=PRS9T&TWZ&Z [(	G 8*o68
'N(;'<=>&|nE,zR^_bcopq_rRrsvRvwzQ{{}~&'8&>a@A&~d&;1=>'9J(J4'PPQRS&'7&8#n:M9NbQXYoQpqtPuuwxyNY  	((88H1MN	s   7V77	W WW)      rO   rG   T)5rf  r   r_  rY  warningsr   r   pathlibr   typingr   numpyr  pandasr   lightgbmr   xgboostr   r  sklearn.model_selectionr   sklearn.metricsr   r	   r
   r   r   r   r   sklearn.preprocessingr   feature_engineeringr   r   r   filterwarningsUserWarningloggingset_verbosityWARNING__file__parentPROJECT_DIRr   DATA_DIR
KLINES_DIRr   r   r:   rg  r   r  r$  r)   r'   <module>r     s    	   '        3   / W W   ; 7   V^^33 4 8n##8#
#
| |F D\\DD D 	D
 D D 
Dr)   