Ë
    sw±j6¯  ã            	       óÌ  — 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 d dlmZmZmZmZmZ 	 d dlmZ  ej,                  «       ZdZdZdZ	 dd	„Zd
„ Zdddœd„Zdd„Zerej@                  d„ «       Z!d„ Z"d„ Z#yy# e$ r dZY Œ>w xY w)é    Nz..)Úget_min_trades)Úcalculate_activation_score_pocÚcalculate_positionsÚcalculate_bullish_engulfingÚcalculate_bullish_hammerÚcalculate_shooting_star)ÚcudaFé   g{®Gázt?c                 óÜ  — t        |«      }t        j                  |t        j                  ¬«      }t        j                  |t        ¬«      }t        j                  |t        ¬«      }	d}
d}d}t        |«      D ]n  }|€dnt	        ||   «      }|
r7||k7  r||   |kD  r||   }|d|z
  z  }||   |k  }|s||   r&|r$d}
d|	|<   d}d}n| |   r|rd}
d||<   ||   }|dz   }|
rdnd||<   Œp |||	fS )	u  
    Simulates positions bar-by-bar with a percentage-based trailing stop.
    Replaces calculate_positions when i_trailing_stop_threshold > 0.

    Matches Pine Script behaviour with fill_orders_on_standard_ohlc=true:
      - Entry signal fires at bar-close T; order fills at open[T+1].
      - Pine sets trail_high = position_avg_price = open[T+1] on the fill bar.
        It does NOT update with high[T+1] on that first bar.
      - From bar T+2 onward: trail_high = max(trail_high, high).
      - Stop fires when close <= trail_high * (1 - trail_stop_pct).
      - Python records signal on bar T; TV records fill on bar T+1 (1-day offset).

    The fill_bar skip: when entry fires on bar T, bar T+1 is the fill bar.
    We initialise trade_high = close[T] â‰ˆ open[T+1] = position_avg_price, and
    skip the trail_high update on T+1 to match Pine's initialisation logic.

    time_ok_arr (optional bool array): Pine gates BOTH strategy.close calls
    (score-exit and trailing-stop) on `timeCondition = time>=startDate and
    time<=endDate`. When supplied, entries and exits (trail OR score) may only
    fire on bars where time_ok_arr[t] is True â€” so a position open when the
    window ends is held open to the data end, exactly like Pine (it cannot
    close after endDate). The trail high-water mark keeps updating (Pine does
    not gate that), only the close is gated. Default None = no gating (legacy
    behaviour; the activation strategy and optimizer paths pass nothing).

    Returns (in_pos, exec_entry, exec_exit).
    ©ÚdtypeFç        éÿÿÿÿTç      ð?é   r   )ÚlenÚnpÚzerosÚint32ÚboolÚrange)Úentry_raw_arrÚexit_raw_arrÚ	close_arrÚhigh_arrÚtrail_stop_pctÚtime_ok_arrÚnÚin_posÚ
exec_entryÚ	exec_exitÚpositionÚ
trade_highÚfill_barÚtÚallowedÚ
stop_priceÚ	trail_hits                    úv/Users/jameslopez/projects/TradingBot25/.worktrees/mlp-comparable-measurement/strategies/strategy_activation_scores.pyÚ_apply_trailing_stopr*   &   s  € ô: 	ˆI‹€AÜ—‘˜!¤2§8¡8Ô,€FÜ—‘˜!¤4Ô(€JÜ—‘˜!¤4Ô(€Ià€HØ€JØ€Hä�1ŽXˆØ%Ð-‘$´4¸ÀA¹Ó3GˆÙð �HŠ} ¨!¡¨zÒ!9Ø% a™[�
Ø# s¨^Ñ';Ñ<ˆJØ" 1™¨Ñ3ˆIñ ˜\¨!š_±'Ø!�Ø#�	˜!‘Ø �
Ø‘à˜QÒ¡GØ!�Ø $�
˜1‘Ø& q™\�
Ø ™U�Ù!‘A qˆˆqŠ	ð/ ð2 �:˜yÐ(Ð(ó    c                 ón  ‡ — ‰ j                  «       Š ‰ j                  j                  j                  «       j                  j	                  «       ‰ _        t        |j                  dd«      «      }|dkD  rAg d¢}|D ]8  }|‰ j                  v sŒ‰ |   j                  |d¬«      j                  «       ‰ |<   Œ: d“ˆ fd„	} |d«      } |d«      } |d«      } |d	«      }	 |d
«      }
 |d«      } |d«      } |d«      } |d«      } |d«      } |d«      } |d«      } |d«      } |d«      } |dd«      } |d«      } |d«      } |d«      }‰ d   j                  j                  t        j                  «      }‰ d   j                  j                  t        j                  «      }|j                  dd«      }|j                  dd«      }|j                  dd «      }|j                  d!d"«      }|j                  d#d$«      }|j                  d%d&«      }|j                  d'd"«      } |j                  d(d)«      }!|j                  d*d+«      }"|j                  d,d-«      }#|j                  d.d"«      }$|j                  d/d0«      }%|j                  d1d2«      }&|j                  d3d4«      }'|j                  d5d6«      }(|j                  d7d"«      })|j                  d8d"«      }*|j                  d9d"«      }+|j                  d:d"«      },|j                  d;d"«      }-|j                  d<d"«      }.|j                  d=d"«      }/|j                  d>d"«      }0|j                  d?d"«      }1|j                  d@d"«      }2|j                  dAd"«      }3|j                  dBd"«      }4|j                  dCd"«      }5|j                  dDd"«      }6|j                  dEd"«      }7|j                  dFd"«      }8|j                  dGd"«      }9|j                  dHd"«      }:|j                  dId"«      };|j                  dJd"«      }<|j                  dKd"«      }=|j                  dLd"«      }>|j                  dMd"«      }?|j                  dNd"«      }@|j                  dOd"«      }A|j                  dPd"«      }B|j                  dQd"«      }C|j                  dRd"«      }D|j                  dSd"«      }E|j                  dTd"«      }F|j                  dUd"«      }G|j                  dVd"«      }H|j                  dWd"«      }I|j                  dXd"«      }J |dY«      }K |dZ«      }L |d[«      }M |d\«      }N |d]«      }O |d^«      }P |d_«      }Q |d`«      }R |da«      }S |db«      }T |dc«      }U |dd«      }V |de«      }W |df«      }X |dg«      }Y |dh«      }Z |di«      }[ |dj«      }\ |dk«      }] |dl«      }^ |dm«      }_ |dn«      }` |do«      }a |dp«      }b |dq«      }c |dr«      }d |ds«      }e |dt«      }f |du«      }g |dv«      }h |dw«      }i||z  ||z  z   ||z  z   |	|z  z   |
