o
    <#¿jØ  ã                   @   s”   d Z ddlZddlZddlmZ eeƒ ¡ jZej	 
deeƒ¡ ej	 
dd¡ ddlZdZdZdZdZddd	„Zd
ZdZdd„ Zdd„ Zdd„ ZdS )a«  
confirmed_marks.py -- [2026-10-01] The user: the buy signal is in the wrong spot on the charts
(MSGY/MEDS bought at 9:36 before a crash); locate the buy marks properly. DRAFT rules for a
"confirmed" buy mark (to be approved on example charts before re-marking the library):
  1 swing low L at minute i: no lower low in the next `hold_min` (3) minutes
  2 confirmation c: first minute after i (>= i + hold_min) whose close is above the high of
    the low's bar, with still no lower low -> BUY at the close of c, not before 9:35
  3 stop = L - 1c; risk = buy - stop
  4 valid only if, before the stop is hit, price reaches max(2 x risk, 2% of the buy) above the
    buy (reward:risk >= 2 and >= +2%); otherwise not a buy mark
  5 sell mark = highest close after the buy before the stop is hit (or 15:55)
The day's mark = the valid confirmed trade with the biggest gain; a second one after its sell.
No valid trade -> no buy mark that day.
é    N)ÚPathz/var/www/screener/tradeé   g       @é   c                    s$  g }t ˆ ƒ}|}||t d k �rˆ | d ‰t‡ ‡fdd„t|d t|d t |ƒƒD ƒƒsCt‡ ‡fdd„ttd|d ƒ|ƒD ƒƒrH|d7 }qd}t|t t|d	 |ƒƒD ],}ˆ | d ˆk rb n!ˆ | d
 ˆ | d kr‚ˆ | d tkr‚ˆ | d dkr‚|} nqV|du rŒ|d7 }qˆ | d
 }ˆd }|| }	|tt|	 |t d ƒ }
d\}}}t|d |ƒD ]3}ˆ | d dksÅˆ | d |krÇ n ˆ | d |
krÑd}|du sÝˆ | d
 |kræˆ | d
 |}}q³|�r|du�r||k�r| 	||||| d d |f¡ |d7 }||t d k s|S )zTAll valid confirmed trades starting at index >= start, as (i_low, c, j_sell, gain%).é   Úlc                 3   ó    � | ]}ˆ | d  ˆk V  qdS ©r   N© ©Ú.0Úk©ÚBÚLr	   ú;/var/www/screener/trade/reports/playbook/confirmed_marks.pyÚ	<genexpr>%   ó   € z#confirmed_trades.<locals>.<genexpr>c                 3   r   r   r	   r
   r   r	   r   r   &   r   r   r   Né<   ÚcÚhÚmiY  g{®Gáz„?éd   )NNFé�  T)
ÚlenÚHOLDÚanyÚrangeÚminÚmaxÚFIRST_BUY_MÚMIN_RRÚMIN_GAINÚappend)r   ÚstartÚoutÚnÚir   r   ÚeÚstopÚriskÚneedÚbest_jÚbest_cÚokr	   r   r   Úconfirmed_trades   sJ   0&ÿ8€
 € ãr.   g      ø?c                 C   sˆ  g d}}t | ƒ}	 dd„ t| |ƒD ƒ}|s	 |S t|dd„ d�\}}}}}| | d }	|	| }
|	|d	}}}t|d
 |ƒD ]L}| | d dksQ| | d |krU|} n7| | d |krf| | d |}}t|t d t|
 ƒ}| | d || kr‹| | d | | d k r‹|} nq?||	 d
 d }||kr¯||	td|
 |	d ƒ kr¯| |||||f¡ t|p³|d |d
 ƒ}||d krÃ	 |S q
)an  Greedy through the day: take the first valid confirmed trade; while in it, end it at the
    highest close so far when price closes >= max(DROP_PCT %, DROP_R x starting risk) under that
    high AND below VWAP (or at the high before the stop is hit / 15:55); then look for the next
    confirmed trade after it. Only trades that pass the 2x-risk / +2% rule are kept.r   Tc                 S   s   g | ]}|‘qS r	   r	   ©r   Útr	   r	   r   Ú
<listcomp>O   s    z split_trades.<locals>.<listcomp>c                 S   ó   | d S )Nr   r	   ©r0   r	   r	   r   Ú<lambda>R   ó    zsplit_trades.<locals>.<lambda>©Úkeyr   Nr   r   r   r   r   Úvwapé   g{®Gáz”?r   )r   r.   r   r   r   ÚDROP_PCTÚDROP_Rr"   )r   r$   r#   r%   Úcandsr&   r   Ú_r(   r'   r)   Úhi_cÚhi_jÚend_jr   ÚdropÚgainr	   r	   r   Úsplit_tradesG   s6   
ï ,€"ërC   c                    s*   t ˆ ƒ}‡ fdd„‰d‡fdd„|D ƒiS )Nc              	      ód   ˆ | d  d ˆ | d  d ˆ | d  d t | d dƒˆ | d  d ˆ | d  d t | d dƒdœS ©	Nr   r   r   r   é   r9   r   )Úlow_mÚentry_mÚentryr(   Úexit_mÚexitÚgain_pct©Úroundr3   ©r   r	   r   r4   h   ó   6 (ÿz'label_confirmed_split.<locals>.<lambda>Útradesc                    s   g | ]}ˆ |ƒ‘qS r	   r	   r/   )Úmkr	   r   r1   j   s    z)label_confirmed_split.<locals>.<listcomp>)rC   )r   ÚTr	   )r   rR   r   Úlabel_confirmed_splitf   s   rT   c                    sz   t ˆ ƒ}|sd d dœS t|dd„ d�‰‡ fdd„}‡fdd„|D ƒ}|r,t|dd„ d�nd }|ˆƒ|r9||ƒdœS d dœS )	N)ÚbuyÚleg2c                 S   r2   ©Nr   r	   r3   r	   r	   r   r4   q   r5   z!label_confirmed.<locals>.<lambda>r6   c              	      rD   rE   rM   r3   rO   r	   r   r4   r   rP   c                    s    g | ]}|d  ˆ d kr|‘qS )r   r9   r	   r/   )Úbestr	   r   r1   t   s     z#label_confirmed.<locals>.<listcomp>c                 S   r2   rW   r	   r3   r	   r	   r   r4   u   r5   )r.   r   )r   rS   rR   ÚlaterrV   r	   )r   rX   r   Úlabel_confirmedm   s   
rZ   )r   )Ú__doc__ÚjsonÚsysÚpathlibr   Ú__file__ÚresolveÚparentÚHEREÚpathÚinsertÚstrÚ
label_daysÚLDr   r    r!   r   r.   r:   r;   rC   rT   rZ   r	   r	   r	   r   Ú<module>   s"     
&