Ë
    Bp±j
W  ã            	       óx  — d Z ddlZddlZddlZddlZddlZej                  j                  ej                  j                  ej                  j                  ej                  j                  e«      d«      «      «       ddlmZmZmZ ddlmZ g d¢ZdZg d¢Zg d	¢Zd
„ Zd„ Z	 	 dd„Zi Zd„ Z	 dd„Zd„ Zd„ Zd„ Z y)u  
MLP-based activation score strategy.

Replaces the single-layer weighted sum of strategy_activation_scores.py with a
small multi-layer perceptron over the pre-normalised feature columns (55 for
BTC, 50 for alts; see FEATURE_COLS / the artifact's feature_cols):

    score = 1000 * tanh( W3 . tanh( W2 . tanh(W1.x + b1) + b2 ) + b3 )

Everything downstream of the score â€” crossunder entry/exit, confirmation,
trailing stop, regime/MVRV gates, metrics â€” is identical to the existing
strategy (imported or mirrored verbatim), so results stay directly comparable
and the TV-parity workflow carries over.

Weights are NOT optimizer params: they live in a JSON artifact
(strategies/params/mlp/mlp_weights_{ASSET}_{TF}.json) produced by
tools/train_mlp.py and referenced via the `mlp_weights_file` param.
The same weights are embedded into strategy_mlp_scores.pine as array literals
by tools/generate_pine_mlp_presets.py, with tanh implemented in Pine by the
identical clamped closed form (Pine v6 has no math.tanh):

    tanh(x) = x >= 20 ?  1.0
            : x <= -20 ? -1.0
            : (exp(2x) - 1) / (exp(2x) + 1)

Pilot limitations (documented intentionally):
  - `i_div_window` is unsupported â€” the MLP consumes raw single-bar RSID flags,
    matching _prepare_features()'s window=1 behaviour.
é    Nz..)Ú_apply_trailing_stopÚ_prepare_featuresÚcalculate_metrics)Úcalculate_positions)	ÚFEATURE_COLSÚFEATURE_WEIGHT_PARAMSÚACTIVATION_NAMEÚ_tanhÚmlp_forwardÚsave_mlp_artifactÚload_mlp_artifactÚgenerate_signalsr   Útanh_closed_form_clamp20)7Ú
stoch_normÚmacd_pred_normÚosc_normÚtotalvol_normÚm3_momentum_normÚm2_tiny_normÚnewaddr_normÚstoch_div_normÚvwap_div_normÚstoch_peak_normÚsendaddr_normÚm3_div_normÚbearish_engulfing_scoreÚm2_nooff_normÚm2_div_normÚbullish_hammer_scoreÚbullish_engulfing_scoreÚshooting_star_scoreÚbtc_spx_corr_30Údxy_roc_normÚvix_pctrank_invÚbtc_dom_roc_signÚus10y_roc_inv_signÚspy_above_200emaÚgold_roc_pctrankÚmvrv_zscore_valueÚmvrv_zscore_contÚ	nupl_normÚfed_net_liq_signÚgc_positionÚus2y_roc_inv_signÚyield_curve_signÚ	sopr_normÚrsid_reg_bull_normÚrsid_reg_bear_normÚrsid_hid_bull_normÚrsid_hid_bear_normÚrsid_rt_bull_normÚrsid_rt_bear_normÚrsid_slow_bull_normÚrsid_slow_bear_normÚrsid_delayed_peak_normÚrsid_delayed_dip_normÚoi_roc_normÚusdt_d_normÚ
basis_normÚcvd_normÚbtc_gold_normÚrsi_subtf_normÚbb_pct_b_normr>   Ú	rvol_normÚactive1y_normÚhr_normr0   )2Ú	i_w_stochÚi_w_macd_predÚi_w_oscÚi_w_totalvolÚi_w_m3_momentumÚi_w_m2_tinyÚi_w_newaddrÚi_w_stoch_div_oscÚi_w_vwap_div_oscÚi_w_stoch_peakingÚi_w_sendaddrÚi_w_m3_div_oscÚi_w_bearish_engulfingÚi_w_m2_div_osc_noOffsetÚi_w_m2_div_oscÚi_w_bullish_hammerÚi_w_bullish_engulfingÚi_w_shooting_starÚi_w_btc_spx_corrÚi_w_dxyÚi_w_vixÚi_w_btc_domÚ	i_w_us10yÚi_w_spyÚi_w_goldÚi_w_mvrvÚi_w_mvrv_contÚi_w_nuplÚi_w_fed_net_liqÚi_w_gc_positionÚi_w_us2yÚi_w_yield_curveÚi_w_qqq_spy_ratioÚi_w_rsid_reg_bullÚi_w_rsid_reg_bearÚi_w_rsid_hid_bullÚi_w_rsid_hid_bearÚi_w_rsid_rt_bullÚi_w_rsid_rt_bearÚi_w_rsid_slow_bullÚi_w_rsid_slow_bearÚi_w_rsid_delayed_peakÚi_w_rsid_delayed_dipÚ
i_w_oi_rocÚ
i_w_usdt_dÚ	i_w_basisÚi_w_fear_greedÚi_w_btc_goldÚi_w_rsi_subtfÚi_w_bb_pct_bc                 ó   — t        j                  | t         j                  ¬«      } t        j                  | «      }| dk\  }| dk  }||z   }d||<   d||<   t        j                  d| |   z  «      }|dz
  |dz   z  ||<   |S )a  Clamped closed-form tanh, formula-identical to the Pine implementation.

    Inside (-20, 20): (exp(2x) - 1) / (exp(2x) + 1). At |x| >= 20 returns
    exactly +/-1.0 (Pine and Python clamp at the same point so neither side
    can diverge in the saturated region).
    ©Údtypeg      4@g      4Àç      ð?g      ð¿g       @)ÚnpÚasarrayÚfloat64Ú
