o
    _�¿jw  ã                   @  s�   d Z ddlmZ ddlZddlmZmZ ddlmZ ddlm	Z	 ddl
mZmZ ddlmZmZmZ e d	¡Zd
Zddd„Zddd„ZdgZdS )a9  NSE option chain response parser.

Transforms the raw JSON payload from NSE's ``/api/option-chain-v3``
endpoint into a typed :class:`~indiaopt.models.option_chain.OptionChainResult`.

NSE response schema (simplified)::

    {
        "records": {
            "expiryDates": ["27-Jun-2024", ...],
            "data": [
                {
                    "strikePrice": 22000,
                    "CE": {
                        "openInterest": 12345,
                        "changeinOpenInterest": 678,
                        "impliedVolatility": 12.34,
                        "lastPrice": 45.6,
                        ...
                    },
                    "PE": { ... }
                },
                ...
            ],
            "underlyingValue": 22150.35
        },
        "filtered": { ... }
    }
é    )ÚannotationsN)ÚdatetimeÚtimezone)ÚAny)Ú
ParseError)ÚOptionChainResultÚOptionChainRow)Ú
safe_floatÚsafe_intÚsafe_int_or_zerozindiaopt.parsers.nseÚNSEÚrawúdict[str, Any]ÚsymbolÚstrÚreturnr   c              
   C  s^   zt | |ƒW S  ty   ‚  ty. } ztd|› d|› �|tt| ƒdd… d�|‚d}~ww )aœ  Parse an NSE ``option-chain-v3`` response into :class:`OptionChainResult`.

    Args:
        raw:    Raw JSON dict from NSE API.
        symbol: The trading symbol (used for error messages).

    Returns:
        Fully typed :class:`OptionChainResult`.

    Raises:
        :class:`~indiaopt.exceptions.ParseError`: If the response is missing
            required structure (e.g. ``"records"`` key absent).
    z*Unexpected error parsing NSE response for z: NéÈ   ©r   ÚexchangeÚraw_preview)Ú_parser   Ú	ExceptionÚEXCHANGEr   )r   r   Úexc© r   úO/home/dinkstrade/pdmp/venv/lib/python3.10/site-packages/indiaopt/parsers/nse.pyÚparse_option_chain.   s   üû€ÿr   c                   s0  |   d¡}t|tƒs%td|› dt|   d¡ƒj›d�|tt| ƒd d… d�‚|  d¡p+g }|r2|d nd }t|  d	¡ƒ‰ |  d
¡pAg }|sJt	 
d|¡ g }d}|D ]†}t|tƒs\|d7 }qPt|  d¡ƒ}	|	d u rl|d7 }qP|  d¡pri }
|  d¡pyi }| t|	t|
  d¡ƒt|
  d¡ƒt|  d¡ƒt|  d¡ƒt|
  d¡ƒt|  d¡ƒt|
  d¡ƒt|  d¡ƒt|
  d¡ƒt|  d¡ƒt|
  d¡ƒt|  d¡ƒt|
  d¡ƒt|  d¡ƒd�¡ qP|ràt	 d||¡ |jdd„ d� d }ˆ d u�r|�rt|‡ fdd„d�j}t	 d||ˆ t|ƒ¡ t|t|ˆ ||t tj¡|d�S )NÚrecordsz'NSE response missing 'records' key for z. Got type=uJ   . This often means the session cookie expired â€” the client will refresh.r   r   ÚexpiryDatesr   ÚunderlyingValueÚdatazWNSE response for %s has empty 'records.data'. Market may be closed or symbol not found.é   ÚstrikePriceÚCEÚPEÚopenInterestÚchangeinOpenInterestÚimpliedVolatilityÚ	lastPriceÚtotalTradedVolumeÚbidpriceÚaskPrice)ÚstrikeÚcall_oiÚcall_coiÚput_oiÚput_coiÚcall_ivÚput_ivÚcall_ltpÚput_ltpÚcall_volÚput_volÚcall_bidÚput_bidÚcall_askÚput_askz!Skipped %d malformed rows for %s.c                 S  s   | j S ©N)r,   ©Úrr   r   r   Ú<lambda>‰   s    z_parse.<locals>.<lambda>)Úkeyc                   s   t | jˆ  ƒS r;   )Úabsr,   r<   ©Ú
spot_pricer   r   r>   Ž   s    z9ATM strike for %s: %.2f (spot=%.2f, %d strikes available))r   r   ÚexpiryrB   Ú
atm_striker    Ú
fetched_atÚexpiry_dates)ÚgetÚ
isinstanceÚdictr   ÚtypeÚ__name__r   r   r	   ÚloggerÚwarningÚappendr   r   r
   ÚdebugÚsortÚminr,   Úlenr   r   Únowr   Úutc)r   r   r   rF   Únearest_expiryÚraw_dataÚrowsÚskippedÚitemr,   ÚceÚperD   r   rA   r   r   I   s’   

ÿú
ý
ñÿû
ør   )r   r   r   r   r   r   )Ú__doc__Ú
__future__r   Úloggingr   r   Útypingr   Úindiaopt.exceptionsr   Úindiaopt.models.option_chainr   r   Úindiaopt.utils.coercer	   r
   r   Ú	getLoggerrL   r   r   r   Ú__all__r   r   r   r   Ú<module>   s    



Z