o
    »Uj{  ã                   @  st   d Z ddlmZ ddlmZmZ ddlmZmZ ddl	Z
ddlZddlZdd
d„ZeG dd„ dƒƒZdddd„ZdS )a  Data access layer built on yfinance (free Yahoo Finance data).

Everything the strategies need is normalised into a single `StockData`
object so the scoring code never touches yfinance directly. yfinance is
flaky about which fields exist per ticker, so every getter is defensive.
é    )Úannotations)Ú	dataclassÚfield)ÚAnyÚOptionalNÚvaluer   ÚreturnúOptional[float]c              	   C  sN   | du rdS zt | ƒ}W n ttfy   Y dS w t |¡s#t |¡r%dS |S )z=Coerce a yfinance value to float, or None if missing/garbage.N)ÚfloatÚ	TypeErrorÚ
ValueErrorÚnpÚisnanÚisinf)r   Úf© r   úIC:\Users\cheed\OneDrive\Desktop\Claude work\finance-tool\screener\data.pyÚ_num   s   ÿr   c                   @  s    e Zd ZU ded< eed�Zded< eejd�Z	ded< dZ
d	ed
< dZded< ddd„Zed dd„ƒZed dd„ƒZed!dd„ƒZed!dd„ƒZd"dd„ZdS )#Ú	StockDataÚstrÚticker)Údefault_factoryÚdictÚinfozpd.DataFrameÚhistoryFÚboolÚokÚ ÚerrorÚkeyr   r	   c                 C  s   t | j |¡ƒS )N)r   r   Úget)Úselfr   r   r   r   r    '   s   zStockData.getc                 C  s   | j  d¡p| j  d¡p| jS )NÚ	shortNameZlongName)r   r    r   ©r!   r   r   r   Úname*   s   zStockData.namec                 C  s   | j  d¡pdS )NÚsectorZUnknown)r   r    r#   r   r   r   r%   .   s   zStockData.sectorc                 C  s<   |   d¡p	|   d¡}|d u r| jjst| jd jd ƒ}|S )NÚcurrentPriceZregularMarketPriceÚCloseéÿÿÿÿ)r    r   Úemptyr   Úiloc)r!   Úpr   r   r   Úprice2   s   zStockData.pricec                 C  s
   |   d¡S )NÚ	marketCap)r    r#   r   r   r   Ú
market_cap9   s   
zStockData.market_capÚdaysÚintc                 C  sj   | j jst| j ƒ|krdS | j d }t|j| d  ƒ}t|jd ƒ}|r-|dks-|du r/dS || d S )zBTotal return over the trailing `days` trading days, as a fraction.Nr'   é   r(   r   g      ð?)r   r)   Úlenr   r*   )r!   r/   ÚcloseZpastÚnowr   r   r   Úreturns=   s   
zStockData.returnsN)r   r   r   r	   )r   r   )r   r	   )r/   r0   r   r	   )Ú__name__Ú
__module__Ú__qualname__Ú__annotations__r   r   r   ÚpdÚ	DataFramer   r   r   r    Úpropertyr$   r%   r,   r.   r5   r   r   r   r   r      s    
 
r   Ú1yr   r   Úperiodc              
   C  s  t | d�}zft | ¡}z
t|jpi ƒ|_W n ty0 } zi |_d|› �|_W Y d}~nd}~ww z
|j|dd�|_W n" ty] } zt 	¡ |_|jd|› �  
¡ |_W Y d}~nd}~ww t|jƒpg|jj |_W |S  ty† } zt|ƒ|_d|_W Y d}~|S d}~ww )z=Fetch info + price history for a single ticker. Never raises.)r   zinfo: NT)r>   Zauto_adjustz hist: F)r   ÚyfZTickerr   r   Ú	Exceptionr   r   r:   r;   Ústripr   r)   r   r   )r   r>   ÚsdZtkÚexcr   r   r   ÚfetchI   s2   

€þ
"€þý
€ýrD   )r   r   r   r	   )r=   )r   r   r>   r   r   r   )Ú__doc__Ú
__future__r   Údataclassesr   r   Útypingr   r   Únumpyr   Úpandasr:   Zyfinancer?   r   r   rD   r   r   r   r   Ú<module>   s    
*