
    U>qjN                    t   d dl mZ d dlZd dlmZmZmZmZmZ d dl	Z	d dl
Zd dlmZmZmZ d dlZd dlmZmZmZ ddlmZ ddlmZmZmZ dd	lmZ dd
lmZ ddlmZ  G d d      Z e dZ!dZ"dg dg ddgdddddddg dg dg ddddiddg d g d!d"gd#d$d%d&d'd(ddg d)g d*gdd+d,idd-Z# G d. d/      Z$y)0    )annotationsN)AnyOptionalListUnionDict)SessionResponse
exceptions)datetimedate	timedelta   )_QUERY1_URL_)log_indent_decoratorget_yf_logger_parse_user_dt)screen)YfData)YFExceptionc                  :    e Zd ZdZddZddZed	d       Zd
dZy)CalendarQuerya  
    Simple CalendarQuery class for calendar queries, similar to yf.screener.query.QueryBase.

    Simple operand accepted by YF is of the form:
        `{ "operator": operator, "operands": [field, ...values] }`

    Nested operand accepted by YF:
        `{ "operator": operator, "operands": [ ...CalendarQuery ] }`

    ### Simple example:
    ```python
    op = CalendarQuery('eq', ['ticker', 'AAPL'])
    print(op.to_dict())
    ```
    c                @    |j                         }|| _        || _        y)z
        :param operator: Operator string, e.g., 'eq', 'gte', 'and', 'or'.
        :param operand: List of operands: can be values (str, int), or other Operands instances (nested).
        N)upperoperatoroperands)selfr   operands      Q/opt/rentech/trading_bot/.venv/lib/python3.12/site-packages/yfinance/calendars.py__init__zCalendarQuery.__init__"   s    
 >>#     c                :    | j                   j                  |       y)z
        Append an operand to the operands list.

        :param operand: CalendarQuery to append (can be value or CalendarQuery instance).
        N)r   append)r   r   s     r   r#   zCalendarQuery.append+   s     	W%r!   c                2    t        | j                        dk(  S )zy
        Check if the operands list is empty.

        :return: True if operands list is empty, False otherwise.
        r   )lenr   r   s    r   is_emptyzCalendarQuery.is_empty3   s     4==!Q&&r!   c                    | j                   }| j                  }||D cg c]$  }t        |t              r|j	                         n|& c}dS c c}w )a  
        Query-ready dict for YF.

        Simple operand accepted by YF is of the form:
            `{ "operator": operator, "operands": [field, ...values] }`

        Nested operand accepted by YF:
            `{ "operator": operator, "operands": [ ...CalendarQuery ] }`
        )r   r   )r   r   
isinstancer   to_dict)r   opopsos       r   r*   zCalendarQuery.to_dict<   sI     ]]mmUXYPQ
1m(D!KY
 	
Ys   )AN)r   strr   z'Union[List[Any], List['CalendarQuery']])r   r   returnNone)r/   bool)r/   dict)	__name__
__module____qualname____doc__r    r#   propertyr'   r*    r!   r   r   r      s*      & ' '
r!   r   z/v1/finance/visualizationz%Y-%m-%dintradaymarketcap)	tickercompanyshortnamer9   	eventnamestartdatetimestartdatetimetypeepsestimate	epsactualepssurprisepct)Surprise (%)zEPS EstimatezReported EPSEvent Start DateSymbolzSurprise(%)Company	Marketcap)rB   zCompany NamezMarket Cap (Intraday))	sortFieldincludeFieldsnan_colsdatetime_colsdf_indexrenamesr=   )r:   r;   exchange_short_name
filingdater=   amendeddate	pricefrompriceto
offerpricecurrencynamesharesdealtype)z
Price FromzPrice ToPriceShares)zFiling DateDatezAmended DatezExchange Short NameExchange)econ_releasecountry_coder=   periodafter_release_actualconsensus_estimateprior_release_actualoriginally_reported_actual)ActualMarket ExpectationPrior to ThisRevised fromz
Event TimeEventRegionExpectedLastRevised)zCountry Coderb   rc   rd   )r:   r;   r=   
optionableold_share_worthshare_worthz
Payable OnzOptionable?
Optionable)sp_earningsipo_infoeconomic_eventsplitsc                  :   e Zd ZdZ	 	 	 d	 	 	 	 	 ddZddZ	 d	 	 	 	 	 ddZddZddZe		 d	 	 	 dd       Z
ddd	Ze		 	 	 	 	 	 	 d	 	 	 	 	 dd
       Ze		 d	 d d       Ze		 d	 d d       Ze		 d	 d d       Zed d       Zed d       Zed d       Zed d       Zy)!	Calendarsa&  
    Get economic calendars, for example, Earnings, IPO, Economic Events, Splits

    ### Simple example default params:
    ```python
    import yfinance as yf
    calendars = yf.Calendars()
    earnings_calendar = calendars.get_earnings_calendar(limit=50)
    print(earnings_calendar)
    ```Nc                   t               | _        |xs
 t               | _        t	        |      | _        | j                  |      }| j                  |      }|xs' t        j                         j                  t              | _        |xsD t        j                  | j                  t              t        d      z   j                  t              | _        |s8|r6| j                  j                  d| j                  d| j                         n:|r8|s6| j                  j                  d| j                  d| j                  d       t!        dg       | _        i | _        i | _        y	)