|z  z   ||z  z   || z  z   ||!z  z   ||"z  z   ||#z  z   ||$z  z   ||%z  z   ||(z  z   ||'z  z   ||&z  z   ||)z  z   ||*z  z   ||+z  z   |K|,z  z   |L|-z  z   |M|.z  z   |N|/z  z   |O|0z  z   |P|1z  z   |Q|2z  z   |R|3z  z   |S|4z  z   |T|5z  z   |U|6z  z   |V|7z  z   |W|8z  z   |X|9z  z   |Y|:z  z   |Z|;z  z   |[|<z  z   |\|=z  z   |]|>z  z   |^|?z  z   |_|@z  z   |`|Az  z   |a|Bz  z   |b|Cz  z   |c|Dz  z   |d|Ez  z   |e|Fz  z   |f|Gz  z   |g|Hz  z   |h|Iz  z   |i|Jz  z   }jt        |«      t        |«      z   t        |«      z   t        |«      z   t        |«      z   t        |«      z   t        | «      z   t        |!«      z   t        |"«      z   t        |#«      z   t        |$«      z   t        |%«      z   t        |(«      z   t        |'«      z   t        |&«      z   t        |)«      z   t        |*«      z   t        |+«      z   t        |,«      z   t        |-«      z   t        |.«      z   t        |/«      z   t        |0«      z   t        |1«      z   t        |2«      z   t        |3«      z   t        |4«      z   t        |5«      z   t        |6«      z   t        |7«      z   t        |8«      z   t        |9«      z   t        |:«      z   t        |;«      z   t        |<«      z   t        |=«      z   t        |>«      z   t        |?«      z   t        |@«      z   t        |A«      z   t        |B«      z   t        |C«      z   t        |D«      z   t        |E«      z   t        |F«      z   t        |G«      z   t        |H«      z   t        |I«      z   t        |J«      z   }k|kdxkD  rjkz  dyz  }jj‰ dz<   |j                  d{d|«      }l|j                  d}d~«      }m|j                  dd€«      }n|j                  d�d4«      }o|j                  d‚dƒ«      }p‰ dz   }qt        |j                  d„dx«      «      }rt        |j                  d…d†«      «      }s|rdxkD  r%qj                  rd¬‡«      j                  «       skD  }tn!t!        j"                  dˆ‰ j$                  ¬‰«      }tt'        |j                  dŠdƒ«      «      }u|urd‹‰ j                  v rt‰ d‹   dxk\  z  }tor0qj)                  dŒ«      mk\  |qj)                  d«      |mk  z  |qnk  z  }vnPt!        j"                  |dxk7  ‰ j$                  ¬‰«      }wqj)                  dŒ«      mk\  |qj)                  d«      |mk  z  |wz  }vprTqj)                  dŒ«      lk\  |qj)                  d«      |lk  z  |q|qj)                  d«      kD  z  vj)                  ddƒ¬�«       z  }xnqj)                  d«      lk\  |q|lk  z  }xxtz  }xt        |j                  dŽd"«      «      d�z  }y|yd"kD  rlt+        xj-                  dƒ«      j                  j                  t&        «      vj-                  dƒ«      j                  j                  t&        «      ||y«      \  }z}{}|nht/        xj-                  dƒ«      j                  j                  t&        «      vj-                  dƒ«      j                  j                  t&        «      «      \  }z}{}|zj                  t
        «      ‰ d�<   {‰ d‘<   |‰ d’<   ‰ S )”aê  
    Generates entry/exit signals using the activation score framework.

    Reads pre-calculated component values from the TradingView export (TV_Export.csv),
    applies proper normalization via calculate_activation_score_poc (matching the
    Pine Script library function), then implements the same crossunder entry/exit
    logic as the Pine Script strategy.

    Parity notes:
    - Prefers non-DB_ columns (which match the inputs used to compute activation_score_poc).
    - Falls back to DB_ columns if non-DB columns are absent.
    - Entry:  score crosses FROM ABOVE to BELOW i_long_entry_activation_threshold
              (Pine: ta.crossunder(activation_score_poc, entry_threshold))
    - Exit:   score crossed under i_long_exit_activation_threshold one bar ago
              AND current score < i_long_exit_activation_confirmation_threshold
              (Pine: ta.crossunder(activation_score_poc[1], exit_threshold)
                     AND activation_score_poc < exit_conf_threshold)
    Úi_div_windowr   )
