
    L1jJ                       S r SSKJr  SSKrSSKrSSKJrJrJr  SSKJ	r	  SSK
rSSKr\R                  R                  S\" \	" \5      R%                  5       R&                  5      5        SSKJrJrJr    S#   S$S jjrS%S&S	 jjrS%S'S
 jjrS(S)S jjrS*S jrS+S,S jjr\S:X  a  \" S5        \R                  " 5       r \" 5       r!\" S\"" \!5       S\R                  " 5       \ -
  S S35        \" 5         \" SS SSS SSS SSS SSS S3
5        \! H7  r#\" \#S   S S\#S   <S S\#S   <S S\#S    <S S\#S!   <S S\#S"    35        M9     gg)-z{Fetch ETF/futures/BTC prices via yfinance.

Returns pandas DataFrames and structured dicts for journal/weekly/event notes.
    )annotationsN)datedatetime	timedelta)Path)UNIVERSEheadline_yf_tickers
yf_tickersc                   U (       d  [         R                  " 5       $ [        R                  " XUSSS9nUb  UR                  (       a  [         R                  " 5       $ [        UR                  [         R                  5      (       a_  SUR                  R                  S5      ;   a  US   nOwSUR                  R                  S5      ;   a  US   nOR[         R                  " 5       $ SUR                  ;   a+  [        UR                  5      S:X  a  US/   nU S   /Ul        OUn[        U[         R                  5      (       a  UR                  5       nU SS Ul        U$ )a  Fetch adjusted close for a list of tickers. Returns DataFrame indexed by date,
columns = tickers. Handles both MultiIndex and flat-column yfinance responses
(yfinance returns inconsistent shapes when tickers include ^-prefixed indices
or crypto like BTC-USD).T)periodprogressauto_adjustthreadsNCloser   z	Adj Close   )pd	DataFrameyfdownloadempty
isinstancecolumns
MultiIndexget_level_valueslenSeriesto_frame)tickersr   r   dfclosess        //home/rpi/Obsidian-Macro/scripts/data/prices.pyfetch_close_historyr"      s    ||~	Wh!%t
5B	zRXX||~"**bmm,,bjj11!44[FBJJ77::_F<<>! bjj S_%9	]F%aj\FNF&"))$$" !M    tickerc                   Uc  [        U /SS9nUR                  (       a  g[        UR                  [        R
                  5      (       a
   US   U    nO+SUR                  ;   a  US   nOXR                  ;   a  X   nOgUR                  5       nUR                  (       a  g[        UR                  S   5      $ ! [         a     gf = f)z)Last available close for a single ticker.N5dr   r   )
r"   r   r   r   r   r   KeyErrordropnafloatiloc)r$   r   seriess      r!   
last_closer.   9   s    	z &$7	xx"**bmm,,	[(F
 bjj [Fzz!ZF]]_F||R!!  		s   B9 9
CCc                  ^^ Uc  [        U /SS9nUR                  (       a	  U SSSSSS.$ [        UR                  [        R
                  5      (       a   US   U    R                  5       mOOSUR                  ;   a  US   R                  5       mO+XR                  ;   a  X   R                  5       mO	U SSSSSS.$ TR                  (       a	  U SSSSSS.$ [        TR                  S   5      mTR                  S   n[        US5      (       a  UR                  S5      O
[        U5      nSUU4S	 jjnU [        TS
5      U" S5      U" S5      U" S5      US.$ ! [         a    U SSSSSS.s $ f = f)z/Compute 1d, 5d (1w), and 1m percentage changes.N2mor'   )r$   last
chg_1d_pct
chg_5d_pct
chg_1m_pctas_ofr   r(   strftimez%Y-%m-%dc                   > [        T5      U :  a6  [        TR                  SU -
     5      nUS:w  a  [        TU-
  U-  S-  S5      $ g )Nr(   r   d      )r   r+   r,   round)n_barspriorr1   r-   s     r!   pctchange_metrics.<locals>.pctm   sK    v;&++b6k23EzdUle3c91==r#      r         )r;   intreturnfloat | None)r"   r   r   r   r   r   r*   r)   r+   r,   indexhasattrr6   strr:   )r$   r   r5   	as_of_strr=   r1   r-   s        @@r!   change_metricsrI   R   s   	z &%8	xx $d"$G 	G"**bmm,,	K[(//1F
 bjj ['')Fzz!Z&&(F$d$"&dTK K|| $d"$G 	GR!DLLE.5eZ.H.Hz*cRWjI  dA!f!f"g /  	K$d$"&dTK K	Ks   E E-,E-c                    [        5       nU(       d  / $ [        XS9n/ n[         HA  n[        US   US9nUS   US'   US   US'   US   US'   US   US'   UR	                  U5        MC     U$ )zDCompute change metrics for the entire universe in one yfinance call.r'   r   r   namedisplaybucketkind)r
   r"   r   rI   append)r   r   r   outums         r!   all_change_metricsrT   }   s    lG		W	4B
C1T7r*fI&	|)k(fI&	

1  Jr#   c                 L   [        5       n [        U SS9n/ n[         Vs0 s H  o3S   US   _M     nn[         Vs0 s H  o3S   US   _M     nnU  HE  n[        XaS9nUR	                  Xf5      US'   UR	                  Xf5      US'   UR                  U5        MG     U$ s  snf s  snf )z8Quick change metrics for the headline set only (faster).r0   r'   r   rL   rM   rK   )r	   r"   r   rI   getrP   )r   r   rQ   rR   name_mapdisp_maptrS   s           r!   headline_metricsrZ      s    !#G	WU	3B
C,45Hq$6"HH5/78x!$9%xH81$LL&&	||A))

1	 
 J 68s
   BB!c                p   [        5       n[        R                  " USSSSSS9nUR                  (       a  / $ [	        UR
                  [        R                  5      (       a   US   nOSUR
                  ;   a  US/   OUn/ nU GH  nXdR
                  ;  a  M  XF   R                  5       nUR                  (       a  M:  XwR                  U :*     nXwR                  U :     n	UR                  (       d  U	R                  (       a  M  [        UR                  S   5      n
[        U	R                  S   5      nU
S:X  a  M  [        X-
  U
-  S	-  S
5      nUR                  U[        U
S5      [        US5      U[        UR                  S   S5      (       a  UR                  S   R!                  S5      O[#        UR                  S   5      [        U	R                  S   S5      (       a  U	R                  S   R!                  S5      O[#        U	R                  S   5      S.5        GM     U$ ! [         a    / s $ f = f)zFor a given event time, fetch the price move in the window [-1h, +1h]
around the event for the headline universe. Returns pct moves.r&   1hFT)r   intervalr   r   r   r   r(   r   r8   r9   r?   r6   z%Y-%m-%d %H:%M %Z)r$   prepostchg_pctpre_time	post_time)r	   r   r   r   r   r   r   r   r)   r*   rE   r+   r,   r:   rP   rF   r6   rG   )event_time_utcwindow_hoursr   r   r    rQ   rY   sr<   r_   	pre_price
post_pricer`   s                r!   fetch_event_reactionrh      s    "#G	WTD#t
EB	xx	"**bmm,,	[F #*RZZ"7WIR CNN"I77''^+,N*+;;$**%**R.)	499Q<(
>/9<sBAF

A&*a(IPQVQ\Q\]_Q`blImImB001DEsvw|  xC  xC  DF  xG  tHHOPTPZPZ[\P]_iHjHjA//0CDpstxt~t~  @A  uB  qC
 	! 0 J?  	I	s   !H& &H54H5__main__zFetching headline universe...z  z tickers in z.1fre   Tickerz<10 Lastz>10z1d%z>8z5d%z1m%z  As ofr1   r2   r3   r4   r5   )6moF)r   z	list[str]r   rG   r   boolrC   zpd.DataFrame)N)r$   rG   r   pd.DataFrame | NonerC   rD   )r$   rG   r   ro   rC   dict)r0   )r   rG   rC   
list[dict])rC   rq   )r   )rc   r   rd   rB   rC   rq   )$__doc__
__future__r   systimer   r   r   pathlibr   pandasr   yfinancer   pathinsertrG   __file__resolveparentuniverser   r	   r
   r"   r.   rI   rT   rZ   rh   __name__printt0metricsr   rS    r#   r!   <module>r      s   # 
  . .    3tH~--/667 8 > > ;@).""&"3?"J"2(V$+\ z	
)*	B G	Bs7|nLR(<A
>?	G	XcN!F3<qr
!E":QuRj
PQ8S!6!S!<&2&a<&2&a<&2&b7 	  r#   