empty_likeÚexp)ÚxÚoutÚhiÚloÚmidÚe2xs         úo/Users/jameslopez/projects/TradingBot25/.worktrees/mlp-comparable-measurement/strategies/strategy_mlp_scores.pyr
   r
   Ž   s†   € ô 	�
‰
�1œBŸJ™JÔ'€AÜ
�-‰-˜Ó
€CØ	
ˆd‰€BØ	
ˆe‰€BØ�‰Gˆ*€CØ€Cˆ�GØ€Cˆ�GÜ
�&‰&��q˜‘v‘Ó
€CØ�c‘	˜c C™iÑ(€Cˆ�HØ€Jó    c                 ó˜  — t        j                  | t         j                  ¬«      }|D ]‰  \  }}t        j                  ddd¬«      5  |t        j                  |t         j                  ¬«      j                  z  t        j                  |t         j                  ¬«      z   }ddd«       t        «      }Œ‹ |dd…df   dz  S # 1 sw Y   Œ"xY w)a	  Forward pass: X (T, F) float64, layers = [(W, b), ...] with W (n_out, n_in).

    Every layer (including the output layer) applies _tanh; the final scalar is
    scaled by 1000 so scores live in [-1000, +1000] like the existing
    activation-score convention.
    rx   Úignore)ÚdivideÚoverÚinvalidNr   g     @�@)r{   r|   r}   ÚerrstateÚTr
   )ÚXÚlayersÚaÚWÚbÚzs         r†   r   r   ¡   s—   € ô 	�
‰
�1œBŸJ™JÔ'€AÛ‰ˆˆ1Ü�[‰[ ¨xÀÖJØ”B—J‘J˜q¬¯
©
Ô3×5Ñ5Ñ5¼¿
¹
À1ÌBÏJÉJÔ8WÑWˆA÷ Kä�!‹H‰ð ð ŠQ�ˆT‰7�VÑÐ÷ KÐJús   ÁAC Ã C		c                 ó\  — |�t        |«      nt        t        «      }t        t        j                  |d   d   «      j
                  d   «      g|D ��cg c]0  \  }}t        t        j                  |«      j
                  d   «      ‘Œ2 c}}z   }d|||t        ||D ��	cg c]l  \  }}	t        j                  |t        j                  ¬«      j                  «       t        j                  |	t        j                  ¬«      j                  «       dœ‘Œn c}	}|xs i dœ}