Ú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)Úmin_periodsc                 óô   •— | ‰j                   v r‰|    j                  d«      j                  S |r,|‰j                   v r‰|   j                  d«      j                  S t        j                  t        ‰«      «      S )zLReturn column values, preferring primary over fallback, defaulting to zeros.r   )ÚcolumnsÚfillnaÚvaluesr   r   r   )ÚprimaryÚfallbackÚdfs     €r)   Úget_colz!generate_signals.<locals>.get_col’   sf   ø€ à�b—j‘jÑ Ø�g‘;×%Ñ% aÓ(×/Ñ/Ð/Ù˜ B§J¡JÑ.Ø�h‘<×&Ñ& qÓ)×0Ñ0Ð0Ü�x‰xœ˜B›Ó Ð r+   Ú
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Úm2_div_normÚm2_nooff_normÚbearish_engulfing_scoreÚ
db_bearishÚbullish_hammer_scoreÚbullish_engulfing_scoreÚshooting_star_scoreÚcloseÚhighÚ	i_w_stochg®Gáz@Úi_w_macd_predg     @Q@Úi_w_oscgffffffÀÚi_w_totalvolr   Úi_w_m3_momentumg®Ø_vOæ?Úi_w_m2_tinyg      Q@Úi_w_newaddrÚi_w_stoch_div_oscgìQ¸…ëÀÚi_w_vwap_div_oscg      7@Úi_w_stoch_peakingg
×£p=
ÀÚi_w_sendaddrÚi_w_m3_div_oscgÉv¾Ÿ/	ÀÚi_w_m2_div_oscg      K@Úi_w_m2_div_osc_noOffsetr   Úi_w_bearish_engulfingg     €C@Ú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Ú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Úqqq_spy_roc_signr.   r/   r0   r1   r2   r3   r4   r5   r6   r7   Úoi_roc_normÚusdt_d_normÚ
basis_normÚfear_greed_normÚbtc_gold_normÚrsi_subtf_normr   ç     @�@Ú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_confirmationÚi_use_long_entry_confirmationFÚi_regime_windowÚi_regime_entry_min_scoreg     @�À)Úwindowr8   T)ÚindexÚi_mvrv_suppress_bearÚmvrv_regimeé   )Ú
fill_valueÚi_trailing_stop_thresholdç      Y@r"   Úexecute_entryÚexecute_exit©N)Úcopyr:   ÚstrÚlowerÚstripÚintÚgetÚrollingÚmaxr<   Úastyper   Úfloat64ÚabsÚfloatÚmeanÚpdÚSeriesr¦   r   Úshiftr*   r;   r   )}r?   ÚparamsÚ_div_windowÚ
_rsid_colsÚ_colr@   Ústoch_nÚmacd_pred_nÚosc_nÚ
totalvol_nÚm3_mom_nÚ	m2_tiny_nÚ	newaddr_nÚstoch_div_nÚ
vwap_div_nÚstoch_peak_nÚ
sendaddr_nÚm3_div_nÚm2_div_nÚ
m2_nooff_nÚ	bearish_nÚ
bull_ham_nÚ
bull_eng_nÚstar_nr   r   Úw_stochÚw_macd_predÚw_oscÚ
w_totalvolÚw_m3_momentumÚ	w_m2_tinyÚ	w_newaddrÚw_stoch_div_oscÚw_vwap_div_oscÚw_stoch_peakingÚ
w_sendaddrÚw_m3_div_oscÚw_m2_div_oscÚw_m2_div_osc_nooffsetÚw_bearish_engulfingÚw_bullish_hammerÚw_bullish_engulfingÚw_shooting_starÚw_btc_spx_corrÚw_dxyÚw_vixÚ	w_btc_domÚw_us10yÚw_spyÚw_goldÚw_mvrvÚw_mvrv_contÚw_nuplÚw_fed_net_liqÚw_gc_positionÚw_us2yÚw_yield_curveÚw_qqq_spy_ratioÚw_rsid_reg_bullÚw_rsid_reg_bearÚw_rsid_hid_bullÚw_rsid_hid_bearÚw_rsid_rt_bullÚw_rsid_rt_bearÚw_rsid_slow_bullÚw_rsid_slow_bearÚw_rsid_delayed_peakÚw_rsid_delayed_dipÚw_oi_rocÚw_usdt_dÚw_basisÚw_fear_greedÚ
w_btc_goldÚw_rsi_subtfÚbtc_spx_corrrˆ   Ú
vix_pr_invÚbtc_dom_signÚus10y_inv_signÚ
spy_200emaÚgold_pctrankÚmvrv_zscore_valr�   r�   r‘   r’   Úus2y_inv_signÚyield_curve_nÚ	qqq_spy_nÚrsid_reg_bull_nÚrsid_reg_bear_nÚrsid_hid_bull_nÚrsid_hid_bear_nÚrsid_rt_bull_nÚrsid_rt_bear_nÚrsid_slow_bull_nÚrsid_slow_bear_nÚrsid_dpeak_nÚrsid_ddip_nÚoi_roc_nÚusdt_d_nÚbasis_nÚfear_greed_nÚ
btc_gold_nÚrsi_subtf_nÚscoresÚ	max_scoreÚentry_thresholdÚexit_thresholdÚexit_conf_thresholdÚuse_exit_confÚuse_entry_confÚscoreÚregime_windowÚ
regime_minÚ	regime_okÚsuppress_bearÚexit_rawÚ
stoch_peakÚ	entry_rawr   r   r    r!   s}   `                                                                                                                            r)   Úgenerate_signalsr0  h   s%  ø€ ð& 
�‰‹€BØ—‘—‘×%Ñ%Ó'×+Ñ+×1Ñ1Ó3€B„Jô �f—j‘j °Ó3Ó4€KØ�Q‚ò
ˆ
ó ˆDØ�r—z‘zÒ!Ø˜d™8×+Ñ+¨KÀQÐ+ÓG×KÑKÓM��4’ð õ!ñ ˜<Ó(€GÙÐ+Ó,€KÙ˜:Ó&€EÙ˜?Ó+€JÙÐ-Ó.€HÙ˜>Ó*€IÙ˜>Ó*€IÙÐ+Ó,€KÙ˜?Ó+€JÙÐ,Ó-€LÙ˜?Ó+€JÙ˜=Ó)€HÙ˜=Ó)€HÙ˜?Ó+€JÙÐ4°lÓC€IÙÐ1Ó2€JÙÐ4Ó5€JÙÐ0Ó1€Fà�7‘×"Ñ"×)Ñ)¬"¯*©*Ó5€IØ�6‘
×!Ñ!×(Ñ(¬¯©Ó4€Hð #ŸJ™J {À$ÓG€GØ"ŸJ™J À$ÓG€KØ"ŸJ™J yÀ$ÓG€EØ"ŸJ™J ~À#ÓF€JØ"ŸJ™JÐ'8À&ÓI€MØ"ŸJ™J }À$ÓG€IØ"ŸJ™J }À#ÓF€IØ"ŸJ™JÐ':À%ÓH€OØ"ŸJ™JÐ'9À$ÓG€NØ"ŸJ™JÐ':À%ÓH€OØ"ŸJ™J ~À#ÓF€JØ"ŸJ™JÐ'7À&ÓI€LØ"ŸJ™JÐ'7À$ÓG€LØ"ŸJ™JÐ'@À#ÓFÐØ"ŸJ™JÐ'>À$ÓGÐØ"ŸJ™JÐ';À3ÓGÐØ"ŸJ™JÐ'>À3ÓGÐØ"ŸJ™JÐ':À3ÓG€OØ"ŸJ™JÐ'9À3ÓG€NØ"ŸJ™J yÀ3ÓG€EØ"ŸJ™J yÀ3ÓG€EØ"ŸJ™J }À3ÓG€IØ"ŸJ™J {À3ÓG€GØ"ŸJ™J yÀ3ÓG€EØ"ŸJ™J zÀ3ÓG€FØ"ŸJ™J zÀ3ÓG€FØ"ŸJ™J À3ÓG€KØ"ŸJ™J zÀ3ÓG€FØ"ŸJ™JÐ'8À3ÓG€MØ"ŸJ™JÐ'8À3ÓG€MØ"ŸJ™J zÀ3ÓG€FØ"ŸJ™JÐ'8À3ÓG€MØ"ŸJ™JÐ':À3ÓG€OØ"ŸJ™JÐ':À3ÓG€OØ"ŸJ™JÐ':À3ÓG€OØ"ŸJ™JÐ':À3ÓG€OØ"ŸJ™JÐ':À3ÓG€OØ"ŸJ™JÐ'9À3ÓG€NØ"ŸJ™JÐ'9À3ÓG€NØ"ŸJ™JÐ';À3ÓGÐØ"ŸJ™JÐ';À3ÓGÐØ"ŸJ™JÐ'>À3ÓGÐØ"ŸJ™JÐ'=À3ÓGÐØ"ŸJ™J |À3ÓG€HØ"ŸJ™J |À3ÓG€HØ"ŸJ™J {À3ÓG€GØ"ŸJ™JÐ'7À3ÓG€LØ"ŸJ™J ~À3ÓG€JØ"ŸJ™J À3ÓG€Kñ Ð0Ó1€LÙ˜~Ó.€LÙÐ0Ó1€JÙÐ1Ó2€LÙÐ3Ó4€NÙÐ1Ó2€JÙÐ1Ó2€LÙÐ2Ó3€OÙÐ1Ó2ÐÙ˜{Ó+€IÙÐ1Ó2ÐÙ˜}Ó-€KÙÐ2Ó3€MÙÐ1Ó2€MÙÐ1Ó2€IÙÐ3Ó4€OÙÐ3Ó4€OÙÐ3Ó4€OÙÐ3Ó4€OÙÐ2Ó3€NÙÐ2Ó3€NÙÐ4Ó5ÐÙÐ4Ó5ÐÙÐ7Ó8€LÙÐ6Ó7€Kñ ˜}Ó-€HÙ˜}Ó-€HÙ˜|Ó,€GÙÐ0Ó1€LÙ  Ó1€JÙÐ/Ó0€Kð 	�wÑØ�{Ñ"ñ	#à�uÑñ	ð 	�zÑ!ñ	"ð 	�}Ñ$ñ		%ð
 	�yÑ ñ	!ð 	�yÑ ñ	!ð 	�Ñ&ñ	'ð 	�~Ñ%ñ	&ð 	�Ñ&ñ		'ð 	�zÑ!ñ
	"ð 	�|Ñ#ñ	$ð 	Ð*Ñ*ñ	+ð 	Ð,Ñ,ñ	-ð 	�|Ñ#ñ	$ð 	Ð'Ñ'ñ	(ð  	Ð*Ñ*ñ!	+ð" 	�Ñ&ñ#	'ð$ 	�~Ñ%ñ%	&ð& 	�uÑñ'	ð( 	�uÑñ)	ð* 	�yÑ ñ+	!ð, 	˜Ñ ñ-	!ð. 	�uÑñ/	ð0 	�vÑñ1	ð2 	˜6Ñ!ñ3	"ð4 	˜;Ñ&ñ5	'ð6 	�vÑñ7	ð8 	˜=Ñ(ñ9	)ð: 	�}Ñ$ñ;	%ð< 	˜Ññ=	ð> 	˜Ñ%ñ?	&ð@ 	�Ñ&ñA 	'ðB 	˜?Ñ*ñC!	+ðD 	˜?Ñ*ñE"	+ðF 	˜?Ñ*ñG#	+ðH 	˜?Ñ*ñI$	+ðJ 	˜>Ñ)ñK%	*ðL 	˜>Ñ)ñM&	*ðN 	Ð+Ñ+ñO'	,ðP 	Ð+Ñ+ñQ(	,ðR 	Ð.Ñ.ñS)	/ðT 	Ð-Ñ-ñU*	.ðV 	˜8Ñ#ñW+	$ðX 	˜8Ñ#ñY,	$ðZ 	˜7Ñ"ñ[-	#ð\ 	˜<Ñ'ñ].	(ð^ 	˜:Ñ%ñ_/	&ð` 	˜;Ñ&ña0	'ð ôh 	ˆG‹”s˜;Ó'Ñ'¬#¨e«*Ñ4´s¸:³ÑFÜˆMÓñ	Ü  ›^ñ	,Ü.1°)«nñ	=Ü?BÀ?Ó?Sñ	TäˆNÓñ	ä! /Ó2ñ	3ä58¸³_ñ	EäGJÈ<ÓGXñ	Yô 	ÐÓ ñ	!ô $'Ð'<Ó#=ñ	>ô ADÀLÓ@Qñ	Rô 	ÐÓñ		ô !$Ð$7Ó 8ñ		9ô <?¸Ó;Oñ		Pô
 	ˆNÓñ	ô
 " %›jñ	)ô
 ,/¨u«:ñ	6ô
 9<¸I»ñ	Gô 	ˆG‹ñ	ô ˜5“zñ	"ô %(¨£Kñ	0ô 	ˆF‹ñ	ô ˜+Ó&ñ	'ô *-¨V«ñ	5ô 	ˆMÓñ	ô ! Ó/ñ	0ô 	ˆF‹ñ		ô ˜-Ó(ñ		)ô ,/¨Ó+?ñ		@ô 	ˆOÓñ
	ô  # ?Ó3ñ
	4ô 	ˆOÓñ	ô  # ?Ó3ñ	4ô 	ˆNÓñ	ô  # >Ó2ñ	3ô 	ÐÓñ	ô !$Ð$4Ó 5ñ	6ô 	ÐÓ ñ	!ô $'Ð'9Ó#:ñ	;ô 	ˆH‹ñ	ô ˜H›ñ	&ô ),¨G«ñ	5ô  	ˆLÓñ!	ô    