a  
        :param str | datetime | date start: start date (default today)             eg. start="2025-11-08"
        :param str | datetime | date end: end date (default `start + 7 days`)             eg. end="2025-11-08"
        :param session: requests.Session object, optional
        )session   )dayszFIncomplete boundary: did not provide `start`, using today self._start=z to self._end=z>Incomplete boundary: did not provide `end`, using self._start=z: +7 days from self._startorN)r   _loggerr	   ru   r   _data_parse_date_paramr   nowstrftimeDATE_STR_FORMAT_startstrptimer   _enddebugr   _most_active_qy_cache_request_body	calendars)r   startendru   r   r   s         r   r    zCalendars.__init__   s/    %+')#G4
''.%%c*H 7 7 H{X..t{{OLy^_O``jjkz{	LL!h\`\g\g[iixnrnwnwmyz{3LL!`TXT_T_Saapfjfofoeq  rL   M  N.;D".E#% 24r!   c                D    |syt        |      j                  t              S )N )r   r}   r~   )r   _dates     r   r{   zCalendars._parse_date_param   s    !%(11/BBr!   c                   |t         vrt        d|       ddd}d|t         |   d   t         |   d   t        |d      ||j                         d	}| j                  j                  |d       rR|sP| j                  |   }||k(  r<|| j                  v r.| j                  j                  d
|d       | j                  |   S || j                  |<   | j                  j                  d|d|       | j                  j                  t        ||      }		 |	j                         }
|
j                  di       j                  di       r+t        |
j                  di       j                  di             | j                  |
      | j                  |<   | j!                  |      S # t        j                  $ r# | j                  j                  | d       i }
Y w xY w)NzUnknown calendar type: zen-USUS)langregionDESCrG   rH   d   )sortTypeentityIdTyperG   rH   sizeoffsetqueryzGetting calendar_type=z from local cachezFetching calendar_type=z with limit=)paramsbodyz: Failed to retrieve calendar.financeerror)PREDEFINED_CALENDARSr   minr*   r   getr   ry   r   rz   post_CALENDAR_URL_jsonJSONDecodeErrorr   
_create_df_cleanup_df)r   calendar_typer   limitr   forcer   r   
cache_bodyresponse	json_datas              r   	_get_datazCalendars._get_data   s     44 7GHH!T2)-m<[I1-@QsO]]_
 ##''t<U11-@JT!mt~~&E""%<m-==N#OP~~m4426  /5}&6mUHEF!ZZ__^FQU_V	 I ==B'++GR8immIr:>>wKLL(,	(B}%.. ## 	LL-0NOPI	s   F 3GGc                    g }|d   d   d   d   d   d   D ]-  }|j                  |d          |d   dk(  s |d   d	k(  s)d
|d<   / |d   d   d   d   d   d   }t        j                  ||      S )Nr   resultr   	documentscolumnslabelrC   typeSTRINGTimingrows)r   )r#   pd	DataFrame)r   r   r   colr   s        r   r   zCalendars._create_df  s    Y'1!4[A!DYO 	'CNN3w<(7|11c&kX6M&	' #H-a0=a@H||D'22r!   c                   t         |   }| j                  |   }|j                  r|S |d   }|r5||   j                  d      j	                  dt
        j                        ||<   |j                  |d   d       |d   j                         D ]  \  }}|j                  ||id        |d	   D ]  }t        j                  ||         ||<    |S )