t        j                  t        j                  j                  t        j                  j                  | «      «      d¬«       t        | d	«      5 }t        j                   |
|«       ddd«       yc c}}w c c}	}w # 1 sw Y   yxY w)
zƒWrites the weights artifact JSON. Floats serialised via repr (full
    precision) by json, so load() round-trips bit-exact float64.Nr   é   rx   )r’   r“   )ÚversionÚassetÚ	timeframeÚarchÚ
activationÚfeature_colsr�   ÚtrainingT)Úexist_okÚw)Úlistr   Úintr{   r|   Úshaper	   r}   ÚtolistÚosÚmakedirsÚpathÚdirnameÚabspathÚopenÚjsonÚdump)r¦   r�   r˜   r™   r�   rœ   r’   Ú_rš   r“   ÚpayloadÚfs               r†   r   r   ´   sV  € ð *6Ð)A”4˜Ô%ÄtÌLÓGY€LÜ”—
‘
˜6 !™9 Q™<Ó(×.Ñ.¨qÑ1Ó2Ð3Ù06ô7Ù06©¨¨1ŒŒB�J‰J�q‹M×Ñ Ñ"Õ#°ò7ñ €Dð ØØØÜ%Ø$ñ ô
ñ ‘��1ô —*‘*˜Q¤b§j¡jÔ1×8Ñ8Ó:Ü—*‘*˜Q¤b§j¡jÔ1×8Ñ8Ó:ó<àò
ð
 ’N ñ€Gô ‡K�K”—‘—‘¤§¡§¡°Ó 5Ó6ÀÕFÜ	ˆd�CŒ˜AÜ�	‰	�'˜1Ô÷ 
ˆùó%7ùó
÷ 
ˆús   Á5FÂA1FÅ6F"Æ"F+c                 óÒ  — t         j                  j                  | «      }t         j                  j                  |«      }t        j                  |«      }|�|d   |k(  r|d   S t        |«      5 }t        j                  |«      }ddd«       d   D �cg c]R  }t        j                  |d   t        j                  ¬«      t        j                  |d   t        j                  ¬«      f‘ŒT }}||d   |d	   |j                  d
«      |j                  d«      |j                  d«      |j                  d«      |j                  di «      dœdœ}||ft        |<   |S # 1 sw Y   ŒÕxY wc c}w )a“  Loads (and caches by path+mtime) a weights artifact.

    Returns {"layers": [(W, b), ...] float64, "arch": [...],
             "feature_cols": [...], "meta": {...}}.

    Note: artifacts trained on the 49-feature set (pre-bb_pct_b_norm) are still
    loadable via load_mlp_artifact() and mlp_results_table; they carry their own
    feature_cols list and will fall back to 0 for any missing column.
    Nr   r–   r�   r’   rx   r“   rš   rœ   r—   r˜   r™   r›   r�   )r—   r˜   r™   r›   r�   )r�   rš   rœ   Úmeta)r¤   r¦   r¨   ÚgetmtimeÚ_ARTIFACT_CACHEÚgetr©   rª   Úloadr{   Úarrayr}   )	r¦   r¨   ÚmtimeÚcachedr®   r­   Úlayerr�   Úarts	            r†   r   r   Ò   sA  € ô �g‰g�o‰o˜dÓ#€GÜ�G‰G×Ñ˜WÓ%€EÜ× Ñ  Ó)€FØÐ˜f Q™i¨5Ò0Ø�a‰yÐä	ˆgŒ˜!Ü—)‘)˜A“,ˆ÷ 