›Oñ!	,ô  /2°+Ó.>ñ!	?ð ð& �1‚}Ø˜)Ñ# fÑ,ˆØ#€BÐÑð !Ÿ*™*Ð%HÐW\Ó]€OØ Ÿ*™*Ð%GÐW\Ó]€NØ Ÿ*™*Ð%TÐW^Ó_ÐØ Ÿ*™*Ð%CÐWZÓ[€MØ Ÿ*™*Ð%DÐW\Ó]€NàÐ!Ñ"€Eô ˜Ÿ
™
Ð#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ˆ	ñ à�[‰[˜‹^˜~Ñ-Ø�[‰[˜‹^˜nÑ,ñ.àÐ(Ñ(ñ*ñ 	ô —Y‘Y˜|¨qÑ0¸¿¹ÔAˆ
à�[‰[˜‹^˜~Ñ-Ø�[‰[˜‹^˜nÑ,ñ.àñð 	ñ ð �[‰[˜‹^˜Ñ.Ø�[‰[˜‹^˜oÑ-ñ/à�U—[‘[ “^Ñ#ñ%ð �^‰^˜A¨%ˆ^Ó0Ð0ñ1ñ 	ð —[‘[ “^ Ñ6¸5À?Ñ;RÑSˆ	ð ˜IÑ%€Iô ˜6Ÿ:™:Ð&AÀ3ÓGÓHÈ5ÑP€NØ˜ÒÜ(<Ø×Ñ˜UÓ#×*Ñ*×1Ñ1´$Ó7Ø�O‰O˜EÓ"×)Ñ)×0Ñ0´Ó6ØØØó)
Ñ%ˆ�
™Iô )<Ø×Ñ˜UÓ#×*Ñ*×1Ñ1´$Ó7Ø�O‰O˜EÓ"×)Ñ)×0Ñ0´Ó6ó)
Ñ%ˆ�
˜Ið
 !Ÿ-™-¬Ó,€B€z�NØ$€B€ÑØ#€B€~Ñà€Ir+   )Úraw_metricsc          	      ó`  — ddl m} | j                  rdddddddddœS |�ed| v rat        j                  | j
                  d¬	«      t        j                  |d¬	«      k\  j                  «       st        | j                  dd |¬
«      S  || d| v r|nd¬«      }|�|j                  |«       |d   }|€•d| v r‚t        j                  | j
                  d¬	«      }|�||t        j                  |d¬	«      k\     }t        d|j                  d   |j                  d   z
  j                  dz  «      }t        |«      }	n|�t        nt        }	n|}	||	k\  }
