
    btjA                     &   S r SSKrSSKrSSKrSSKrSSKrSSKr\R                  " S5        S\R                  S'   \R                  R                  S\R                  R                  \R                  R                  \5      5      5        SSKr\R"                  " S5        SSKJrJrJrJr  SSKJr  SS	KJrJrJr  SS
KJr  SSKJr  SSKJ r J!r!J"r"J#r#J$r$  Sr%S\&S\&4S jr'S\&S\4S jr(S\&S\S-  4S jr)       SMS\&S\*S\*S\+S\+S\*S-  S\,S\,S\-4S jjr.S\-4S  jr/\0S!:X  Gak  \Rb                  " S"S#9r2\2Rg                  S$\&S%S&9  \2Rg                  S'\*SS&9  \2Rg                  S(\*SS&9  \2Rg                  S)\*SS*S+9  \2Rg                  S,S-S.S/9  \2Rg                  S0S-S1S/9  \2Rg                  S2S-S39  \2Ri                  5       r5\5Rl                  (       a6  SSK7r7\R                  Rq                  \%5      (       a  \7Rr                  " \%5        \5Rl                  (       Ga&  / S4Qr:/ r;\: H  r<\=" S5S6 35        \." \<\5R|                  \5R~                  \5R                  \5R                  (       + \5R                  S79rC\;R                  \C5        S8\C;   d  Mi  \=" S9\< S:\CS8   S; S<\CS=   S; S>\CS?   S@ SA\CSB   S@ SC35        M     \=" S5SD 35        \=" SE5        \=" SD 5        \; Hf  rES8\E;   a.  \=" S9\ES   SF SG\ES8   S; S<\ES=   S; SH\ES?   S@ SI\ESB   S@ SC35        M7  \=" S9\ER                  SSJ5      SF SK\ER                  SLSJ5       35        Mh     g\." \5R                  \5R|                  \5R~                  \5R                  \5R                  (       + \5R                  S79rC\/" \C5        gg)Nu\  
Walk-Forward Cross-Validation для MultiTimeframeMoE (v12.5).

Оценивает устойчивость модели на последовательных отрезках времени
(rolling-origin CV). Использует v12.5 архитектуру: раздельные rf_long/rf_short,
per-ticker class_weight и пороги, единый predict_all на всём df.

Запуск:
    python3 walkforward_cv.py --ticker SBER --folds 7
    python3 walkforward_cv.py --ticker SBER --folds 5 --epochs 40
    python3 walkforward_cv.py --all                   # все 14 тикеров
    Nignore3TF_CPP_MIN_LOG_LEVELtrain)_prepare_df_get_feature_cols_build_dataset_split_signals)ExpertEnsemble)TARGET_CONFIG
get_marketshould_disable_short_training)MultiOutputClassifier)RandomForestClassifier)TICKER_SHORT_WEIGHTSTICKER_LONG_WEIGHTSTICKER_THRESHOLDSDEFAULT_SHORT_WEIGHTDEFAULT_LONG_WEIGHTz/tmp/opencode/moe_cachetickerreturnc                 P    [         R                  R                  [        U  S35      $ )Nz_experts_latest.joblib)ospathjoin	CACHE_DIR)r   s    walkforward_cv.py_cache_pathr   (   s    77<<	fX-C#DEE    ensemblec                     [         R                  " [        SS9  UR                  5       UR                  UR
                  S.nSSKnUR                  U[        U 5      5        U$ )uc   Сохраняет веса экспертов в кэш для transfer learning между folds.T)exist_ok)stateexpert_names
n_featuresr   N)	r   makedirsr   
state_dictr$   r%   joblibdumpr   )r   r    cacher(   s       r   _save_expert_cacher+   ,   sR    KK	D)$$& --))E
 