NrI   float64g        rK   T)inplacerL   )r   r   rJ   )r   r   emptyastypereplacenpnan	set_indexitemsrenamer   to_datetime)r   r   
predef_caldfrI   rename_from	rename_todatetime_cols           r   r   zCalendars._cleanup_df  s    />
>>-888I $J/h<..y9AA#rvvNBxL 	Z
+T:&0&;&A&A&C 	F"KII{I6IE	F '7 	@L!~~b.>?B|	@ 	r!   c                Z   | j                   j                  s|s| j                   S | j                  j                  d       	 t	        dd      }|j                  di g      }t        dg       | _         |D ]j  }t        |      t        ur|j                  dd	      }|j                  d
d      }|s<|||k\  sD| j                   j                  t        dd|g             l | j                   S # t
        j                  $ r* | j                  j                  d       | j                   cY S w xY w)ax  
        Retrieve tickers from YF, converts them into operands accepted by YF.
        Saves the operands in self._most_active_qy.
        Will not re-query if already populated.

        Used for earnings calendar optional filter.

        :param force: if True, will re-query even if operands already exist
        :return: list of operands for active traded stocks
        z.Fetching 200 most_active for earnings calendarMOST_ACTIVES   )r   countz&Failed to retrieve most active stocks.quotesrx   symbolr   	marketCapr   eqr:   )r   r'   ry   r   r   r   	HTTPErrorr   r   r   r   r2   r#   )r   _market_capr   json_rawrawstockr:   t_market_caps           r   _get_most_active_operandsz#Calendars._get_most_active_operands&  s    ##,,U'''KL	(#.DH
 ll8bT*,T26 	UEE{$&YYx,F 99[!4L;.,+2M$$++M$6@R,ST	U #### ## 	(LLGH'''	(s   C- -:D*)D*c           
        | j                  |      }| j                  |      }|r|r|r|st        j                  dt        d       t	        dt	        dd|xs | j
                  g      t	        dd|xs | j                  g      g      S )z
        Get startdatetime operands for start/end dates.
        If no dates passed, defaults to internal date set on initialization.
        pWhen providing custom `start` and `end` parameters, you may want to specify both, to avoid unexpected behaviour.   
stacklevelandgter=   lte)r{   warningswarnUserWarningr   r   r   )r   r   r   r   r   s        r   _get_startdatetime_operatorsz&Calendars._get_startdatetime_operatorsN  s    
 ''.%%c*#3uMM C eov7L%MNeot7Htyy%IJ
 	
r!   c                   | j                  |      }| j                  |      }	|r|r|r|st        j                  dt        d       t	        dt	        dddg      t	        dt	        dd	d
g      t	        dd	dg      g      t	        dd|xs | j
                  g      t	        dd|	xs | j                  g      g      }
|B|dk  r t        j                  d| dt        d       |
j                  t	        dd|g             |r"|s |
j                  | j                  |             | j                  d|
|||      j                  dd      S )a/  
        Retrieve earnings calendar from YF as a DataFrame.
        Will re-query every time it is called, overwriting previous data.

        :param market_cap: market cap cutoff in USD, default None
        :param filter_most_active: will filter for actively traded stocks (default True)
        :param str | datetime | date start: overwrite start date (default set by __init__)             eg. start="2025-11-08"
        :param str | datetime | date end: overwrite end date (default set by __init__)             eg. end="2025-11-08"
        :param limit: maximum number of results to return (YF caps at 100)
        :param offset: offsets the results for pagination. YF default 0
        :param force: if True, will re-query even if cache already exists
        :return: DataFrame with earnings calendar
        r   r   r   r   r   r   usrx   	eventtypeEADERAr   r=   r   i zmarket_cap z, is very low, did you mean to set it higher?r9   rn   r   r   r   r   r   rC   F)	ascending)r{   r   r   r   r   r   r   r#   r   r   sort_values)r   
market_capfilter_most_activer   r   r   r   r   r   r   r   s              r   get_earnings_calendarzCalendars.get_earnings_calendarf  sd   4 ''.%%c*#3uMM C dXt$45%d[%,@A%d[%,@A eov7L%MNeot7Htyy%IJ
  !J&!*-YZ 
 LLu/BJ.OPQfLL77
CD~~'  
 +(E+
:	;r!   c                   | j                  |      }| j                  |      }|r|r|r|st        j                  dt        d       t	        dt	        dd|xs | j
                  |xs | j                  g      t	        dd|xs | j
                  |xs | j                  g      t	        dd|xs | j
                  |xs | j                  g      g      }| j                  d	||||
      S )aB  
        Retrieve IPOs calendar from YF as a Dataframe.

        :param str | datetime | date start: overwrite start date (default set by __init__)             eg. start="2025-11-08"
        :param str | datetime | date end: overwrite end date (default set by __init__)             eg. end="2025-11-08"
        :param limit: maximum number of results to return (YF caps at 100)
        :param offset: offsets the results for pagination. YF default 0
        :param force: if True, will re-query even if cache already exists
        :return: DataFrame with IPOs calendar
        r   r   r   rx   gteltr=   rN   rO   ro   r   )r{   r   r   r   r   r   r   r   )	r   r   r   r   r   r   r   r   r   s	            r   get_ipo_info_calendarzCalendars.get_ipo_info_calendar  s      ''.%%c*#3uMM C g9N4;;PTPaX\XaXa'bcgf6KTM^UYU^U^'_`gv7LdN_VZV_V_'`a
 ~~$  
 	
