
    Mjw$                       d Z ddlmZ ddlZddlZddlmZ ddlZddl	Z
 ee      j                         j                  j                  ZddlZej                   j#                  d ee             ddlmZmZmZ ddlmZmZmZmZ ddlmZ ddlmZm Z  dd	l!m"Z"m#Z#m$Z$ dd
Z%dddZ&ddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZ'ddZ(d e       d	 	 	 ddZ)ddZ*e+dk(  r e, e*             y)af  Non-promoting screen for a frozen MLP trunk plus tiny slow-regime heads.

This is deliberately not part of ``run_mlp_train.py``: artifacts are written
under ``results/mlp_experiments`` and the runner has no sweep/promote path.
It uses the winner's thresholds unchanged, so any observed change is due to
the 27 residual head parameters, not threshold search.
    )annotationsN)Path)SCORE_START	TRAIN_END	WFO_FOLDS)SlowRouterConfigregime_head_scoresshared_trunk_forwardslow_regime_states)_prepare_features)_score_to_signalsload_mlp_artifact)
_data_path_load_winner_summaryc                   t         j                  j                  j                  |       r1t        j                  | dd      j
                  j                  d      S t        j                  | d      j
                  j                  d      S )zEAccept either TradingView's ISO timestamps or its Unix-second export.sT)unitutcN)r   )pdapitypesis_numeric_dtypeto_datetimedttz_localize)valuess    T/Users/jameslopez/projects/TradingBot25/tools/run_mlp_slow_regime_head_experiment.py_parse_chart_timer      s^    	vv||$$V,~~f3D9<<HHNN>>&d+..::4@@    c                   t        j                  | d   j                  t         j                              }t	        j
                  t        j                  ||d               }|j                  |      j                         j                  d      j                         }t        j                  t        |       t         j                        }||d |d|  z
  |z  |d|  t        j                  d|z  |dz   z        }t        j                  |       | d	   t	        j                  t               k\  j                         z  }||fS )
zGSame causal target as train_mlp, kept local to isolate this experiment.closedtyper   )prepend   Ng       @gư>time)nplogto_numpyfloat64r   Seriesdiffrollingstdshiftfulllennantanhisnan	Timestampr   )	framek
vol_window	log_closeret1volforwardyvalids	            r   _targetr@   %   s    uW~..RZZ.@AI99RWWY	!=>D
,,z
"
&
&
(
.
.q
1
:
:
<Cggc%j"&&)GabMIcrN2a7GCaRL
gt,-AXXa[LE&MR\\+-FFPPRREe8Or    ,  MbP?)epochsl2c          	     	   ddl }
|
j                  |       t        j                  j	                  |       |j                  t        j                        dz   }|||k  j                         z  }|||k\  j                         z  |t        j                  t              k  j                         z  }|j                         r|j                         st        d      |\  }}t        j                  ddd      5  | |j                  z  |z   j                  d      }ddd       |
j!                  | |
j"                        }|
j!                  ||
j$                        }|
j!                  ||
j"                        }|
j!                  t        j&                  |      |
j$                        }|
j!                  t        j&                  |      |
j$                        }|
j(                  j+                  |
j-                  d	| j.                  d   f|
j"                        j1                  d
d            }|
j(                  j+                  |
j-                  d	|
j"                        j1                  d
d            }|
j!                  |
j"                        }|
j2                  j5                  ||fd      }t7        d      dd}}}t9        |      D ]  }|j;                          ||   ||   |||      z  j=                  d      z   |||      z   }|
j?                  |
jA                  |      ||   z
  dz        |	|jC                         j?                         |jC                         j?                         z   z  z   }|jE                          |jG                          |
jI                         5  ||   ||   |||      z  j=                  d      z   |||      z   } t7        |
j?                  |
jA                  |       ||   z
  dz              }!ddd       !|dz
  k  rz|!d}}|jK                         jM                         jO                         jQ                         |jK                         jM                         jO                         jQ                         f}|dz  }|dk\  s n |J |dz   |tS        |j=                               tS        |j=                               dfS # 1 sw Y   xY w# 1 sw Y   xY w)uI   Fit only 3×(trunk width + bias) residuals; the dense trunk stays frozen.r   Nr&   zKExperiment requires non-empty chronological train and validation partitionsignore)overdivideinvalidr#      g        rB   )meanr/   g{Gz?)lrinf   gHz>   )
