o
    Ì5Àj”"  ã                   @   s2  d Z ddlZddlZddl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dejv ZedƒZd\ZZZZZZZd\ZZd	\ZZ Z!d
d„ Z"dd„ Z#dd„ Z$ddd„Z%dd„ Z&e'dkr—dejv rrdZdejv rydZe(ejƒdkrŽejd  )¡ rŽe*ejd ƒZe&ejd ƒ dS dS )a¬  
sf3_batch.py -- [2026-10-01] STAR FOLLOW v3, the user's rules (approved 2026-10-01):
  references : WINNERS only (data/playbook/winners.json: closed >= +2% over the open with a
               confirmed buy mark), only days before the traded day; marks = confirmed marks
  BUY        : reference buys in the last 5 min >= max(6, 2 x normal for that minute)
  HOLD/EXIT  : every minute count the references that STILL MATCH (whole-day distance <= the
               150th-closest distance at the buy). If fewer than 10 match for 2 minutes in a row:
                 not climbing (close <= close 2 min earlier) -> sell next minute's open
                 climbing -> hold, sell at the next open after the first flat/lower 1-min close
               While >= 10 match: also sell on the references' sell signal (>= max(6, 2 x normal))
               15:55 sell-all. No stop. Cost 0.1% per trade.
    python3 sf3_batch.py 2026-08-27..2026-10-01
é    N)ÚPathz/var/www/screener/tradez--v2z2/var/www/screener/trade/data/playbook/winners.json)é–   é   é   g       @gš™™™™™¹?é
   é   )Úcountg      Ð?)iô  g      à?é2   c                 C   s�   |d ||d … |d |  d }| j |||d …f | j ||f dd…df  d }t ||ddd…f  d  d¡¡d }t|tk ¡ ƒS )zYHow many pool days moved like the stock from minute m0 to m (RMS of % change difference).ÚCé   Nr   éd   )r
   ÚnpÚsqrtÚmeanÚintÚ	SINCE_RMSÚsum)ÚlibÚpoolÚaÚm0ÚmÚsÚrÚrms© r   ú5/var/www/screener/trade/reports/playbook/sf3_batch.pyÚsince_count&   s   $4(r   c                  C   s    t  ttƒ¡} dd„ | D ƒ}|S )Nc                 S   s>   i | ]}|d  › d|d › �dd„ |  d¡|  d¡fD ƒ“qS )Údateú|Úsymbolc                 S   s    g | ]}|r|d  |d f‘qS )Úentry_mÚexit_mr   )Ú.0Úxr   r   r   Ú
<listcomp>0   ó     z#load.<locals>.<dictcomp>.<listcomp>ÚbuyÚleg2)Úget)r#   Úwr   r   r   Ú
<dictcomp>0   s   > zload.<locals>.<dictcomp>)ÚjsonÚloadÚopenÚWINNERS)ÚWÚmarksr   r   r   r-   .   s   r-   c                    s¬   t  d¡}t  d¡}|  ¡ D ]7}tdƒD ]0‰ ˆ t d ‰t‡ ‡fdd„|D ƒƒr0|ˆ   d7  < t‡ ‡fdd„|D ƒƒrD|ˆ   d7  < qqt| ƒ}|| t || t fS )Ni†  r   c                 3   s,   � | ]\}}ˆ|  koˆ kn  V  qd S ©Nr   ©r#   ÚbmÚsm©r   Úw0r   r   Ú	<genexpr>9   s   €* znormal_rates.<locals>.<genexpr>c                 3   s4   � | ]\}}|ˆk oˆ|  koˆ kn  V  qd S r2   r   r3   r6   r   r   r8   ;   s   €2 )r   ÚzerosÚvaluesÚrangeÚWINÚanyÚlenÚK)r1   r'   ÚsellÚmkÚnr   r6   r   Únormal_rates4   s   €ûrC   c                    s¨  t  ˆ j|k |@ ¡d }ˆ j| }	t  t|ƒ¡}
‡ fdd„|D ƒ}d g }}tddƒD �]Ù}|
|	d d …|d d …f |d d |d d …f  d  d¡7 }
|dk rPq+|
|d  }t  |t	¡d t	… }|t
 d }d }}|D ]3}| || d	¡D ](\}}||  kr„|krŠn n|d7 }||k rž||  kr˜|kržn qv|d7 }qvql|d u �r|d