t        |d   «      }|
r|dkD  r
|d   �|d   nd}||d   |
r
|d   �|d   nd|
r
|d   �|d   nd||
rd|cxk  rdk  rn n|d   |z  nd|d   |d   dœS )a=  Calendar-correct measurements with the existing optimizer eligibility rules.

    Signals are unchanged. Scoring retains carry-in returns and marks open trades
    to market using the historical additive fee convention. When supplied,
    raw_metrics receives the same accounting result for diagnostic reporting.
    r   )Úwindow_metricsr   ç      $À)zTotal TradeszTotal P&L %zSharpe RatiozSortino RatiozCalmar RatiozP&L/DD RatiozMax Drawdown %z% In MarketNÚtimeT)Úutc)Ú
min_trades)ÚstartÚentriesç      à?r   g     Ôv@Údd_pctgš™™™™™¹?ÚcalmarÚpnl_pctÚsharpeÚsortinog      D@Úexposure_pct)Ústrategies.mlp_accountingr3  Úemptyr½   Úto_datetimer5  ÚanyÚcalculate_metricsÚilocÚupdater·   Údaysr   ÚMIN_SCORABLE_TRADESÚ
MIN_TRADESrº   )r?   Úscore_startr7  r1  r3  ÚmetricsÚtradesÚtimesÚfloor_yearsÚmin_requiredÚeligibleÚddr<  s                r)   rE  rE  µ  sã  € õ 9à	‡x‚xØ !°#Ø %¸ÈuØ #°sÈ3ñPð 	Pð Ð 6¨R¡<Ü—‘˜rŸw™w¨DÔ1´R·^±^ÀKÐUYÔ5ZÑZ×_Ñ_ÔaÜ$ R§W¡W¨R¨a [¸ZÔHÐHÙ˜R°fÀ±l¡{ÈÔM€GØÐØ×Ñ˜7Ô#Ø�YÑ€FØÐð �R‰<Ü—N‘N 2§7¡7°Ô5ˆEØÐ&Ø˜e¤r§~¡~°kÀtÔ'LÑLÑM�Ü˜b 5§:¡:¨b¡>°E·J±J¸q±MÑ#A×"GÑ"GÈ&Ñ"PÓQˆKÜ)¨+Ó6‰Là2=Ð2IÕ.Ìz‰Là!ˆØ˜Ñ%€HÜ	ˆW�XÑÓ	€BÙ"*¨r°Bªw¸7À8Ñ;LÐ;XˆW�XÒÐ^b€Fà¨w°yÑ/AÙ-5¸'À(Ñ:KÐ:W˜ Ò)Ð]aÙ/7¸GÀIÑ<NÐ<Z˜ Ò+Ð`dØÙ3;ÀÀbÄÈCÅ˜ 	Ñ*¨RÒ/ÐUWØ! (Ñ+¸GÀNÑ<Sñð r+   c                 óÖ  ‡ — ‰ j                  «       Š ‰ j                  j                  j                  «       j                  j	                  «       ‰ _        d5ˆ fd„	}|�Ft        j                  |D �cg c]
  } ||«      ‘Œ c}«      j                  t
        j                  «      S g  |d«      ‘ |d«      ‘ |d«      ‘ |d«      ‘ |d«      ‘ |d«      ‘ |d«      ‘ |d	«      ‘ |d
