o
    ó×ºj
*  ã                   @   s¨  d Z ddlZddlZddlZddlZddlZddlmZ ddlmZm	Z	 ddl
mZ ddlZe d¡ ddlmZ ddlmZ eeƒ ¡ jZedƒZej deeƒ¡ dd	„ Zddd„Zi Zeƒ Z dd„ Z!dd„ Z"dd„ Z#dd„ Z$e%dkrÐej&d dkr¬ej&d ej&d
d… Z'Z(e  )e(¡ e(D ]Z*ee*› de'› d�  +e$e*e'ƒ¡ e,de*dd� q�dS ej&d Z*ej&dd… D ]Z'ee*› de'› d�  +e$e*e'ƒ¡ e,de'ƒ q¸dS dS )au  
day_report.py -- [2026-09-28] One-symbol, one-day report section (markdown +
chart): premarket-to-close 1-min chart with VWAP and the bot's trades, price
vs open / VWAP through the day, volume by hour, the bot's scanner ranks, its
entry-check decisions and its trades that day.

    python3 day_report.py AGEN 2026-09-21 2026-09-22 ...   -> <SYM>_<date>.md + .png per day
é    N)ÚCounter)ÚdatetimeÚ	timedelta)ÚPathÚAggz/var/www/screener/tradec                    sR  t | › d� }| ¡ r‡ fdd„t t|ƒ¡D ƒng }|r|S ddlm} ddlm} |dƒ}t	 
ˆ ¡j|d�}d	 }}	g }
|ƒ j| |jd
d�|jdd�dd�D ]V}|j |¡}| d¡dk radnd}|dkr†|t|jƒt|jƒ t|jƒ d t|jƒ 7 }|	t|jƒ7 }	|
 ˆ | d¡||j|j|j|j|j|	r¡t||	 d
ƒnddœ	¡ qP|
S )Nz"_1min_premarket_to_close_6days.csvc                    s   g | ]
}|d  ˆ kr|‘qS )Údate© ©Ú.0Úr©Údayr   ú4/var/www/screener/trade/reports/agen/./day_report.pyÚ
<listcomp>   ó    z load_minutes.<locals>.<listcomp>r   )Ú
get_client©ÚZoneInfoúAmerica/New_York©Útzinfog        é   ©Úhouré   éè  )ÚstartÚendÚlimitú%H:%Mz09:30ÚpreÚregé   Ú )	r   Útime_etÚsessionÚopenÚhighÚlowÚcloseÚvolumeÚvwap_regular)ÚHEREÚexistsÚcsvÚ
DictReaderr&   Úalpaca_clientr   Úzoneinfor   r   ÚfromisoformatÚreplaceÚget_minute_barsÚ	timestampÚ
astimezoneÚstrftimeÚfloatr'   r(   r)   r*   ÚappendÚround)Úsymr   ÚpÚrowsr   r   ÚETÚdÚpvÚvÚoutÚbÚtÚsessr   r   r   Úload_minutes   s(   ((0 
ÿrF   r"   c              
   C   sî   ddl }ddlm} ddlm} |dƒ}|ƒ }t |¡j|d�}|jd|j	|j
dœ| |t|d	�  ¡ |jd
d� ¡ dddœdd�}	g }
|	jru|	 ¡  dg ¡D ]&}t |d  dd¡¡ |¡}|
 | d¡|d | dd¡| dd¡f¡ qN|
S )z‹Alpaca news (Benzinga) mentioning sym, from days_before days before `day`
    through its 4:00 PM close. [(time ET, headline, source, url)]r   Nr   )Úget_envr   r   z(https://data.alpaca.markets/v1beta1/news)zAPCA-API-KEY-IDzAPCA-API-SECRET-KEY)Údaysr   r   é2   Úasc)Úsymbolsr   r   r   Úsorté   )ÚheadersÚparamsÚtimeoutÚnewsÚ
created_atÚZz+00:00z%m/%d %H:%M ETÚheadlineÚsourcer#   Úurl)Úrequestsr1   r   Úconfig_loaderrG   r   r2   r3   ÚgetÚapi_keyÚ
secret_keyr   Ú	isoformatÚokÚjsonr6   r9   r7   )r;   r   Údays_beforerW   r   rG   r>   Úer?   r   rB   ÚnrD   r   r   r   Únews_for2   s&   ÿý.rb   c           	   	   C   sæ   t | ƒ}|tvr]t|hB }dd„ |D ƒ}t| ƒ�9}|D ].}d|vr"q| d¡}|dkr9||d | d|d ¡… nd }||v rI||  t |¡¡ qW d   ƒ n1 sTw   Y  |t|< |t| vrmt |¡ t	| |ƒS t| | S )Nc                 S   s   i | ]}|g “qS r   r   )r
   Úsr   r   r   Ú
