o
    y!Àjó  ã                   @   sÒ   d Z ddlZddlZddlZddlmZ ddlmZ ddlmZ ddl	Z
eeƒ ¡ jZej deeƒ¡ ej dd¡ ddlZddlZedƒZdd	„ Zd
d„ Zdd„ Z		ddd„Zdd„ Zedkrgeƒ  dS dS )a  
star_follow.py -- [2026-10-01] "STAR FOLLOW", the user's playbook-reference method (agreed
2026-10-01 on ARHS). Follows the marked best buys/sells (the stars) of the closest past days.

  1 Library: every stock-day in reports/open_window/bars with its marked best trade(s)
    (data/playbook/day_labels.jsonl: best holdable buy/sell where a 1% stop is never hit,
    plus a second move). Only days BEFORE the traded day are used.
  2 Match: price vs open and price vs VWAP (both / the stock's daily ATR%) and
    0.5*log(1 + volume vs its 14-day normal), minute by minute from 9:30 to NOW, averaged
    over the whole day so far.
  3 Every minute the 150 closest days are found again (references drop out / come in).
  4 Not holding, from 9:35 to 15:15: BUY at the next minute's open when >= `trigger` of the
    current references have a marked best buy within the last `window` minutes.
  5 Holding: SELL at the next minute's open when >= `trigger` references that were already in
    their marked trade (marked buy earlier than the window) have a marked best sell within the
    last `window` minutes; safety stop `stop_pct` below the buy; 15:55 sell-all.
  6 After a sell, back to 4. Cost 0.1% per trade.

    python3 star_follow.py 2026-10-01 CXM [--trigger 10 --window 5 --k 150 --stop 1.0]
é    N)Údatetime)ÚPath)ÚZoneInfoz/var/www/screener/tradezAmerica/New_Yorkc                 C   s$   dd|  d  › dd|  d d›�S )Né	   é   é<   ú:Ú02d© )Úmr
   r
   ú7/var/www/screener/trade/reports/playbook/star_follow.pyÚhm&   s   $r   c                     sH   i } t tjttjƒƒD ]‰ ‡ fdd„dD ƒ| ˆ d › dˆ d › �< q| S )Nc                    s.   g | ]}ˆ   |¡rˆ | d  ˆ | d f‘qS )Úentry_mÚexit_m©Úget)Ú.0Úk©Úlr
   r   Ú
<listcomp>-   s   . zload_marks.<locals>.<listcomp>)Ú	best_heldÚleg2Údateú|Úsymbol)ÚmapÚjsonÚloadsÚopenÚLDÚOUT)Úmarksr
   r   r   Ú
load_marks*   s   *r#   c                 C   s¢   dd l }tjd| › d� }| ¡ r(t | |d¡¡}||d v r(|d | d S ddlm} t	 
| ¡jtd�}|ƒ j||jd	d
d�|jdd�dd�}dd„ |D ƒS )Nr   Úbars_z.json.gzÚrtÚsymbolsÚbars)Ú
get_client)Útzinfor   r   )ÚhourÚminuteé   )r*   iè  )ÚstartÚendÚlimitc              	   S   s<   g | ]}|j t|jƒt|jƒt|jƒt|jƒt|jƒg‘qS r
   )Ú	timestampÚfloatr   ÚhighÚlowÚcloseÚvolume)r   Úbr
   r
   r   r   ;   s   < zday_bars.<locals>.<listcomp>)ÚgzipÚRTÚBARSÚexistsr   Úloadr   Úalpaca_clientr(   r   ÚfromisoformatÚreplaceÚETÚget_minute_bars)ÚdayÚsymr7   ÚpÚdr(   Úd0Úrawr
   r
   r   Úday_bars1   s   &rG   é–   é
   é   ç      ð?éY  çš™™™™™¹?Tc              
      s”  ˆ   |¡ d d g g f\}}}}t|dƒD �]‰ˆ  |d ˆ||¡\}}‡ fdd„|D ƒ}t|ƒ}|r8t||@ ƒn|}|}ˆ| d ‰t‡‡‡fdd„|D ƒƒ}t‡‡‡fdd„|D ƒƒ}ˆtˆƒt|d	 ˆ ƒ||||d ud
dœ}|d u r²||kr±ˆ|	kr±|d u s…|ˆƒr±t|d ˆd  ƒ}ˆd ||d|d   ˆ|dœ}d|› dtˆd ƒ› d|d›�|d< n_|d ˆ |d krÛ| i |¥ˆ|d |› d�dœ¥¡ d|d d›�|d< d }n6||k�rt|d ˆd  ƒ}| i |¥ˆd |d|› d�dœ¥¡ d|› dtˆd ƒ› d|d›�|d< d }| |¡ q|�r-| i |¥dt|d	 d ƒddœ¥¡ |D ]}t	|d |d  d d |
 d ƒ|d!< �q/||fS )"Ni�  ÚFc                    s   g | ]}ˆ j | ‘qS r
   )Úkeys)r   Úi)Úlibr
   r   r   D   s    zstar_follow.<locals>.<listcomp>é   c                 3   sB   � | ]}ˆ  |g ¡D ]\}}ˆ|  krˆ kr