KK{6*+Lr   c                     [        U 5      n[        R                  R                  U5      (       d  g SSKnUR                  U5      n[        US   US   S9nUR                  US   5        U$ ! [         a     gf = f)uF   Загружает кэш экспертов для transfer learning.Nr   r%   r$   )r%   expertsr#   )	r   r   r   existsr(   loadr   load_state_dict	Exception)r   r   r(   r*   r    s        r   _load_expert_cacher2   9   s}    vD77>>$
D!!\*.)
 	  w0 s   :A- -
A:9A:   <     n_foldsepochsval_pctmin_train_pctlimitverbosefastc                     [        XS9nUb  [        U5      S:  a  SSU  SUb  [        U5       30$ S 30$ [        U5      n	[        5       n
U
 Vs/ s H  oUR                  ;   d  M  UPM     nn[	        [        X-  5      S5      n[	        [        X-  5      S	5      n[        R                  " U [        5      n[        R                  " U [        5      n[        R                  " U S
SS.5      n[        R                  " SS5      n/ nUnUU-   nUU-   nUU	::  aG  [        U5      U:  a8  UR                  SUUU45        UnUU-   nUU-   nUU	::  a  [        U5      U:  a  M8  [        U5      S:X  a  SS0$ U(       a[  [        SU  35        [        SU	 S[        U5       S35        [        SU SU 35        [        SUS    SUS    35        [        5         / n/ n/ n/ n/ n/ n[        US5       GH|  u  nu  nnn n!U(       a3  [        SU S[        U5       SU SU SUU-
   S U  SU! SU!U -
   S!35        UR                   UU R#                  5       n"UR                   U U! R#                  5       n#[        U"5      S":  d  [        U#5      S#:  a-  U(       a$  [        S$[        U"5       S%[        U#5       S&35        M   [%        U 5      n$U$b  U$R&                  [        U5      :X  al  U(       a:  [	        US'-  S(5      n%U(       a  [        S)U% S*35        U$R)                  U"US+U%S,9  U$n&OqU(       a  [        S-U S*35        U$R)                  U"US+US,9  U$n&OFU(       a  [        S.U S/35        [+        [        U5      S09n&U&R)                  U"US+US,9  [-        U U&5        U&R/                  X5      n'[1        U'UU5      n([1        U'U U!5      n)[3        U"U(U&U5      n*[5        U 5      n+U+(       a?  U"S1   R6                  R9                  S2S5      n,U#S1   R6                  R9                  S2S5      n-Od[:        R<                  " U"S1   R6                  U"S3   R6                  /5      n,[:        R<                  " U#S1   R6                  U#S3   R6                  /5      n-[?        [        U*5      [        U,5      5      n.U*U.* S U,U.* S n,n*[?        [        W/5      [        U-5      5      n0U/U0* S U-U0* S n-n/[        U*5      S:  d  [        U/5      S(:  a.  U(       a$  [        S4[        U*5       S5[        U/5       S&35        GM3  [A        U[
        [B        45      (       a  S6US7.OUn1[E        S"S(S8S2U1S99n2U2RG                  U*U,SS2S4   5        Sn3U+(       d)  [E        S"S(S8S2S6US7.S99n3U3RG                  U*U,SS2S4   5        U2RI                  U/5      SS2S4   n4U3b+  U3RI                  U/5      SS2S4   n5U-SS2S4   n6U-SS2S4   n7O*[:        RJ                  " [        U/5      5      n5U-SS2S4   n6Sn7U4US   :  RM                  [
        5      n8U5US   :  RM                  [
        5      n9U8S:H  RO                  5       n:U8S:H  U6S:H  -  RO                  5       n;U6S:H  RO                  5       U;-
  n<U:S:  a  U;U:-  OSn=U;U<-   S:  a  U;U;U<-   -  OSn>U=U>-   S:  a  S:U=-  U>-  U=U>-   -  OSn?U9S:H  RO                  5       n@U9S:H  U7S:H  -  RO                  5       nAU7S:H  RO                  5       UA-
  nBU@S:  a  WAW@-  OSnCWAWB-   S:  a  WAUAWB-   -  OSnDWCUD-   S:  a  S:WC-  WD-  UCUD-   -  OSnEU?UE-   S;-  nFUR                  UF5        UR                  U>5        UR                  WD5        UR                  U?5        UR                  UE5        U[        U*5      [        U/5      [C        UF5      [C        U?5      [C        UE5      [C        U>5      [C        UD5      [C        U=5      [C        WC5      [C        U6S:H  RQ                  5       5      [C        U7S:H  RQ                  5       5      S<.nGUR                  UG5        U(       a*  [        S=WFS> S?U?S@ SAU>S@ SBU=S@ SCWES@ SAWDS@ SBWCS@ 35        GM|  GM     U(       d  SGUSH.$ U [        U5      [        U5      U[C        [:        RP                  " U5      5      [C        [:        RZ                  " U5      5      [C        [:        R>                  " U5      5      [C        [:        R                  " U5      5      U(       a  [C        [:        RP                  " U5      5      OSU(       a  [C        [:        RP                  " U5      5      OSU(       a  [C        [:        RP                  " U5      5      OSU(       a  [C        [:        RP                  " U5      5      OSUSI.nJUJ$ s  snf ! [R         aU  nHU(       a  [        SDU SEWH 35        SSK*nIUIRW                  5         UR                  U[Y        WH5      SF.5         SnHAHGM  SnHAHff = f)JuW  
Walk-Forward CV: rolling-origin expanding window (v12.5).

Разбивает хронологические данные на n_folds блоков. На каждой итерации
обучает модель на данных от начала до конца блока k, валидирует на блоке k+1.
Окно train расширяется.

Архитектура v12.5: раздельные rf_long/rf_short, per-ticker thresholds,
единый forward pass экспертов на всём df.

Returns:
    dict: val_accs, long_recalls, short_recalls, per_fold, summary stats
)r:   Ni  erroru-   Недостаточно данных для : r   2   i  gQ?gzG?)longshortmax_barsd   uJ   Не удалось сгенерировать валидные фолдыz
  Walk-Forward CV v12.5: z  Data: z rows, z foldsz  Val size: z, min train: z  Thresholds: long=rA   z, short=rB      z  Fold /z	: train=[:z] (z rows), val=[z rows)      u       ⏭ Skip (train=z, val=)   
   u       [fast] cache → fine-tune z epF)r;   r7   u'       [warm] cache → continue training z'    [cold] full training from scratch (z ep))r%   outcome_longoutcome_shortu       ⏭ Skip (X_train=z, X_val=g      ?)r   rE   *   )n_estimators	max_depthrandom_staten_jobsclass_weight   g       @)foldn_trainn_valval_acclong_f1short_f1long_recallshort_recall	long_prec
short_preclong_pred_rateshort_pred_ratez    val_acc=.2%z  long: F1=.1%z R=z P=z | short: F1=u       ❌ Fold z error: )rW   r>   u   Все фолды упали)r>   per_fold)r   r6   
n_folds_okval_accsval_acc_meanval_acc_stdval_acc_minval_acc_maxlong_recall_meanshort_recall_meanlong_f1_meanshort_f1_meanre   ).r   lenr   columnsmaxintr   getr   r   r   r   r   appendprint	enumerateiloccopyr2   r%   	train_allr   r+   predict_allr
   r	   r   valuesreshapenpcolumn_stackmin
isinstancefloatr   fitpredict_probazerosastypesummeanr1   	traceback	print_excstrstd)Kr   r6   r7   r8   r9   r:   r;   r<   dfnall_featuresc	availablerY   n_train_minshort_weightlong_weightthMAX_BARSfolds	train_end	val_startval_endrg   long_recallsshort_recallslong_f1s	short_f1sre   it_startt_endv_startv_enddf_traindf_valcached	ft_epochsr    signals_fullsignals_trainsignals_valX_train_wfc_disable_shorty_trainy_val	min_len_tX_val	min_len_v
rf_long_cwrf_longrf_shortp_longp_shorty_longy_short	pred_long
pred_shortlpltplfnr_   long_recr[   spstpsfnr`   	short_recr\   rZ   	fold_infoer   resultsK                                                                              r   walk_forward_cvr   K   s
   . 
V	)B	zSWt^HPR^`^lSVWYSZRtuvvrsRtuvvBA$&L(<LqOLI<AK "%Ec!+,c2K (++F4HIL%))&2EFK			vt'D	EB   S1HEIH$I%G
Q,3u:/aIw78	h&	e#	 Q,3u:/ 5zQeff+F84573u:,f56UG=>?#BvJ<x7}EFHLMHIH/8/B++GUGUGA3aE
|9WIQugSw X!!E7#eGm_FD E 7775)..0',,.x=3#f+"2,S]O6#f+aPQG	: (/F!f&7&73y>&I #FaK 4I ?	{#NO$$Xy%PY$Z%H  GxsST$$Xy%PV$W%H CF84PQ)S^D""8Yf"U"684 $//>L*<%HM(wFK$X}h	RG!>v!F!">299AA"aH~.55==b!D//^,33Xo5N5U5U+  >*116/3J3Q3Q)  CL#g,7I&	z{3WiZ[5IWGCJE
3I )-uiZ[/A5E7|b CJO23w<.UTUVW
 6@cSX\5Z5ZS[1`kJ, B'G
 KKA/H%1!$!#B%(\!:
 Wgadm4 **51!Q$7F#"0071=q!t1+((3u:.q!t2f:-55c:I!R[088=J q.%%'BNv{388:CQ;##%+C$&FbI-03Y!OscCi(HLUX`L`deKea)mh.)h2FGklG /&&(B!O15::<Ca<$$&,C%'!VrJ.1Ci1_sSy)!IQ[^gQgklPlq:~	1Z)5KLrsH )S0GOOG$)  +OOG$X& w<U > >uX$Xi@P"9-U:=N"'1(:(:(<"=#('Q,)<)<)>#?
I OOI&WSMWSMXVYNZ]^ghk]l m##+C.Ic?#jQTEUW X Y 0Cl 7XNN u:(mbggh/0RVVH-.RVVH-.RVVH-.<HE"'',"78a>KU277=#9:QR4<bggh/0!6?rwwy12QF M] =l  	:aS45i113OOQQ899		:s-   f)'f)8I$f.Mf..
h8A	hhr   c                    SU ;   a  SU ;  a  [        SU S    35        g[        SS 35        [        SU S    35        [        S 5        [        S	U S
    SU S    35        [        SU S   S SU S   S 35        [        SU S   S SU S   S 35        [        SU S   S SU S   S 35        [        SU S   S SU S   S 35        [        S5        [        SSS  S!S"S# S!S$S% S!S&S' S!S(S% S!S)S% S!S*S% S!S+S% 35        U S,    Hf  nSU;   a  [        SUS-   S  S.US    35        M#  [        SUS-   S  S!US/   S# S!US0   S% S!US1   S2 S!US3   S4 S!US5   S4 S!US6   S4 S!US7   S4 35        Mh     [        S 5        g)8uI   Форматированный отчёт по результатам CV.r>   rg   u   
  ❌ Ошибка: N
F======================================================================z  WALK-FORWARD CV v12.5: r   u     Фолдов: rf   rF   r6   z  Val accuracy (avg F1): rh   rc       ± ri   z  Min/Max:               rj   z / rk   z  Long F1 / Recall:      rn   rd   rl   z  Short F1 / Recall:     ro   rm   z
  Per-fold:  Foldz>4 Train>6Valz>5ValAccz>7zL.F1zS.F1zL.ReczS.Recre   rW   z ERROR: rX   rY   rZ   z>6.2%r[   z>4.1%r\   r]   r^   )rv   )r   fs     r   print_cv_reportr   9  s,   &Zv5&vg&789	Bxj/	%fX&6%7
89	XJ	VL12!F94E3F
GH	%f^&<S%Af]F[\_E`
ab	%f]&;C%@F=DYZ]C^
_`	%f^&<S%AVL^E_`cDd
ef	%f_&=c%B#fM`FabeEf
gh	M	Bvbk72,abz8B-q1VTVKWXY`acXddefmnpeq
rsJa<BqynHQwZL9:BqynAa	l2%6a'
2ay\%(!I,u)=Qq}U>SST}%e,Aa.?-FH I	   
XJr   __main__zWalk-Forward CV v12.5 for MoE)descriptionz--tickerSBER)typedefaultz--foldsz--epochsz--limitzMax rows to load)r   r   helpz--all
store_truezRun all 14 tickers)actionr   z--fastuP   Fast mode: transfer learning между folds (fine-tune, меньше эпох)z--quiet)r   )ASTRGAZPLKOHMOEXMTSSNSVZNVTKPHORPLZLROSNr   SNGSPVTBRX5r   u   ────────────────────────────────────────────────────────────)r   r6   r7   r:   r;   r<   rh   r   z: mean=rc   r   ri   z
 (long F1=rn   rd   z, short F1=ro   rJ   r   z   ALL 14 TICKERS SUMMARY (v12.5)r   r?   z  (L=z/S=?u   : ERROR — r>   )r3   r4   g?g?r5   TF)H__doc__argparser   syswarningsnumpyr~   pandaspdfilterwarningsenvironr   insertdirnameabspath__file__config
set_device
models.moer   r   r	   r
   models.expertsr   r   r   r   sklearn.multioutputr   sklearn.ensembler   r   r   r   r   r   r   r   r   r+   r2   rs   r   booldictr   r   __name__ArgumentParserparseradd_argument
parse_argsargsallshutilr.   rmtreetickersresultstrv   r   r7   r:   quietr<   r   ru   rrt   r    r   r   <module>r     s-    	 
       !%(

! " 277??277??8#<= >    '  U U ) K K 5 3 z z &	F F F
s 
n 
s ~'< ( kkk k 	k
 k :k k k 
k\D 8 z$$1PQF

f=
	Q7

b9
	T@RS
;OP
o  q
	,7D xx77>>)$$MM)$xxxJABzl#$$$**{{$** JJTYYF
 NN6"'1#WVN%;C$@VMEZ[^D_ `""("8!=[P_I`adHeefh i  	8*o02
A"1X;r*"Q~->s,C4-HXY\G] ^n-c2#a6H5MQP Q 1553/3<gs@S?TUV  !;;JJ;;**

N
 	i r   