r!   c                N    | j                  d| j                  ||      |||      S )aX  
        Retrieve Economic Events calendar from YF as a DataFrame.

        :param str | datetime | date start: overwrite start date (default set by __init__)             eg. start="2025-11-08"
        :param str | datetime | date end: overwrite end date (default set by __init__)             eg. end="2025-11-08"
        :param limit: maximum number of results to return (YF caps at 100)
        :param offset: offsets the results for pagination. YF default 0
        :param force: if True, will re-query even if cache already exists
        :return: DataFrame with Economic Events calendar
        rp   r   r   r   r   r   r   r   r   r   s         r   get_economic_events_calendarz&Calendars.get_economic_events_calendar  s6      ~~*33E3?  
 	
r!   c                N    | j                  d| j                  ||      |||      S )aF  
        Retrieve Splits calendar from YF as a DataFrame.

        :param str | datetime | date start: overwrite start date (default set by __init__)             eg. start="2025-11-08"
        :param str | datetime | date end: overwrite end date (default set by __init__)             eg. end="2025-11-08"
        :param limit: maximum number of results to return (YF caps at 100)
        :param offset: offsets the results for pagination. YF default 0
        :param force: if True, will re-query even if cache already exists
        :return: DataFrame with Splits calendar
        rq   r   r   r   s         r   get_splits_calendarzCalendars.get_splits_calendar  s6      ~~"33E3?  
 	
r!   c                \    d| j                   v r| j                   d   S | j                         S )z(Earnings calendar with default settings.rn   )r   r   r&   s    r   earnings_calendarzCalendars.earnings_calendar	  s.     DNN*>>-00))++r!   c                \    d| j                   v r| j                   d   S | j                         S )z$IPOs calendar with default settings.ro   )r   r   r&   s    r   ipo_info_calendarzCalendars.ipo_info_calendar  s.     '>>*--))++r!   c                \    d| j                   v r| j                   d   S | j                         S )z/Economic events calendar with default settings.rp   )r   r   r&   s    r   economic_events_calendarz"Calendars.economic_events_calendar  s/     t~~->>"2330022r!   c                \    d| j                   v r| j                   d   S | j                         S )z&Splits calendar with default settings.rq   )r   r   r&   s    r   splits_calendarzCalendars.splits_calendar  s.     t~~%>>(++''))r!   )NNN)r   $Optional[Union[str, datetime, date]]r   r   ru   zOptional[Session])r   z)Optional[Union[str, datetime, date, int]]r/   r.   )   r   F)r   r.   r   r   r/   pd.DataFrame)r   r2   r/   r  )r   r.   r/   r  )F)r   Optional[float]r/   r   )NN)r/   r   )NTNNr   r   F)r   r  r   r1   r/   r  )NNr   r   F)r/   r  )r3   r4   r5   r6   r    r{   r   r   r   r   r   r   r   r   r   r   r7   r   r   r   r   r8   r!   r   rs   rs      s   	 7;48%)	535 25 #	5BC SX'/ '/)6'/	'/R
3* 27%$*%$	%$ %$N
0  '+#'D;#D; !D; 
D; D;L >C'
	'
 '
R >C
	
 
. >C
	
 
2 , , , , 3 3 * *r!   rs   )%
__future__r   r   typingr   r   r   r   r   r   numpyr   requestsr	   r
   r   pandasr   r   r   r   constr   utilsr   r   r   screenerr   datar   r   r   r   r~   r   rs   r8   r!   r   <module>r     s   "  3 3   2 2  . .  F F   #:
 :
z !>!:; )

 E,-)%%0
!. %
 B@!:
'0 %	
 V&$",#%	
. %
 &<
IU pz* z*r!   