ð ˜XÒ&óá&ˆEô 
�‰�%˜‘*¤B§J¡JÔ	/´·±¸%À¹*ÌBÏJÉJÔ1WÒXØ&ð ð ð
 Ø˜‘Ø Ñ/à—{‘{ 9Ó-Ø—[‘[ Ó)Ø Ÿ™ [Ó1Ø!Ÿ+™+ lÓ3ØŸ™ J°Ó3ñ
ñ	€Cð !& s˜|„O�GÑØ€J÷' 
ˆüòs   Á.EÂAE$ÅE!c	                 ó  — t        |«      }	t        j                  |	t        j                  ¬«      }
t        j                  |	t        ¬«      }t        j                  |	t        ¬«      }d}d}d}d}t        |	«      D ]�  }|€dnt	        ||   «      }|rB||k7  r||   |kD  r||   }|d|z
  z  }||   |k  }|r||   n||   }|s|r0|r.d}d||<   d}d}d}n | |   r|rd}d||<   ||   }|dz   }||   |k  }|rdnd|
|<   Œƒ |
||fS )	u°  Like _apply_trailing_stop but with dead-zone guard for exit smoothing.

    When a trade enters while score_exit[entry_bar] < exit_threshold (i.e. the
    SMA is already below the exit threshold â€” the "dead-zone"), the smoothed
    crossunder can never fire for that trade because there is no transition from
    above to below the threshold.  In that case we switch to the raw-score
    crossunder (exit_raw_fallback_arr) for the duration of that trade only.

    time_ok_arr (optional bool array): see _apply_trailing_stop â€” Pine gates
    strategy.close on timeCondition, so entries/exits only fire where
    time_ok_arr[t] is True; a position open at window end is held open.
    rx   Fç        éÿÿÿÿTrz   r–   r   ©Úlenr{   ÚzerosÚint32ÚboolÚrange)Úentry_raw_arrÚexit_raw_arrÚexit_raw_fallback_arrÚscore_exit_arrÚexit_thresholdÚ	close_arrÚhigh_arrÚtrail_stop_pctÚtime_ok_arrÚnÚin_posÚ