k�r|d u s³||ƒ�r|ttt||  ƒk�rtt  || ¡d ƒ}|| }|t  |t¡d t…  }t jˆ j||d…f ˆ j||f d d …d f  tdd�}||||d t|d |d  ƒ|dddt|d |d  ƒt	dœ}q+t|d t|d | ƒƒ|d< tdk�r?tˆ |d ||d |ƒtk�r<tnd}n8tdk�rm||d  }|d | |d |d   |d t|t|d ƒd ƒ k�rjtnd}n
t||d k ¡ ƒ}t|d |ƒ|d< d }|d �sÇ|tk �r’|d d nd|d< |d tk�r¸d|d< |d | |d |d  k�rµd|d< n,d}n)|ttt||  ƒk�rÆd}n|d �rá|d | t|d |d |… ƒk �rád }|�r| |d! |d" |d t|d |d  ƒ||d |d d#œ¡ d }q+|�r$| |d! |d" dt|d d ƒd$|d |d d#œ¡ |D ]+}|d% |d"  d d& t |d'< |d |d"  d d& |d(< |d) |d!  |d*< �q&|S )+Nr   c                    s   g | ]}ˆ j | ‘qS r   )Úkeys)r#   Úi©r   r   r   r%   E   s    zrun_day.<locals>.<listcomp>i�  ÚFr   r   r   r   iY  éÿÿÿÿi‚  )ÚaxisÚOF)r   Úbandr   Úbuy_mr'   ÚthrÚoutÚdivergedÚclimbÚlowÚ	min_matchrQ   ÚLÚsincer   r   rK   r
   rM   rR   rO   rN   TrP   z no longer matching, not climbingzreferences sellzno longer matching, climb endedrL   r'   )rL   r'   Úsell_mr@   ÚwhyrQ   rR   z15:55r@   r   ÚplÚddrU   Úheld)r   ÚwhereÚdatesrG   r9   r>   r;   r   Úargpartitionr?   r<   r)   ÚmaxÚMIN_NÚRATIOÚfloatÚsortÚPOOLÚquantiler
   ÚBAND_QÚminÚMODEr   Ú	SINCE_MINÚ	MIN_MATCHr   ÚOUT_MINÚappendÚCOST)r   Úwmaskr1   ÚnbÚnsÚdayr   Úcan_buyÚokÚsubÚDrD   ÚposÚtradesr   r   Úorderr7   ÚbuysÚsellsrE   r4   r5   rM   Úrefsr   rK   Ún_matchÚkrV   Útr   rF   r   Úrun_dayA   s†   