epochs_runbest_val_mse
train_barsval_bars)*torchmanual_seedr(   randomseedastypeint64r*   r   r6   r   any
ValueErrorerrstateTreshapetensorfloat32longflatnonzeronn	Parameteremptyshapenormal_optimAdamfloatrange	zero_gradsumrL   r4   squarebackwardstepno_graddetachcpunumpycopyint)"trunkstates	base_headr>   r?   timesrX   	val_startrC   rD   rU   state_index
train_maskval_maskbase_weights	base_biasbase_logitsfeaturesindicestargets	train_idxval_idxheadsbiasfixed	optimizer	best_loss
best_state
since_bestepochlogitsloss
val_logitsval_losss"                                     r   fit_residual_headsr   1   s9    	dIINN4--)A-K%)+5577J*4466%2<<PYCZ:Z9d9d9ffH>>8<<>fgg'L)	(8X	F|~~-	9BB2F 
G||E|7Hll;ejjl9Gll1EMMl2GR^^J7uzzJIll2>>(35::lFG HHu{{Au{{1~+>emm{T\\beko\pqE88ekk!5==kAIIsX\I]^DLLEMML:E  %4 8I(-edA:zIvy!Xi%85AS;T%T$Y$YZ[$\\_cdkludv_wwzz5::f-	0BBqHIBRWR^R^R`ReReRgjnjujujwj|j|j~R~L]]_w8G+<uWWEU?V+V*[*[\]*^^aefmnufvawwJUZZJ)?''BR)RWX(XYZH  i$&&$,azI,,.,,.446;;=t{{}?P?P?R?X?X?Z?_?_?abJ!OJR   !!!eai&)*..*:&;X\\^I\^ ^ ^? 
G	F( _s   6"S$AS'S$'S0	c           	         | j                         }||d<   t        |||d   j                         |d   j                  t        j                        |d   j                  t        j                              S )Nactivation_scorestoch_peak_normr"   high)rv   r   r*   r(   r+   )r7   paramsscorescoreds       r   _signalsr   b   sj    ZZ\F!&FVVV4E-F-O-O-Q#G_55bjjA6&>CZCZ[][e[eCfh hr    )rC   router_configc                  t        j                  t        | |            }|j                  j                  j                         j                  j                         |_        t        |d         |d<   t        | |      }t        |d<   t        t	        |d               }|d   dd  g dk7  rt        d|d          t        ||d         }t        ||d	         }	t        ||      }
t        |      \  }}t        j                   t"        d
   d         }t%        ||t'        |	|
|d	   d
   t)        j*                  d|	j,                  d   f      t)        j*                  d      f            }t/        d|      g}g }|D ]  }t1        |	|
|d	   d
   |||d   |||	      \  }}t%        ||t'        |	|
|d	   d
   |            }t/        d| |      }|j3                  |       |j3                  |||d   j5                         |d   j5                         gd        d| |t7        |      dD ci c](  }t	        |      t9        |
|k(  j;                               * c}t9        t)        j<                  t)        j>                  |
                  t	        |jA                               d|d	}t        jB                  |      |fS c c}w )Nr'   _pine_time_startmlp_weights_filearch)      r&   u+   Expected dense 55→16→8→1 winner, got feature_colslayersrJ   r&   rK   z'null heads (exact shared-trunk control))rX   r|   rC   z slow-regime residual heads seed r   )rX   trainingresidual_headsT)rJ   r   r&   zwinner thresholds unchanged)	non_promotingassettfrouterstate_countsstate_switchesvalidation_startfixed_policyruns)"r   read_csvr   columnsstrlowerstripr   r   r   r   r\   r   r
   r   r@   r6   r   r   r	   r(   zerosrg   r   r   appendtolistvarsrw   rn   count_nonzeror-   date	DataFrame)r   r   seedsrC   r   r7   r   artifactXrx   ry   r>   r?   r|   baselinerowsr   rX   r   r   signalsrowstatemetadatas                           r   runr   i   s   KK
5"-.EMM%%++-11779EM%eFm4E&M%$F!,F V,>%?!@AH
*FxPVGWFXYZZ%.!9:A HX$67E}5Fu~HAuYr]1-.Iv'9%RZI[\^I_<>HHaUVEX<Y[][c[cde[f;g(i jH>IJDD,UFHX<Nr<RTUW\^cdj^k26)TZ\x5&*<UFHU]L^_aLbdi*jk9$@'JCTxERSHOOL]_def_g_n_n_pKqrs  "&R4P]K^Wa bWaeUS&E/1F1F1H-I!IWa b"%b&6&6rwwv&G"H^abkbpbpbr^s =tMH <<x'' !cs   (-J;c                    t        j                  t              } | j                  dd       | j                  dd       | j                  ddt        g d	
       | j                  dt        d       | j                  dt
        t        dz  dz         | j                         }t        |j                  |j                  |j                  |j                        \  }}t        |j                  dd              |j                  d   }|j                  dd  }t	        |d   j!                               }t#        |d   j%                               }d| dt'        |       d|ddt#        |d         dd	}|j(                  j*                  j-                  dd        |j(                  j/                  d!|z   d"z   |j                  dd#       z   d$z   t1        j2                  |d%&      z   d'z          y)(N)descriptionz--assetCOINBASE_BTCUSD)defaultz--tf6Hz--seeds+)i  i  iZ   )nargstyper   z--epochsrA   )r   r   z--outputdocsz4mlp_slow_regime_head_experiment_btc_6h_2026_08_21.md)rC   Fc                
    | dS N.3f values    r   <lambda>zmain.<locals>.<lambda>   s
    uSkNr    )indexfloat_formatr   r&   wfo_eligiblewfo_mean_calmarz]Rejected at the exploratory screen: no candidate met the canonical WFO coverage requirement (/z# eligible), and median WFO Calmar (r   z*) was below the paired null-head control (z@). This is independent of the stricter live-promotion benchmark.T)parentsexist_oku   # Slow Regime-Head Experiment — BTC 6H

Non-promoting, fixed-policy screen. The current winner's thresholds were held fixed; the only trainable parameters are three residual 8→1 output heads.

## Decision

z

## Results

```text
c                
    | dS r   r   r   s    r   r   zmain.<locals>.<lambda>   s    afgj`k^lr    z
```

## Provenance

```json
rO   )indentz
```
)argparseArgumentParser__doc__add_argumentrw   r   REPO
parse_argsr   r   r   r   rC   print	to_stringilocrn   rk   medianr2   outputparentmkdir
write_textjsondumps)	parserargsresultsr   control
candidateseligible
median_wfodecisions	            r   mainr      s   $$9F
	+<=
-
	3@RS

c:

tf}G}7}~DDJJDKKPGX	'

%6R

STll1oGab!J:n-1134Hz"34;;=>J	 z3z?"3 4sEeGTeLfFghkEl mH	H  	KKTD9KK	 %	%("	" %,$5$5EPl$5$m		n
 	.	.
 15

8A0N	O
 R[	[ r    __main__)r   	pd.Seriesreturnr   )
   <   )r7   pd.DataFramer8   rw   r9   rw   r   tuple[np.ndarray, np.ndarray])rx   
np.ndarrayry   r  rz   r   r>   r  r?   r  r{   r   rX   rw   r|   zpd.TimestamprC   rw   rD   rk   r   z<tuple[tuple[np.ndarray, np.ndarray], dict[str, float | int]])r7   r   r   zdict[str, object]r   r  r   r   )r   r   r   r   r   z	list[int]rC   rw   r   r   r   z&tuple[pd.DataFrame, dict[str, object]])r   rw   )-r   
__future__r   r   r   pathlibr   ru   r(   pandasr   __file__resolver   r   syspathinsertr   configr   r   r   !strategies.mlp_slow_regime_routerr   r	   r
   r   %strategies.strategy_activation_scoresr   strategies.strategy_mlp_scoresr   r   (tools.run_mlp_score_structure_experimentr   r   r   r   r@   r   r   r   r   __name__
SystemExitr   r    r   <module>r     s$   #     H~&&-- 
 3t9  4 4Y Y C O W WA	 ?Bt.^$.^-7.^@I.^TW.^"..^8;.^GL.^ YU.^bh AD*:*<('(Ag(B@ z
TV
 r    