exec_entryÚ	exec_exitÚpositionÚ
trade_highÚfill_barÚuse_rawÚtÚallowedÚ
stop_priceÚ	trail_hitÚexit_sigs                         r†   Ú_apply_trailing_stop_with_dzrÙ   ü   s?  € ô  	ˆI‹€AÜ—‘˜!¤2§8¡8Ô,€FÜ—‘˜!¤4Ô(€JÜ—‘˜!¤4Ô(€Ià€HØ€JØ€HØ€Gä�1ŽXˆØ%Ð-‘$´4¸ÀA¹Ó3GˆÙØ�HŠ} ¨!¡¨zÒ!9Ø% a™[�
Ø# s¨^Ñ';Ñ<ˆJØ" 1™¨Ñ3ˆIá3:Ð,¨QÒ/ÀÈQÁˆHÙ™X©7Ø"�Ø#�	˜!‘Ø �
Ø�Ø"‘à˜QÒ¡GØ!�Ø $�
˜1‘Ø& q™\�
Ø ™U�Ø+¨AÑ.°Ñ?�á!‘A qˆˆqŠ	ð/ ð2 �:˜yÐ(Ð(r‡   c                 ón  — t        | «      }t        j                  |t        j                  ¬«      }t        j                  |t        ¬«      }t        j                  |t        ¬«      }d}	d}
t        |«      D ]9  }|	r|
r||   n||   }|rd}	d||<   d}
n| |   rd}	d||<   ||   |k  }
|	rdnd||<   Œ; |||fS )zELike calculate_positions but with dead-zone guard (no trailing stop).rx   FTr–   r   r½   )rÃ   rÄ   rÅ   rÆ   rÇ   rÌ   rÍ   rÎ   rÏ   rÐ   rÓ   rÔ   rØ   s                r†   Ú_calculate_positions_with_dzrÛ   2  sÇ   € ô 	ˆMÓ€AÜ—‘˜!¤2§8¡8Ô,€FÜ—‘˜!¤4Ô(€JÜ—‘˜!¤4Ô(€Ià€HØ€Gä�1ŽXˆÙÙ3:Ð,¨QÒ/ÀÈQÁˆHÙØ �Ø#�	˜!‘Ø‘à˜QÒØ�Ø $�
˜1‘Ø(¨Ñ+¨nÑ<�á!‘A qˆˆqŠ	ð ð �:˜yÐ(Ð(r‡   c                 ó2
  — |j                  dd«      }|j                  dd«      }|j                  dd«      }|j                  dd«      }|j                  d	d
«      }	| d   }
t        dt        |j                  dd«      «      «      }|dkD  r!|
j                  |d¬«      j	                  «       n|
}t        dt        |j                  dd«      «      «      }|dkD  r!|
j                  |d¬«      j	                  «       n|
}t        |j                  dd«      «      }t        |j                  dd«      «      }|dkD  r%|
j                  |d¬«      j	                  «       |kD  }n!t        j                  d| j                  ¬«      }t        |j                  dd
«      «      }|rd| j                  v r|| d   dk\  z  }t        j                  |dk7  | j                  ¬«      }|rf|j                  d«      |k\  |j                  d«      |k  z  ||k  z  }|dkD  r/|
j                  d«      |k\  |
j                  d«      |k  z  |
|k  z  n|}n_|j                  d«      |k\  |j                  d«      |k  z  |z  }|dkD  r,|
j                  d«      |k\  |
j                  d«      |k  z  |z  n|}|	rT|j                  d«      |k\  |j                  d«      |k  z  |
|
j                  d«      kD  z  |j                  dd
¬«       z  }n|j                  d«      |k\  ||k  z  }||z  }|j                  d«      }|j                  d«      }d}|€|�¦d| j                  v r˜t        j                  | d   «      }t        j                  d| j                  ¬«      }|�||t        j                  |«      k\  z  }|�||t        j                  |«      k  z  }||z  }||z  }||z  }|j                  t        ¬«      }t        |j                  d d!«      «      d"z  }|j                  d
«      j                   j#                  t        «      }|j                  d
«      j                   j#                  t        «      }|j                  d
«      j                   j#                  t        «      }|j                   } |dkD  r2|d!kD  rt%        |||| |||||¬#«	      \  }!}"}#n?t'        |||| |«      \  }!}"}#n+|d!kD  rt)        ||||||¬#«      \  }!}"}#nt+        ||«      \  }!}"}#|!j#                  t        «      | d$<   |"| d%<   |#| d&<   | S )'u
  Threshold/regime/crossunder/position block â€” mirrors
    strategy_activation_scores.generate_signals lines 332-421 verbatim (that
    block is inline in the original and cannot be imported without modifying
    it). df must already contain 'activation_score'.
    Ú!i_long_entry_activation_thresholdg     €Z@Ú i_long_exit_activation_thresholdg     �a@Ú-i_long_exit_activation_confirmation_thresholdgÍÌÌÌÌ4@@Úi_use_long_exit_confirmationrz   Úi_use_long_entry_confirmationFÚactivation_scorer–   Úi_exit_score_window)Úmin_periodsÚi_entry_score_windowÚi_regime_windowr   Úi_regime_entry_min_scoreg     @�À)Úwindowrä   T)ÚindexÚi_mvrv_suppress_bearÚmvrv_regimeé   )Ú