«      ‘ |d«      ‘ |d«      ‘ |d«      ‘ |dd«      ‘ |d«      ‘ |d«      ‘ |d«      ‘ |d«      ‘ |d«      ‘ |d«      ‘ |d«      ‘ |d«      ‘ |d«      ‘ |d«      ‘ |d«      ‘ |d«      ‘ |d«      ‘ |d«      ‘ |d«      ‘ |d«      ‘ |d «      ‘ |d!«      ‘ |d"«      ‘ |d#«      ‘ |d$«      ‘ |d%«      ‘ |d&«      ‘ |d'«      ‘ |d(«      ‘ |d)«      ‘ |d*«      ‘ |d+«      ‘ |d,«      ‘ |d-«      ‘ |d.«      ‘ |d/«      ‘ |d0«      ‘ |d1«      ‘ |d2«      ‘ |d3«      ‘ |d4«      ‘}t        j                  |«      j                  t
        j                  «      S c c}w )6u°  
    Reads pre-normalised indicator columns from the TV-exported CSV and returns
    a float64 (T x N) array ready for the GPU kernel / MLP forward pass.

    All columns are already in [-1, +1] â€” Pine exports the normalised form.
    No normalisation is performed here.  Column order must match i_w_* key
    order in params_strategy_activation_scores.json.

    feature_cols: if provided, build the matrix from exactly those column names
    (in order), falling back to 0 for any missing column.  When None, uses the
    full hardcoded 49/50-column list below (perceptron / GPU kernel path).

    col 0  â†’ i_w_stoch               â†’ stoch_norm
    col 1  â†’ i_w_macd_pred           â†’ macd_pred_norm
    col 2  â†’ i_w_osc                 â†’ osc_norm
    col 3  â†’ i_w_totalvol            â†’ totalvol_norm
    col 4  â†’ i_w_m3_momentum         â†’ m3_momentum_norm
    col 5  â†’ i_w_m2_tiny             â†’ m2_tiny_norm
    col 6  â†’ i_w_newaddr             â†’ newaddr_norm
    col 7  â†’ i_w_stoch_div_osc       â†’ stoch_div_norm
    col 8  â†’ i_w_vwap_div_osc        â†’ vwap_div_norm
    col 9  â†’ i_w_stoch_peaking       â†’ stoch_peak_norm
    col 10 â†’ i_w_sendaddr            â†’ sendaddr_norm
    col 11 â†’ i_w_m3_div_osc          â†’ m3_div_norm
    col 12 â†’ i_w_bearish_engulfing   â†’ bearish_engulfing_score
    col 13 â†’ i_w_m2_div_osc_noOffset â†’ m2_nooff_norm
    col 14 â†’ i_w_m2_div_osc          â†’ m2_div_norm
    col 15 â†’ i_w_bullish_hammer      â†’ bullish_hammer_score
    col 16 â†’ i_w_bullish_engulfing   â†’ bullish_engulfing_score
    col 17 â†’ i_w_shooting_star       â†’ shooting_star_score
    col 18 â†’ i_w_btc_spx_corr        â†’ btc_spx_corr_30
    col 19 â†’ i_w_dxy                 â†’ dxy_roc_norm
    col 20 â†’ i_w_vix                 â†’ vix_pctrank_inv
    col 21 â†’ i_w_btc_dom             â†’ btc_dom_roc_sign
    col 22 â†’ i_w_us10y               â†’ us10y_roc_inv_sign
    col 23 â†’ i_w_spy                 â†’ spy_above_200ema
    col 24 â†’ i_w_gold                â†’ gold_roc_pctrank
    col 25 â†’ i_w_mvrv                â†’ mvrv_zscore_value
    col 26 â†’ i_w_mvrv_cont           â†’ mvrv_zscore_cont
    col 27 â†’ i_w_nupl                â†’ nupl_norm
    col 28 â†’ i_w_fed_net_liq         â†’ fed_net_liq_sign
    col 29 â†’ i_w_gc_position         â†’ gc_position
    col 30 â†’ i_w_us2y                â†’ us2y_roc_inv_sign
    col 31 â†’ i_w_yield_curve         â†’ yield_curve_sign
    col 32 â†’ i_w_qqq_spy_ratio       â†’ qqq_spy_roc_sign
    col 33 â†’ i_w_rsid_reg_bull       â†’ rsid_reg_bull_norm
    col 34 â†’ i_w_rsid_reg_bear       â†’ rsid_reg_bear_norm
    col 35 â†’ i_w_rsid_hid_bull       â†’ rsid_hid_bull_norm
    col 36 â†’ i_w_rsid_hid_bear       â†’ rsid_hid_bear_norm
    col 37 â†’ i_w_rsid_rt_bull        â†’ rsid_rt_bull_norm
    col 38 â†’ i_w_rsid_rt_bear        â†’ rsid_rt_bear_norm
    col 39 â†’ i_w_rsid_slow_bull      â†’ rsid_slow_bull_norm
    col 40 â†’ i_w_rsid_slow_bear      â†’ rsid_slow_bear_norm
    col 41 â†’ i_w_rsid_delayed_peak   â†’ rsid_delayed_peak_norm
    col 42 â†’ i_w_rsid_delayed_dip    â†’ rsid_delayed_dip_norm
    col 43 â†’ i_w_oi_roc              â†’ oi_roc_norm
    col 44 â†’ i_w_usdt_d              â†’ usdt_d_norm
    col 45 â†’ i_w_basis               â†’ basis_norm
    col 46 â†’ i_w_fear_greed          â†’ fear_greed_norm
    col 47 â†’ i_w_btc_gold            â†’ btc_gold_norm
    col 48 â†’ i_w_rsi_subtf           â†’ rsi_subtf_norm
    c                 óˆ  •— | ‰j                   v r;‰|    j                  d«      j                  j                  t        j
                  «      S |rI|‰j                   v r;‰|   j                  d«      j                  j                  t        j
                  «      S t	        j                  t        ‰«      t        j
                  ¬«      S )Nr   r   )r:   r;   r<   r¸   r   r¹   r   r   )Úcolr>   r?   s     €r)   rµ   z_prepare_features.<locals>.getV  sˆ   ø€ Ø�"—*‘*ÑØ�c‘7—>‘> !Ó$×+Ñ+×2Ñ2´2·:±:Ó>Ð>Ù˜ B§J¡JÑ.Ø�h‘<×&Ñ& qÓ)×0Ñ0×7Ñ7¼¿
¹
ÓCÐCÜ�x‰xœ˜B›¤r§z¡zÔ2Ð2r+   rA   rB   rC   rD   rE   rF   rG   rH   rI   rJ   rK   rL   rO   rP   rN   rM   rQ   rR   rS   r‡   rˆ   r‰   rŠ   r‹   rŒ   r�   rŽ   r�   r�   r‘   r’   r“   r”   r•   r.   r/   r0   r1   r2   r3   r4   r5   r6   r7   r–   r—   r˜   r™   rš   r›   Úbb_pct_b_normr¯   )	r°   r:   r±   r²   r³   r   Úcolumn_stackr¸   r¹   )r?   Úfeature_colsrµ   ÚcÚcolss   `    r)   Ú_prepare_featuresr[    sÕ  ø€ ð~ 
�‰‹€BØ—‘—‘×%Ñ%Ó'×+Ñ+×1Ñ1Ó3€B„Jõ3ð ÐÜ�‰±Ó=±¨1¡ A¥°Ñ=Ó>×EÑEÄbÇjÁjÓQÐQð3ÙˆLÓð3áÐÓð3ñ 	ˆJ‹ð3ñ 	ˆOÓð	3ñ
 	ÐÓð3ñ 	ˆNÓð3ñ 	ˆNÓð3ñ 	ÐÓð3ñ 	ˆOÓð3ñ 	ÐÓð3ñ 	ˆOÓð3ñ 	ˆMÓð3ñ 	Ð% |Ó4ð3ñ 	ˆOÓð3ñ 	ˆMÓð3ñ  	Ð"Ó#ð!3ñ" 	Ð%Ó&ð#3ñ$ 	Ð!Ó"ð%3ñ& 	ÐÓð'3ñ( 	ˆNÓð)3ñ* 	ÐÓð+3ñ, 	ÐÓð-3ñ. 	Ð Ó!ð/3ñ0 	ÐÓð13ñ2 	ÐÓð33ñ4 	ÐÓ ð53ñ6 	ÐÓð73ñ8 	ˆKÓð93ñ: 	ÐÓð;3ñ< 	ˆMÓð=3ñ> 	ÐÓ ð?3ñ@ 	ÐÓðA3ñB 	ÐÓðC3ñD 	Ð Ó!ðE3ñF 	Ð Ó!ðG3ñH 	Ð Ó!ðI3ñJ 	Ð Ó!ðK3ñL 	ÐÓ ðM3ñN 	ÐÓ ðO3ñP 	Ð!Ó"ðQ3ñR 	Ð!Ó"ðS3ñT 	Ð$Ó%ðU3ñV 	Ð#Ó$ðW3ñX 	ˆMÓðY3ñZ 	ˆMÓð[3ñ\ 	ˆLÓð]3ñ^ 	ÐÓð_3ñ` 	ˆOÓða3ñb 	ÐÓðc3ñd 	ˆOÓðe3€Dôj �?‰?˜4Ó ×'Ñ'¬¯