: €ü
48$ÿ
(
F

€0(ÿ€"ÿ r}   c                    sú  |   d¡\‰ ‰trt ¡ nt ¡ }tƒ ‰tdtrdnddd� t ‡fdd„|j	D ƒ¡}t
ˆƒ\‰}td	t| ¡ ƒ› d
�‡fdd„dD ƒdd� t‡ ‡fdd„|j	D ƒƒ}g }|D ]i}t t tjd|› d� d¡¡}|d D ]C}tj ||¡}	|	s{qotrŠt |d | d |	|¡nt |d | d |	¡}
|
d u r›qot||ˆˆ|||
ƒD ]}| ||dœ|¥¡ q¥qotjj ¡  t|t|ƒdd� qYtj|ttdˆ › dˆ› dt› trÕdnd› tdkrßdt nd› d�	 dƒtd� tdt› d t› �ƒ d!d"„ ‰t d#d„ |D ƒ¡}|t|ƒd$  ‰t ‡fd%d„|D ƒ¡}i }|D ]}| |d& d'¡|d(  ||d& < �qtd)t|ƒ› d*t|ƒ› d+|d'k ¡ d,›d-| ¡ d.›d/t  |¡d.›d0| ¡ d1›d2||  ¡ d1›d3||   ¡ d1›d4td5d6„ | !¡ D ƒƒ› d7t|ƒ› d8| "¡ d1›d9t"d:d6„ |D ƒƒd1›d;tt  d<d„ |D ƒ¡ƒ› �ƒ td=d„ |D ƒƒD ]0‰t ‡fd>d„|D ƒ¡}td?ˆ› d@t|ƒ› d+|d'k ¡ d,›d-| ¡ d.›d0| ¡ d1›dA�ƒ �q t #|¡}tdB|dCd …  ¡ d1›dA�ƒ tdD‡fdEd„t|dFd"„ dG�d dH… D ƒƒ d S )INz..z	features:z(v2 (price, VWAP, volume + SPY, IWM, gap)zv1 (price, VWAP, volume)T)Úflushc                    s   g | ]}|ˆ v ‘qS r   r   ©r#   r{   )r1   r   r   r%   ‰   ó    zmain.<locals>.<listcomp>zwinners in the library: z"; normal buys at 9:35/10:00/11:00:c                    s   g | ]	}t ˆ | d ƒ‘qS )r   ©Úround)r#   r   )rm   r   r   r%   Œ   s    )r   é   éZ   c                    s<   h | ]}ˆ |  d ¡d   krˆkrn n|  d ¡d ’qS )r   r   )Úsplitr   )Úa_Úb_r   r   Ú	<setcomp>�   s   < zmain.<locals>.<setcomp>Úbars_z.json.gzÚrtÚtop30_currentÚsymbolsÚbars)ro   ÚsymÚ
sf3_batch_Ú_Ú_mÚ_v2Ú r   z.jsonr*   )ÚdefaultzMIN_MATCH = z	, MODE = c                 S   s$   dd|  d  › dd|  d d›�S )Né	   rƒ   é<   ú:Ú02dr   )r   r   r   r   Ú<lambda>ž   s   $ zmain.<locals>.<lambda>c                 S   ó   g | ]}|d  ‘qS )rW   r   ©r#   r|   r   r   r   r%   Ÿ   r€   r   c                    s   g | ]}|d  ˆ k ‘qS )ro   r   r›   )Úhalfr   r   r%   Ÿ   s    ro   r   rW   Ú
z days: z trades, win z.0%z, avg z+.2fz
%, median z%, sum z+.1fz
% (halves z% / z%), positive days c                 s   s   � | ]}|d kV  qdS )r   Nr   )r#   Úvr   r   r   r8   ¤   ó   € zmain.<locals>.<genexpr>ú/z, worst trade z%, worst dip c                 s   s   � | ]}|d  V  qdS )rX   Nr   r›   r   r   r   r8   ¥   rŸ   z%, median minutes held c                 S   rš   )rY   r   r›   r   r   r   r%   ¥   r€   c                 S   s   h | ]}|d  ’qS )rV   r   r›   r   r   r   rˆ   ¦   r€   c                    s    g | ]}|d  ˆ kr|d ‘qS )rV   rW   r   r›   )r*   r   r   r%   §   r&   z	   exit 'z': ú%z    without the worst 10 trades: r   z	   worst:c                    s@   g | ]}|d  dd… |d ˆ |d ƒt |d dƒ|d f‘qS )ro   r   NrŽ   rL   rW   r   rV   r�   r›   )Úhmr   r   r%   «   s   @ c                 S   s   | d S )NrW   r   )r|   r   r   r   r™   «   s    )Úkeyr   )$r…   ÚUSE_V2ÚL2ÚLibÚRTr-   Úprintr   ÚarrayrD   rC   r   r   Úsortedr,   Úgzipr.   ÚBARSÚREFÚ
day_arraysr}   rj   Ú_CACHEÚclearr>   ÚdumpÚHERErh   rf   r`   r)   r   Úmedianr:   re   ra   )Úrngr   rl   rn   ÚdaysÚTro   Údr   Úrefr   r|   ÚpÚhÚbydÚqr   )r†   r‡   rœ   r¢   r1   rm   r*   r   Úmain„   sn   ÿ 6ÿN<$BÿÿÿÿÿþþþF
0r½   Ú__main__z--bandrK   z--sincerT   r   r   r2   )+Ú__doc__r«   r,   ÚsysÚpathlibr   Únumpyr   Ú__file__ÚresolveÚparentr²   ÚpathÚinsertÚstrÚreference_traderr§   Úlib_v2r¥   Úargvr¤   r/   r?   r<   r^   r_   rk   rh   ri   rf   rd   rb   r   rg   r   r-   rC   r}   r½   Ú__name__r>   Úisdigitr   r   r   r   r   Ú<module>   s:     


C*

ù