Ë
    )rƒj¤
  ã                  ó¶  — d Z ddlmZ ddlZddlZddlZddlZej                  j                  ej                  j                  e«      «      Zej                  j                  e«      Zej                  j                  de«       ej                  j!                  ed«      Zej                  j!                  ed«      Zdd„Zdd„Zdd„Zddd	„Zed
k(  r e«        yy)uÌ   Fixed data prep + evaluation for the autoresearch loop.

FROZEN â€” the research agent never edits this file (see program.md).
Run once to build the price cache:  .venv/bin/python autoresearch/prepare.py
é    )ÚannotationsNz	close.csvz
volume.csvc                 óB  — dd l } ddlm}  |«       }| j                  |dd¬«      }|d   j	                  dt        t        |«      dz  «      ¬	«      }|d
   |j                     }|j                  «       j                  t        «       |j                  t        «       t        d|j                  d   › d|j                  d   › d|j                  d   j                  «       › d|j                  d   j                  «       › �«       |j                  d   dk  rt        d«       y y )Nr   )Ú	get_sp500Ú5yT)ÚperiodÚauto_adjustÚCloseé   gÍÌÌÌÌÌì?)ÚaxisÚthreshÚVolumezclose panel: z rows x z
 tickers, z..éÿÿÿÿéd   u@   WARNING: small universe â€” offline fallback or throttled fetch?)ÚyfinanceÚscreener.universer   ÚdownloadÚdropnaÚintÚlenÚcolumnsÚffillÚto_csvÚ	CLOSE_CSVÚ
VOLUME_CSVÚprintÚshapeÚindexÚdate)Úyfr   ÚtickersÚdfÚcloseÚvolumes         ú2/var/www/html/finance-tool/autoresearch/prepare.pyÚfetchr%      sö   € Ûå+á‹k€GØ	�‰�W T°tˆÓ	<€BØˆw‰K×Ñ A¬c´#°b³'¸C±-Ó.@ÐÓA€EØ�‰\˜%Ÿ-™-Ñ(€FØ	‡K�KƒM×ÑœÔ#Ø
‡M�M”*ÔÜ	ˆM˜%Ÿ+™+ a™.Ð)¨°%·+±+¸a±.Ð1AÀØ�[‰[˜‰^× Ñ Ó"Ð# 2 e§k¡k°"¡o×&:Ñ&:Ó&<Ð%=ð?ô @à‡{�{�1�~˜ÒÜÐPÕQð ó    c                 óô   — t         j                  j                  t        «      st	        j
                  d«       t        dd¬«      } t        j                  t        fi | ¤Žt        j                  t        fi | ¤ŽfS )NuE   price cache missing â€” run: .venv/bin/python autoresearch/prepare.pyr   T)Ú	index_colÚparse_dates)
ÚosÚpathÚexistsr   ÚsysÚexitÚdictÚpdÚread_csvr   )Úkws    r$   Úloadr3   '   sR   € Ü�7‰7�>‰>œ)Ô$Ü�‰ÐXÔYÜ	˜ tÔ	,€BÜ�;‰;”yÑ' BÑ'¬¯©´ZÑ)FÀ2Ñ)FÐFÐFr&   c                ó‚   — t        t        j                  d«      | j                  «       z  | j	                  «       z  «      S )Né   )ÚfloatÚnpÚsqrtÚmeanÚstd)Úmonthly_retss    r$   Úsharper<   .   s1   € Ü”—‘˜“˜|×0Ñ0Ó2Ñ2°\×5EÑ5EÓ5GÑGÓHÐHr&   c           	     ó¤  — t        «       \  }}|j                  }|j                  «       j                  |j	                  d«      «      D ��cg c]  \  }}|j
                  d   ‘Œ }}}g }	t        ||dd «      D ]°  \  }}
|j                  |«      dk  rŒ | |j                  d| |j                  d| «      j                  «       j                  |«      j                  }|	j                  t        |j                  |
|f   |j                  ||f   z  dz
  j                  «       «      «       Œ² t        j                  |	«      }	|	j
                  d|  |	j
                  | d }}t!        t#        |	«      › dt#        |«      › dt#        |«      › d�«       t!        d	t%        |«      d
›�«       t!        dt%        |«      d
›d�«       t%        |«       S c c}}w )zíMonthly-rebalanced equal-weight top-N backtest. Returns -Sharpe(in-sample).

    scores_fn(close, volume) receives panels truncated to the rebalance date
    (the last row IS the as-of date), so lookahead is structurally impossible.
    ÚMr   r
   Ni  z monthly returns: z in-sample, z holdoutzin-sample Sharpe: z.4fzholdout Sharpe:   u6     (reported for honesty â€” never optimize against it))r3   r   Ú	to_seriesÚgroupbyÚ	to_periodÚilocÚzipÚget_locÚlocr   ÚnlargestÚappendr6   r9   r0   ÚSeriesr   r   r<   )Ú	scores_fnÚtop_nÚholdout_monthsr"   r#   ÚidxÚ_ÚdÚ
month_endsÚretsÚd_nextÚpicksÚinsÚholds                 r$   ÚevaluaterU   2   s¢  € ô “F�M€Eˆ6Ø
�+‰+€CØ),¯©«×)@Ñ)@ÀÇÁÈsÓASÓ)T×U¡  A�!—&‘&˜“*ÐU€JÑUà€DÜ˜ Z°° ^Ó4ò X‰	ˆˆ6Ø�;‰;�q‹>˜CÒØÙ˜%Ÿ)™) B Q˜-¨¯©°B°Q¨Ó8×?Ñ?ÓA×JÑJÈ5ÓQ×WÑWˆØ�‰”E˜5Ÿ9™9 V¨U ]Ñ3°e·i±iÀÀ5ÀÑ6IÑIÈAÑM×SÑSÓUÓVÕWð	Xô
 �9‰9�T‹?€Dà—	‘	Ð*˜N˜?Ð+¨T¯Y©Y¸°Ð7GÐ-Hˆ€CÜ	ŒS�‹YˆKÐ)¬#¨c«(¨°<ÄÀDÃ	¸{È(Ð
SÔTÜ	Ðœv c›{¨3Ð/Ð
0Ô1Ü	Ðœv d›|¨CÐ0Ð0fÐ
gÔhÜ�3‹Kˆ<Ðùó Vs   ÁGÚ__main__)ÚreturnÚNone)rW   z!tuple[pd.DataFrame, pd.DataFrame])r;   z	pd.SeriesrW   r6   )é   r5   )rJ   r   rK   r   rW   r6   )Ú__doc__Ú
__future__r   r*   r-   Únumpyr7   Úpandasr0   r+   ÚdirnameÚabspathÚ__file__ÚHEREÚROOTÚinsertÚjoinr   r   r%   r3   r<   rU   Ú__name__© r&   r$   ú<module>rg      s±   ðñõ
 #ã 	Û 
ã Û à	‡w�w‡��r—w‘w—‘ xÓ0Ó1€Ø	‡w�w‡��tÓ€Ø ‡�‡���4Ô à�G‰G�L‰L˜˜{Ó+€	Ø�W‰W�\‰\˜$ Ó-€
óRó"GóIôð2 ˆzÒÙ	…Gð r&   