©
Ó3Ð3ùòq  >s   Á.I&c                 óä  — t        j                  d«      }||j                  d   k\  ry| j                  d   }	| j                  d   }
d}d}d}d}d}d}d}d}||df   }||df   }||df   }||df   d	z  }||df   d
kD  }||df   d
kD  }d}t        |
«      D ]  }|||f   }||dk\  r|n| z  }Œ |dk(  rd}d}t        |
«      D ]  }|| d|f   |||f   z  z  }Œ ||z  dz  }|}d}d}t        d|	«      D �]e  } d}!|r$|dkD  r||    |kD  r||    }|d|z
  z  }"||    |"k  rd}!d}#|r"|| dz
     dk7  r||    || dz
     z
  || dz
     z  }#||#z  }||#|#z  z  }|#dk  r||#|#z  z  }|d|#z   z  }||kD  r|}|dkD  r||z
  |z  nd}$|$|k  r|$}d}%t        |
«      D ]  }|%| | |f   |||f   z  z  }%Œ |%|z  dz  }%d}&d}'d}(||k\  xr ||k  })|)r|r|%|k  rd}(n| | df   dk  rd}(|s"|r||k\  r||k  r|%|kD  r|sd}&n||k\  r|%|k  rd}&|r|(s|!rd}'|r"|'rId}d}|dz  }|dkD  r||z
  |z  nd}$|$|k  r,|$}n)|&r'd}||    }|dz  }|dz  }|dkD  r||z
  |z  nd}$|$|k  r|$}|}|%}|(}�Œh |dz
  d	z  }*t	        |d	z  «      }+d},d}-|dk\  rQ|	dkD  rL|	dz
  }.||.z  }/||.z  |/|/z  z
  }0|0dkD  r|0d
z  nd}1|1dkD  r|/|1z  dz  },||.z  }2|2dkD  r|2d
z  nd}3|3dkD  r|/|3z  dz  }-|*||df<   |+||df<   |,||df<   |-||df<   |||df<   y)uE  
        GPU kernel: runs one complete backtest per thread (one parameter set per row
        of weights/thresholds/configs).

        features  â€” (T, 49) pre-normalised float64 feature matrix
        weights   â€” (N, 49) float64 weight vectors
        thresholds â€” (N, 4) float64: [entry_threshold, exit_threshold, exit_conf_threshold, trailing_stop_pct]
        configs   â€” (N, 2) float64: [use_exit_conf, use_entry_conf]
        close     â€” (T,) float64 close prices
        high      â€” (T,) float64 bar high prices (for trailing stop high-water mark)
        low       â€” (T,) float64 bar low prices  (for trailing stop trigger)
        results   â€” (N, 5) output: [total_pnl_pct, max_dd_pct, sharpe, sortino, trades]

        Signal logic (matches CPU generate_signals):
          Entry (conf=false): 1-bar crossunder â€” prev_score >= entry_thr AND score < entry_thr
          Entry (conf=true) : 2-bar crossunder â€” pprev_score >= entry_thr AND prev_score < entry_thr
                              AND score > prev_score (rising) AND NOT prev_exit_cond_raw
          Exit  : 2-bar crossunder + confirmation
                  pprev_score >= exit_thr AND prev_score < exit_thr
                  AND (score < exit_conf_thr  [if use_exit_conf]
                       OR  stoch_is_peaking  [otherwise, feature col 9 < -0.5])
        r   r   NFr   r   r©   é   r¬   r:  rœ   Té	   g      à¿g×£p=
×ï?r4  r
   g•Ö&è.>g^žŸ…ß3@é   )r	   ÚgridÚshaper   rº   )4ÚfeaturesÚweightsÚ