n nd V  q
qdS ©rR   Nr   ©r   ÚkeyÚbmÚsm©r   r"   Úw0r
   r   Ú	<genexpr>I   s   €@ zstar_follow.<locals>.<genexpr>c                 3   sJ   � | ] }ˆ  |g ¡D ]\}}|ˆk r
ˆ|  krˆ kr
n nd V  q
qdS rS   r   rT   rX   r
   r   rZ   J   s   €H ÚCÚ )r   ÚtÚpriceÚkeptÚbuysÚsellsÚholdingÚeventÚOéd   )Úbuy_mÚbuyÚstopÚsignal_mÚsignal_nzBUY signal (z reference buys) -> buy z at ú.3frc   ÚLrh   z% stop)Úsell_mÚsellÚwhyzSTOP at zreferences exit (ú)zEXIT signal (z reference sells) -> sell z15:55rn   rg   é   Úpl_pct)
r-   ÚrangeÚmatchÚsetÚlenÚsumr   r1   ÚappendÚround)rQ   r"   rA   Úar   ÚtriggerÚwindowÚstop_pctÚstart_mÚ
last_buy_mÚcostÚverboseÚcan_buyÚposÚprevÚtradesÚlogÚidxÚ_ÚcurÚSr_   r`   ra   ÚrowÚeÚs_r]   r
   )rQ   r   r"   rY   r   Ústar_follow>   sF   
ÿ  $€$
&$&*rŽ   c                  C   sþ  t  ¡ } |  d¡ |  d¡ | jdtdd� | jdtdd� | jdtd	d� | jd
tdd� |  ¡ }tj |j	|j
¡}t t|j	|j
ƒ|¡}t ¡ }tƒ }t|||j	||j|j|j|jƒ\}}t |j	|j
t dd„ t|j	|j
ƒD ƒ|¡¡}td|j
› d|j	› d|j› d|j› d|j› d|j› d�ƒ tdd›ddd›ddd›ddd›ddd›ddd›d �ƒ |D ]>}	|	d! s¿|	d" d# d$krït|	d% d›d|	d d&›d|	d' rÒd(nd)d›d|	d d*›d|	d+ d,›d|	d- d.›d/|	d! › �ƒ q±td0ƒ |D ],}
td1t|
d2 ƒ› d|
d3 d4›d5t|
d6 ƒ› d|
d7 d4›d/|
d8 d9›d:|
d; › d<�ƒ qötd=td>d?„ |D ƒƒd9›d@�ƒ | dA¡}|�rdtdBt|dC ƒ› d|dD d d4›d5t|dE ƒ› d|dF d d4›dG|dH dI›d@�ƒ tj||dJœttdK|j
› dL|j	› dM� dNƒd$dO� d S )PNrA   r   z--krH   )ÚtypeÚdefaultz	--triggerrI   z--windowrJ   z--stoprK   c                 S   s<   g | ]}|d  }t |tƒrt| ¡ ƒn|g|dd… ¢‘qS )r   rR   N)Ú
isinstancer   Úintr0   )r   ÚrÚxr
   r
   r   r   o   s    
,ÿzmain.<locals>.<listcomp>zSTAR FOLLOW ú z  (k=z
, trigger=z in z min, stop z%)Útimez>5r^   z>7Ústater_   z>4zref buysz>8z	ref sellsz>9z  eventrc   r   é   r   r]   z7.3frb   ÚHOLDÚflatÚ4r`   Ú8ra   Ú9z  z
TRADES (0.1% cost each):z  buy rf   rg   rk   z	 -> sell rm   rn   rr   z+.2fz%  [ro   ú]z  total c                 s   s   � | ]}|d  V  qdS )rr   Nr
   )r   r]   r
   r
   r   rZ   y   s   € zmain.<locals>.<genexpr>ú%r   z"marked best trade of the day: buy r   Úentryr   Úexitz  +Úgain_pctz.2f)r…   r†   Ústarfollow_rˆ   z.jsonÚw)Úindent)ÚargparseÚArgumentParserÚadd_argumentr’   r1   Ú
parse_argsr8   ÚREFr;   rA   r   Ú
day_arraysrG   ÚLibr#   rŽ   r   r{   r|   rh   r    ÚlabelÚbuildÚprintr   rw   r   r   Údumpr   ÚHERE)ÚapÚargsÚrefrz   rQ   r"   r…   r†   Úlabr“   r]   Úbhr
   r
   r   Úmaind   sB     $ÿÿ:8`€V 
0ÿ
ÿ6r·   Ú__main__)	rH   rI   rJ   rK   rJ   rL   rM   TN)Ú__doc__r¦   r   Úsysr   Úpathlibr   Úzoneinfor   ÚnumpyÚnpÚ__file__ÚresolveÚparentr±   ÚpathÚinsertÚstrÚreference_traderr8   Ú
label_daysr    r?   r   r#   rG   rŽ   r·   Ú__name__r
   r
   r
   r   Ú<module>   s.     
ÿ&
ÿ