fill_valueÚ_pine_time_startÚ_pine_time_endNÚtimerx   Úi_trailing_stop_thresholdr»   g      Y@)rË   rÐ   Úexecute_entryÚexecute_exit)r³   Úmaxr¡   ÚrollingÚmeanÚfloatÚpdÚSeriesré   rÁ   ÚcolumnsÚshiftÚto_datetimeÚ	TimestampÚto_numpyÚfillnaÚvaluesÚastyperÙ   rÛ   r   r   )$ÚdfÚparamsÚstoch_peak_arrrÈ   rÉ   Úentry_thresholdrÇ   Úexit_conf_thresholdÚuse_exit_confÚuse_entry_confÚscoreÚexit_windowÚ
score_exitÚentry_windowÚscore_entryÚregime_windowÚ
regime_minÚ	regime_okÚsuppress_bearÚ
stoch_peakÚexit_rawÚexit_raw_fallbackÚ	entry_rawÚ
time_startÚtime_endrË   rð   Útime_okrÊ   Ú	entry_arrÚexit_arrÚfallback_arrrÆ   rÍ   rÎ   rÏ   s$                                       r†   Ú_score_to_signalsr  O  s^  € ð !Ÿ*™*Ð%HÐW\Ó]€OØ Ÿ*™*Ð%GÐW\Ó]€NØ Ÿ*™*Ð%TÐW^Ó_ÐØ Ÿ*™*Ð%CÐWZÓ[€MØ Ÿ*™*Ð%DÐW\Ó]€NàÐ!Ñ"€Eô �aœ˜VŸZ™ZÐ(=¸qÓAÓBÓC€KØEPÐSTÂ_�—‘˜{¸�Ó:×?Ñ?ÔAÐZ_€Jô �qœ#˜fŸj™jÐ)?ÀÓCÓDÓE€LØGSÐVWÒGW�%—-‘- ¸!�-Ó<×AÑAÔCÐ]b€Kô ˜Ÿ
™
Ð#4°aÓ8Ó9€MÜ˜&Ÿ*™*Ð%?ÀÓIÓJ€JØ�qÒØ—M‘M¨ÀA�MÓF×KÑKÓMÐPZÑZ‰	ä—I‘I˜d¨"¯(©(Ô3ˆ	ô ˜Ÿ™Ð$:¸EÓBÓC€MÙ˜¨"¯*©*Ñ4Ø  MÑ!2°aÑ!7Ñ8ˆ	ô —‘˜>¨QÑ.°b·h±hÔ?€JÙà×Ñ˜aÓ  NÑ2Ø×Ñ˜aÓ  >Ñ1ñ3àÐ-Ñ-ñ/ð 	ð ˜1Š_ð �[‰[˜‹^˜~Ñ-Ø�[‰[˜‹^˜nÑ,ñ.àÐ(Ñ(ò*ð #+ñ	 	ð ×Ñ˜aÓ  NÑ2Ø×Ñ˜aÓ  >Ñ1ñ3àñð 	ð ˜1Š_ð �[‰[˜‹^˜~Ñ-Ø�[‰[˜‹^˜nÑ,ñ.àòð #+ð	 	ñ à×Ñ˜qÓ! _Ñ4Ø×Ñ˜qÓ! OÑ3ñ5à�U—[‘[ “^Ñ#ñ%ð �^‰^˜A¨%ˆ^Ó0Ð0ñ1ñ 	ð !×&Ñ& qÓ)¨_Ñ<ÀÈÑA^Ñ_ˆ	à˜IÑ%€IØ—‘Ð.Ó/€JØ�z‰zÐ*Ó+€Hð €KØÐ (Ð"6¸FÀbÇjÁjÑ<PÜ�~‰~˜b ™jÓ)ˆÜ—)‘)˜D¨¯©Ô1ˆØÐ!Ø ¬¯©°jÓ)AÑ!AÑBˆGØÐØ ¬¯©°hÓ)?Ñ!?Ñ@ˆGØ Ñ'ˆ	Ø˜gÑ%ˆØ-°Ñ7ÐØ×&Ñ&¬TÐ&Ó2ˆô ˜6Ÿ:™:Ð&AÀ3ÓGÓHÈ5ÑP€NØ×#Ñ# EÓ*×1Ñ1×8Ñ8¼Ó>€IØ—?‘? 5Ó)×0Ñ0×7Ñ7¼Ó=€HØ$×+Ñ+¨EÓ2×9Ñ9×@Ñ@ÄÓF€LØ×&Ñ&€Nà�Q‚Ø˜CÒÜ,HØ˜8 \Ø Ø˜8 ^Ø'ô	-Ñ)ˆF�J¡	ô -IØ˜8 \Ø ó-Ñ)ˆF�J¡	ð 
˜#Ò	Ü(<Ø�x ¨H°nØ#ô)
Ñ%ˆ�
™Iô
 )<¸IÀxÓ(PÑ%ˆ�
˜Ià Ÿ-™-¬Ó,€B€z�NØ$€B€ÑØ#€B€~ÑØ€Ir‡   c                 ó¾  — |j                  d«      }|st        d«      ‚t        |«      }|d   }|t        k7  r¹t        D �cg c]	  }||vsŒ|‘Œ }}|D �cg c]  }|t        vsŒ|‘Œ }}ddl}|rK|D �cg c]  }|| j
                  vsŒ|‘Œ }	}|	rt        d|› d|	› �«      ‚|j                  d|› d|› d	�d