thresholdsÚconfigsrT   rU   ÚlowÚresultsÚidxÚTÚFÚin_positionrM  Úsum_retÚ
sum_sq_retÚsum_sq_neg_retÚequityÚpeak_equityÚmax_drawdownÚ	entry_thrÚexit_thrÚconf_thrr   r&  r'  r"  ÚfÚwÚ
prev_scoreÚpprev_scoreÚprev_exit_cond_rawr#   r%   Útrail_stop_hitÚstop_price_nowÚ	daily_retrR  r(  Úentry_signalÚexit_signalÚexit_cond_rawÚcrossedÚtotal_pnl_pctÚ
max_dd_pctr>  r?  r   Úmean_retÚvar_retÚstd_retÚdownside_varÚdownside_stds4                                                       r)   Ú_backtest_kernelrˆ  š  sØ  € ô0 �i‰i˜‹lˆØ�'—-‘- Ñ"Ò"Øà�N‰N˜1ÑˆØ�N‰N˜1ÑˆàˆØˆØˆØˆ
ØˆØˆØˆØˆà# C¨ FÑ+ˆ	Ø# C¨ FÑ+ˆØ# C¨ FÑ+ˆØ# C¨ FÑ+¨eÑ3ˆØ   a ™¨3Ñ.ˆØ   a ™¨3Ñ.ˆð ˆ	Ü�q–ˆAØ˜˜Q˜‘ˆAØ˜a 3šh™¨Q¨BÑ.‰Ið ð ˜ÒØˆIð ˆ
Ü�q–ˆAØ˜( 1 a 4™.¨7°3¸°6©?Ñ:Ñ:‰Jð à )Ñ+¨fÑ4ˆ
Ø ˆØ"ÐØˆ
ä�q˜!—ˆAð #ˆNÙ˜~°Ò3ð ˜‘7˜ZÒ'Ø!% a¡�JØ!+¨s°^Ñ/CÑ!D�Ø˜‘8˜~Ò-Ø%)�Nð ˆIÙ˜u Q¨¡U™|¨sÒ2Ø" 1™X¨¨a°!©e©Ñ4¸¸aÀ!¹e¹ÑD�	à�yÑ ˆGØ˜) iÑ/Ñ/ˆJØ˜3ŠØ )¨iÑ"7Ñ7�à�s˜Y‘Ñ'ˆFØ˜Ò#Ø$�Ø9DÀsÒ9J�&˜;Ñ&¨+Ò5ÐPSˆBØ�LÒ Ø!�ð ˆEÜ˜1–X�Ø˜ ! Q $™¨'°#°q°&©/Ñ9Ñ9‘ð à˜IÑ%¨Ñ.ˆEà ˆLØˆKð "ˆMØ! XÑ-ÒG°*¸xÑ2GˆGÙÙ Ø˜xÒ'Ø(,™ð    1 ‘~¨Ò,Ø(,˜ñ Ù!à" iÒ/°JÀÒ4JÈuÐWaÒOaÑj|Ø'+™ð " YÒ.°5¸9Ò3DØ'+˜ñ ¡±Ø"�áÙØ"'�KØ!$�Jà˜{Ñ+�FØALÈsÒAR˜& ;Ñ.°+Ò=ÐX[�BØ˜LÒ(Ø')™áØ"&�KØ!& q¡�JØ˜a‘K�Fà˜{Ñ+�FØALÈsÒAR˜& ;Ñ.°+Ò=ÐX[�BØ˜LÒ(Ø')˜à$ˆKØˆJØ!.Òðs ðx   #™¨Ñ.ˆÜ˜¨Ñ-Ó.ˆ
ØˆØˆð �RŠ<˜A šEØ�A‘ˆAØ ‘{ˆHØ! A‘~¨(°XÑ*=Ñ>ˆGØ(/°$ª�g ’n¸CˆGØ˜Š~Ø" WÑ,°Ñ>�Ø)¨AÑ-ˆLØ2>ÀÒ2E˜<¨3Ò.È3ˆLØ˜dÒ"Ø# lÑ2°|ÑD�à'ˆ��Q�‰Ø$ˆ��Q�‰Ø ˆ��Q�‰Ø!ˆ��Q�‰Ø ˆ��Q�Šr+   c                 óh  — | j                  «       } | j                  j                  j                  «       j                  j	                  «       | _        t        | «      }| d   j                  j                  t        j                  «      }| d   j                  j                  t        j                  «      }| d   j                  j                  t        j                  «      }t        j                  |«      t        j                  |«      t        j                  |«      t        j                  |«      dœS )zCNormalises features on CPU and uploads static data to the GPU once.rT   rU   rf  )rb  rT   rU   rf  )r°   r:   r±   r²   r³   r[  r<   r¸   r   r¹   r	   Ú	to_device)r?   rb  rT   rU   rf  s        r)   Úprepare_gpu_datar‹  O  sÒ   € à�W‰W‹YˆØ—Z‘Z—^‘^×)Ñ)Ó+×/Ñ/×5Ñ5Ó7ˆŒ
Ü$ RÓ(ˆØ�7‘×"Ñ"×)Ñ)¬"¯*©*Ó5ˆØ�6‘
×!Ñ!×(Ñ(¬¯©Ó4ˆØ�5‘	× Ñ ×'Ñ'¬¯
©
Ó3ˆäŸ™ xÓ0ÜŸ™ uÓ-ÜŸ™ tÓ,ÜŸ™ sÓ+ñ	
ð 	
r+   c           
      ó@  — |j                   d   }t        j                  |j                  t        j
                  «      «      }t        j                  |j                  t        j
                  «      «      }t        j                  |j                  t        j
                  «      «      }t        j                  t	        j                  |dft        j
                  ¬«      «      }d}	||	z   dz
  |	z  }
t        |
|	f   | d   |||| d   | d   | d	   |«       |j                  «       S )
z=Launches the backtest kernel for a batch of N parameter sets.r   é   r   é€   r   rb  rT   rU   rf  )	ra  r	   rŠ  r¸   r   r¹   r   rˆ  Úcopy_to_host)Úgpu_datarc  rd  re  ÚNÚ	d_weightsÚd_thresholdsÚ	d_configsÚ	d_resultsÚthreadsÚblockss              r)   Úexecute_gpu_batchr˜  ^  sâ   € à�M‰M˜!ÑˆÜ—~‘~ g§n¡n´R·Z±ZÓ&@ÓAˆ	Ü—~‘~ j×&7Ñ&7¼¿
¹
Ó&CÓDˆÜ—~‘~ g§n¡n´R·Z±ZÓ&@ÓAˆ	Ü—~‘~¤b§h¡h°°1¨v¼R¿Z¹ZÔ&HÓIˆ	àˆØ�w‘; ‘? wÑ.ˆÜ˜ ˜Ñ)Ø�ZÑ  )¨\¸9Ø�WÑ˜x¨Ñ/°¸%±À)ô	
ð ×%Ñ%Ó'Ð'r+   r¯   )NN)$Únumpyr   Úpandasr½   ÚosÚsysÚpathÚappendÚabspathÚjoinÚdirnameÚ__file__Úconfigr   Ú$strategies.library_activation_scoresr   r   r   r   r   Únumbar	   Úis_availableÚHAS_GPUÚ	ExceptionrJ  rI  ÚCOMMISSION_RATEr*   r0  rE  r[  Újitrˆ  r‹  r˜  © r+   r)   Ú<module>r¬     sð   ðÛ Û Û 	Û 
à ‡�‡��—‘—‘ §¡§¡¨R¯W©W¯_©_¸XÓ-FÈÓ MÓNÔ OÝ !÷õ ð
ÝØˆd×ÑÓ!€Gð €
ð Ð ð €ð &*ó?)òDJðZ
+ÈDô +ó~B4ñJ Ø	‡X�Xñr!ó ðr!òh
ó(ðK øðS ò Ø‚Gðús   ÂC ÃC#Ã"C#