<dictcomp>O   s    z!_entry_checks.<locals>.<dictcomp>z"kind": "entry"z"symbol": "r   é   ú")
ÚstrÚ_CHECKSÚWANTr&   Úfindr9   r^   ÚloadsÚpopÚ_entry_checks)	Údpr;   ÚkeyÚwantÚfoundÚfhÚlineÚirc   r   r   r   rm   K   s(   


(€úÿ

rm   c                 C   sV   t d d |› d� }g }| ¡ r)t|ƒD ]}t |¡}| d¡| kr(| |¡ q|S )NÚdataÚtradesz_trades.jsonlÚsymbol)ÚTRADEr-   r&   r^   rk   rY   r9   )r;   r   r<   rB   ÚlrD   r   r   r   Ú
trades_for_   s   

€rz   c                 C   sB   t  | ¡}|jd u r|tdd�  d¡S | tdƒ d¡¡ d¡S )Nr   )Úhoursr   r1   r   )r   r2   r   r   r7   r6   Ú
__import__r   )ÚisorD   r   r   r   Úetj   s   

r~   c           '         sL  t | ˆ ƒ}dd„ |D ƒ}dd„ ‰ˆ|d dƒ}t|‡fdd„d�}t|‡fd	d„d�}d
d„ |D ƒ}t| ˆ ƒ}‡ fdd„|D ƒ}	tjdddddddgid�\}
\}}|j|	‡fdd„|D ƒdddd� |j‡ fdd„|D ƒ‡fdd„|D ƒdddd� |rŽ|j|	d t 	ˆ d d¡ddd� |D ]O}d | 
d!¡d"d#fd$| 
d%¡d&d'ffD ]:\}}}}| 
|¡rÞ|rÞt 	ˆ d( t|| ƒ d¡}|j|g|g|d)d*d+� |j|› d(|d,›�||fd-d.d/|d0� q¤q�|j| › d(ˆ › d1�d2d3� |jd/d4d5� |jd6d7� |j|	‡fd8d„|D ƒd9d:d„ |D ƒd;� |jd6d7� |j t d<¡¡ t ¡  t| › d=ˆ › d>� }tj|d?d@� t ¡  dA| › dBˆ › �dCdD|› dE�dCg}|dFdGdH|d,›dIˆ|dJƒd,›dK|dL › dMˆ|dNƒd,›dK|dL › dMˆ|dO dPƒd,›dIˆ|dO dPƒ| d dQ dR›dSt‡fdTdU„|D ƒddV�d,›dWtt‡fdXdU„|D ƒƒƒdY›dItt‡fdXdU„|D ƒƒƒdY›dZ�dCg7 }|g d[¢7 }g d\¢}|D ]I‰t‡fd]dU„|D ƒd ƒ}|�r|d^ �rˆ|dPƒˆ|d^ƒ}}| dH|dL › dI|d,›dI|| d dQ dR›dS|d,›dI|| d dQ dR›d_�¡ �q½tƒ }|D ]}||dL d d…   ˆ|d`ƒ7  < �q|dCdadb dcdU„ t | !¡ ƒD ƒ¡ dCg7 }|dddCg7 }t t" "t#t$de df ˆ › dg� ƒ¡ƒ}g }|D ]u}t% &t'|ƒ¡}dhd„ |D ƒ}| (di¡d  )djdC¡ *d=¡�prdk}|dkk�rzdln|d d… › dm|dd … › �}| |v �r½|| +| ¡ }|dn ‰| dH|› do| +| ¡d › dI|dp › dIˆ 
dq¡› dSˆ 
dr¡› dZ�¡ �qR| dH|› ds�¡ �qR|�rØ|dt )du| ¡dvg| 7 }n| dw¡ ˆ dxk�rè|dCdyg7 }| dC¡ t$de dz ˆ › d{� } |d|dCg7 }|  ,¡ �rwt-| | ƒ}!|!�rgtƒ }"|!D ])}#|# 
d}¡�p |# 
d~¡�p dCgd }$|"|#d t. /d€d�|$¡d d‚… f  d7  < �q|t0|!ƒdY›dƒt|!d d„ ƒ› d…t|!dO d„ ƒ› d†�dCd‡dˆg7 }|d‰d„ |" 1d/¡D ƒ7 }n| dŠ¡ ˆ d‹k�rv| dŒ¡ n| d�¡ | dC¡ |dŽdCg7 }t2| ˆ ƒ}%|%�r™|d�d„ |%D ƒ7 }n| d�¡ | dC¡ |d‘dCg7 }|�r|D ]g}| d’| 
d“¡› d”| 
d!¡d,›dKt|d  ƒ› d•�| 
d$¡�ròd–| 
d%¡d,›dKt|d$ ƒ› d—| 
d˜dC¡d d™… › dš| 
d›d¡dœ›d��	ndž ¡ | 
d$¡�rˆ|dO dPƒ|d!  |d“  }&| dŸ|&d ›�¡ �q®n| d¡¡ | dC¡ d¢ |¡S )£Nc                 S   ó   g | ]
}|d  dkr|‘qS )r%   r!   r   r	   r   r   r   r   s   r   zsection.<locals>.<listcomp>c                 S   s   t | | ƒS )N)r8   )r   Úkr   r   r   Ú<lambda>t   s    zsection.<locals>.<lambda>r   r&   c                    ó
   ˆ | dƒS )Nr'   r   ©r   ©Úfr   r   r�   v   ó   
 )ro   c                    r‚   )Nr(   r   rƒ   r„   r   r   r�   w   r†   c                 S   r   )r%   r    r   r	   r   r   r   r   x   r   c                    ó$   g | ]}t  ˆ d  |d  d¡‘qS ©ú r$   ú%Y-%m-%d %H:%M©r   Ústrptimer	   r   r   r   r   |   ó   $ é   é   )re   gffffff@TÚheight_ratiosr"   )ÚfigsizeÚsharexÚgridspec_kwc                    ó   g | ]}ˆ |d ƒ‘qS )r)   r   r	   r„   r   r   r   ~   ó    ú#1f3a5fzprice (1-min close))ÚcolorÚlwÚlabelc                    r‡   rˆ   r‹   r	   r   r   r   r      r�   c                    r”   )r+   r   r	   r„   r   r   r   €   r•   z#c0392bÚVWAPz 09:30rŠ   z#eeeeeeÚ	premarket)r—   r™   Ú
entry_timeÚentry_priceÚgreenÚBUYÚ	exit_timeÚ
exit_priceÚredÚSELLr‰   é   é#   )r—   Úzorderrc   z.2f)r   é   zoffset pointsé   )ÚxytextÚ
textcoordsÚfontsizer—   u"    â€” premarket to close (1-minute)re   )r«   z
upper left)r«   Úlocg333333Ó?)Úalphac                    r”   )r*   r   r	   r„   r   r   r   �   r•   ga2U0*©C?c                 S   s    g | ]}|d  dkrdnd‘qS )r%   r    z#999r–   r   r	   r   r   r   r   Ž   s     )Úwidthr—   r   Ú_z.pngéx   )Údpiz## õ    â€” r#   z![](ú)ua   | Open | Low (time) | High (time) | Close | Openâ†’close | Premarket high / volume | Day volume |z|---|---|---|---|---|---|---|ú| ú | r(   ú (r$   z) | r'   éÿÿÿÿr)   éd   z+.1fz% | c                 3   ó   � | ]}ˆ |d ƒV  qdS )r'   Nr   r	   r„   r   r   Ú	<genexpr>™   ó   € zsection.<locals>.<genexpr>)Údefaultz / c                 3   r¹   )r*   Nr   r	   r„   r   r   rº   š   r»   ú,ú |)z**Price vs the open and VWAP**r#   z+| Time | Price | vs open | VWAP | vs VWAP |ú|---|---|---|---|---|)z09:45z10:00z10:30z11:00z11:30z12:00z12:30z13:00z13:30z14:00z14:30z15:00z15:30z15:59c                 3   s    � | ]}|d  ˆ kr|V  qdS )r$   Nr   r	   )Úmr   r   rº   Ÿ   s   € r+   z% |r*   zVolume by hour: u    Â· c                 s   s,   � | ]\}}|› d t |d ƒ› d�V  qdS )z:00 r   r€   N)Úint)r
   ÚhrA   r   r   r   rº   ¦   s   €* z**Scanner lists that day**ru   Ú
candidatesz_scanner*.jsonc                 S   s   g | ]}|d  ‘qS )rw   r   )r
   Úcr   r   r   r   ®   s    Ú_scannerz.jsonÚ0928z9:28ú:Úmetricsz | rank Úcandidate_scoreÚgap_pctÚrvolz | not on the list | | | |z$| Scan | AGEN | Score | Gap | RVOL |ÚAGENr¿   z$No scanner lists saved for this day.z
2026-09-25zZ_Note: 9:28 scans before 9/25 10:05 used two-session-old prior-day data (bug fixed 9/25)._Ú	decisionsz.jsonlz**Bot entry checks**Úreasons_againstÚreasons_forÚstatez[\d.]+ú#éF   z	 checks, r5   u   â€“z ET.z| Decision | Checks |z	|---|---|c              	   S   s.   g | ]\\}}}d |› d|› d|d›d�‘qS )r´   r²   rµ   r½   r¾   r   )r
   rc   Úwra   r   r   r   r   Ë   s   . z:The bot never checked it for entry (not on its watchlist).z
2026-09-22u=   _9/22: the bot crashed at 10:49 ET â€” no checks after that._zNo decision log for this day.z***News (3 days before through the close)**c              	   S   s,   g | ]\}}}}d |› d|› d|› d�‘qS )z- r²   r¶   r³   r   )r
   rD   rÂ   ÚsrcrV   r   r   r   r   Ø   s   , zNo news items found.z**Bot trades**z	- Bought Úqtyz at $z), z	sold at $u   ) â€” Úexit_reasonéP   u    â€” **$Ú
pl_dollarsz+.2fz**z
still openz&  - held to the close instead: about $z+.0fz
No trades.Ú
)3rF   ÚmaxÚminrz   ÚpltÚsubplotsÚplotÚaxvspanr   rŒ   rY   r~   ÚscatterÚannotateÚ	set_titleÚlegendÚgridÚbarÚxaxisÚset_major_formatterÚmdÚDateFormatterÚtight_layoutr,   Úsavefigr)   rÁ   ÚsumÚnextr9   r   ÚjoinÚsortedÚitemsÚglobrg   rx   r^   Úloadr&   Úsplitr3   ÚstripÚindexr-   rm   ÚreÚsubÚlenÚmost_commonrb   )'r;   r   ÚRr!   ÚoÚhiÚlor    ÚtrÚxÚfigÚarC   rD   r€   ÚpxÚcolÚlabÚtmÚpngÚLÚmarksr   rÄ   ÚvwÚvolÚfilesr=   ÚfpÚlstÚsymsÚtagrn   ÚchÚcntr?   ÚwhyÚnwÚheldr   )r   r…   rÀ   r   Úsectionq   sú   

$"ÿ"ÿ&€ûÿ LÿÿþþýN€&*$",
H




".6ÿ


€




08ÿÿþ€ú


r  Ú__main__r�   z--dayrŽ   r¯   z.mdÚdoneT)Úflush)r"   )-Ú__doc__r.   rñ   r^   rö   ÚsysÚcollectionsr   r   r   Úpathlibr   Ú
matplotlibÚuseÚmatplotlib.datesÚdatesrè   Úmatplotlib.pyplotÚpyplotrÜ   Ú__file__ÚresolveÚparentr,   rx   ÚpathÚinsertrg   rF   rb   rh   Úsetri   rm   rz   r~   r  Ú__name__Úargvr   r  Úupdater;   Ú
write_textÚprintr   r   r   r   Ú<module>   sL    

|
 þ
 ó