¬«       |r6|j                  d|› dt        |«      › dt        t        «      › d|› d�	d
¬«       | j                  «       } | j
                  j                  j                  «       j                  j                  «       | _        t        | |«      }
t        |
|d   «      | d<   |
dd…df   }| d   j                  j                  t         j"                  «      }| d   j                  j                  t         j"                  «      }t%        | ||||«      S c c}w c c}w c c}w )uÿ  Generates entry/exit signals from the MLP activation score.

    Params:
      mlp_weights_file â€” path to the weights artifact JSON (required)
      i_long_entry_activation_threshold / i_long_exit_activation_threshold /
      i_long_exit_activation_confirmation_threshold â€” score thresholds
      i_use_long_entry_confirmation / i_use_long_exit_confirmation â€” flags
      i_trailing_stop_threshold â€” pct (0 disables)
      i_regime_window / i_regime_entry_min_score / i_mvrv_suppress_bear â€” gates
    Úmlp_weights_filez9strategy_mlp_scores requires the 'mlp_weights_file' paramrœ   r   Nz	Artifact z, expects columns not in FEATURE_COLS or df: z) expects extra columns (probe features): z'. These will be read from the input df.rì   )Ú
stacklevelz was trained on z$ features; current FEATURE_COLS has z (new: u=   ). New columns default to 0 â€” retrain for full performance.r�   râ   é	   ÚcloseÚhigh)r³   Ú
ValueErrorr   r   Úwarningsrú   Úwarnr¾   ÚcopyÚstrÚlowerÚstripr   r   r   r  r{   r}   r  )r  r  Úweights_filer¹   Úart_colsÚcÚextraÚmissingr$  Úmissing_and_absentr�   r  rÈ   rÉ   s                 r†   r   r   Ï  s  € ð —:‘:Ð0Ó1€LÙÜÐTÓUÐUÜ
˜LÓ
)€CØ�>Ñ"€HØ”<Òõ )Ó>™L�q¨A°XÒ,=’˜LˆÐ>Ù&Ó@™h˜¨!´<Ò*?’1˜hˆÐ@ÛÙñ .5Ó!L©W¨¸ÀÇÁÒ8K¢!¨WÐÐ!LÙ!Ü Ø ˜~Ð-YØ)Ð*ð,óð ð �M‰MØ˜L˜>Ð)RÐSZÐR[ð \8ð 8àð ô ñ
 Ø�M‰MØ˜L˜>Ð)9¼#¸h»-¸ð I,Ü,/´Ó,=Ð+>¸gÀeÀWð MMðMð ð	 ô ð 
�‰‹€BØ—‘—‘×%Ñ%Ó'×+Ñ+×1Ñ1Ó3€B„Jä˜"˜hÓ'€AÜ(¨¨C°©MÓ:€BÐÑà’q˜!�t‘W€NØ�7‘×"Ñ"×)Ñ)¬"¯*©*Ó5€IØ�6‘
×!Ñ!×(Ñ(¬¯©Ó4€Hä˜R ¨¸ÀHÓMÐMùòI ?ùÚ@ùò "Ms$   Á 	GÁ
GÁGÁ"GÁ2GÂG)NNNN)N)!Ú__doc__rª   r¤   ÚsysÚnumpyr{   Úpandasrø   r¦   Úappendr¨   Újoinr§   Ú__file__Ú%strategies.strategy_activation_scoresr   r   r   Ú$strategies.library_activation_scoresr   Ú__all__r	   r   r   r
   r   r   r²   r   rÙ   rÛ   r  r   © r‡   r†   Ú<module>r;     sÅ   ðñó: Û 	Û 
ã Û à ‡�‡��—‘—‘ §¡§¡¨R¯W©W¯_©_¸XÓ-FÈÓ MÓNÔ O÷ñ õ
 Eò€ð -€ò8€òzÐ ò*ò&ð& JNØ#'óð6 €ò#ðZ 04ó3)òl)ò:}ó@8Nr‡   