o
    ̿SiD                     @  s"  U d dl m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mZmZmZmZmZmZ d dlmZ d dlmZ eeZed	Zg d
Zded< edd p]dZeeddZ eeddZ!eeddZ"eeddZ#eeddZ$e%eddd Z&e%eddZ'e%eddZ(e%ed d!Z)e%ed"d#d Z*ed$d%G d&d' d'Z+drd,d-Z,dsd/d0Z-dtd4d5Z.dud:d;Z/dvd=d>Z0dwd?d@Z1dxdAdBZ2dydDdEZ3dzdIdJZ4d{dNdOZ5d|dWdXZ6d}d\d]Z7d~d`daZ8ddgdhZ9ddidjddkddpdqZ:dS )    )annotationsN)	dataclass)datetime	timedelta)median)AnyDictIterableListOptionalTuple)ZoneInfo)ZerodhaClientzAsia/Kolkata)NIFTY 50z
NIFTY BANKzNIFTY PSU BANKzNIFTY FIN SERVICEzNIFTY ITz
NIFTY AUTOzNIFTY PHARMAzNIFTY HEALTHCARE INDEXzNIFTY METALzNIFTY ENERGYzNIFTY OIL & GASzNIFTY REALTYzNIFTY INFRAz
NIFTY FMCGzNIFTY CONSUMER DURABLESzNIFTY CAPITAL GOODSz	List[str]DEFAULT_INDEX_QUERIESMI_PRIMARY_INDEXr   $MARKET_INTELLIGENCE_INTERVAL_SECONDS900MI_EMA_PERIOD20MI_ATR_PERIOD14MI_STRUCTURE_LOOKBACK6MI_TREND_LOOKBACK12MI_MIN_TREND_PCTz0.35      Y@MI_SLOPE_ATR_FRACTIONz0.08MI_VOL_LOW_RATIOz0.85MI_VOL_HIGH_RATIOz1.25MI_SECTOR_MIN_MOVE_PCTz0.30T)frozenc                   @  s>   e Zd ZU ded< ded< ded< ded< ded< ded< d	S )
Candler   tsfloatohlcvN)__name__
__module____qualname____annotations__ r/   r/   A/var/www/html/Trade-python/app/v1/services/market_intelligence.pyr#   =   s   
 r#   r*   r   returnOptional[float]c                 C  sV   z | d u s
t | trW d S t| }t|st|rW d S |W S  ty*   Y d S w N)
isinstanceboolr%   mathisnanisinf	Exception)r*   fr/   r/   r0   _safe_floatG   s   r;   Optional[datetime]c                 C  sN   t | tr| S t | tr%|  r%z
t| ddW S  ty$   Y d S w d S )NZz+00:00)r4   r   strstripfromisoformatreplacer9   )r*   r/   r/   r0   _to_datetimeS   s   
rB   rawIterable[Dict[str, Any]]List[Candle]c           	      C  s   g }| pg D ]W}t |tsqt|d}|sqt|d}t|d}t|d}t|d}t|d}d ||||fv rDq|t|t|t|t|t|t|pXdd q|jd	d
 d |S )Ndateopenhighlowclosevolume        )r$   r&   r'   r(   r)   r*   c                 S  s   | j S r3   )r$   )xr/   r/   r0   <lambda>o   s    z$_normalize_candles.<locals>.<lambda>)key)	r4   dictrB   getr;   appendr#   r%   sort)	rC   outrowr$   r&   r'   r(   r)   r*   r/   r/   r0   _normalize_candles_   s"   
4rV   valuesList[float]periodintc                 C  sl   | sg S t dt|}d|d  }g }| d }|| | dd  D ]}|| |d|   }|| q"|S )N   g       @      ?r   )maxrZ   rR   )rW   rY   kemaprevrM   r/   r/   r0   _emas   s   
ra   candlesc                 C  sp   t | dk rg S g }| d j}| dd  D ] }t|j|j t|j| t|j| }|t| |j}q|S )N   r   r[   )lenr)   r]   r'   r(   absrR   r%   )rb   rT   
prev_closer)   trr/   r/   r0   _true_ranges   s   
(rh   c                 C  s\   t | }|sd S tdt|}t||k rtt|t| S || d  }tt|| S )Nr[   )rh   r]   rZ   rd   r%   sum)rb   rY   trswindowr/   r/   r0   _atr   s   rl   c                 C  sX   d}d}| D ]}|j |j |j d }|||j 7 }||j7 }q|dkr&d S t|| S )NrL   g      @r   )r'   r(   r)   r*   r%   )rb   pvvvr)   tpr/   r/   r0   _vwap   s   rp   lookbackc                 C  s   t dt|}t| |kr| | d n| }t|dk rdS d}tdt|D ]"}|| j||d  jkr9|d7 }|| j||d  jkrI|d7 }q'|S )z>Higher-high + higher-low score in the last `lookback` candles.   Nr   r[   )r]   rZ   rd   ranger'   r(   )rb   rq   rk   scoreir/   r/   r0   _structure_score   s   rv   ar%   bc                 C  s0   | d u s|d u r
d S |dkrd S t | | | S Nr   )r%   )rw   rx   r/   r/   r0   _pct_change   s
   rz   atr_pctatr_pct_historyTuple[str, Dict[str, Any]]c                 C  s   | d u r
dddifS dd |D }|rt |n| }|r!t| | nd}|tkr/d| ||dfS |tkr;d	| ||dfS d| ||dfS )
NModeratereasonmissing_atrc                 S  s    g | ]}|d ur|dkr|qS ry   r/   ).0rM   r/   r/   r0   
<listcomp>   s     z%_volatility_state.<locals>.<listcomp>r\   High)r{   baselineratioLow)r   r%   VOL_HIGH_RATIOVOL_LOW_RATIO)r{   r|   histbaser   r/   r/   r0   _volatility_state   s   r   rJ   r_   ema_prevvwapatrstructure_score	trend_retc              	   C  s  |pd}t || }|dkrt|t| knt|dk}|d u p#| |k}	|d u p+| |k}
|d uo3|tk}|d uo<|t k}| |koN|	oN|dkoN|oN|dkoN|}| |k o`|
o`|dk o`|o`|dko`|}|rodd| |||||dfS |r}dd	| |||||dfS d
d| |||||dfS )NrL   r      rc   Trendingup)	directionrJ   r_   	ema_sloper   r   r   BearishdownSidewaysflat)r%   re   SLOPE_ATR_FRACTIONMIN_TREND_PCT)rJ   r_   r   r   r   r   r   slopeslope_okabovebelowtrend_ok_uptrend_ok_dnbullbearr/   r/   r0   _market_bias   sL   
$$$	
r   market_biasr>   volatility_statec                 C  sD   |pd   }| pd   }|dkrdS |dkr |dv r dS dS )N rH   r   rI   >   bearishtrendingr   Medium)r?   lower)r   r   vbmbr/   r/   r0   _overall_risk  s   r   queryOptional[int]c              	   C  s  |pd  }|s
dS z'| d d| ddddd	d
di}|r0|d
dur0t|d
W S W n	 ty:   Y nw z'| d d| dddddd
di}|ra|d
durat|d
W S W n	 tyk   Y nw | d d| dddddd
di}|r|d
rzt|d
W S  ty   Y dS w | d d| dddddd
di}|r|d
rzt|d
W S  ty   Y dS w | d ddiddi}t|tr|dnd}t|trM|rM| }|D ]]}t|tsqt	|dpd   }t	|dpd   }	t	|dpd   }
|
r)|
dkr)q||ks3|	|krL|d
}zt|W   S  tyK   Y  dS w qdS )zResolve an instrument token from cached Zerodha instruments.

    We attempt exact match on tradingsymbol (case-insensitive), and fall back to name.
    r   Nstocks^$ru   )z$regexz$optionsNSE)symbolexchangeinstrument_tokenr[   )namer   zerodha_instruments)tradingsymbolr   type
nse_equityinstrumentsr   r   r   )
r?   find_onerQ   rZ   r9   r4   rP   listupperr>   )dbr   qdoccachedarrq_upperinstr$   nmextokr/   r/   r0   _resolve_instrument_token  s   

r   zerodha_clientr   r   interval	days_backc                 C  s@   t  }|tttd|d }| jj||||ddd}t|S )z@Fetch candles from Zerodha (raw list), normalize to Candle list.r[   )daysF)r   	from_dateto_dater   
continuousoi)r   utcnowr   rZ   r]   kitehistorical_datarV   )r   r   r   r   endstartrC   r/   r/   r0   _fetch_candlesZ  s   	r   15minute   )captured_atr   r   index_queriesr   r   Optional[List[str]]Dict[str, Any]c           :        sD  |pt  }|p	t}i }g }|D ]!}zt| |}	W n ty$   d}	Y nw |	r,|	||< q|| qt|vr>tdt d|t }
t||
||d}t	|t
tttd k rbtdt dt	| dd	 |D }t|t}|d
 }t	|dkr||d n|}|d
 }t|t}|r|rt|| d nd}g }ttd tt	|dD ]$}|d|d  }t|t}|r|d
 jr|t||d
 j d  qt||dd \}}|t   fdd	|D }t|p|dd }t|t}t	|tkr|t d  jn|d j}t||}t|t|t|||||d\}}t||} g }!g }"g }#i }$| D ]O\}}	|tkr9q-zt||	||d}%t	|%t
tttd k rSW q-dd	 |%D }&t|&t}'|&d
 }(|'d
 })t	|'dkrr|'d n|)}*t|%t}+|+r|(rt|+|( d nd},g }-ttd tt	|%dD ]'}|%d|d  }t|t}|r|d
 jr|-t||d
 j d  qt|,|-dd \}.}/t	|%tkr|%t d  jn|%d j}0t|(|0}1t|)|* }2d}3|.dkrd}3|#| n<|(|)ko
|1duo
|1tko
|2dk}4|(|)k o|1duo|1t ko|2dk }5|4r*d}3|!| n
|5r4d}3|"| |3|1|(t|)|2d|.i|/d|$|< W q- ty} }6 z)t !ddpXd" # }7|7dv}8|8rlt$%d ||6 nt$&d!| W Y d}6~6q-d}6~6ww |t|||| t't(|!t't(|"t't(|#d"||d#|$|d$d%}9|9S )&zpCompute deterministic Market Intelligence Summary.

    No LLMs, no probabilistic logic. Purely rule-based.
    NzPrimary index 'z"' not found in zerodha_instruments)r   r   r   r      zNot enough candles for z: c                 S     g | ]}|j qS r/   r)   r   r)   r/   r/   r0   r         z7compute_market_intelligence_summary.<locals>.<listcomp>rc   r      r[   ic                   s$   g | ]}|j t  kr|qS r/   )r$   
astimezoneISTrF   r   	today_istr/   r0   r     s   $ ir   )rJ   r_   r   r   r   r   r   c                 S  r   r/   r   r   r/   r/   r0   r     r   NEUTRALr   VOLATILEBULLISHBEARISHstate)classretrJ   r_   r   
volatility
QUIET_LOGStrue)0falsenooffz#[MI] Failed computing sector %s: %sz[MI] Failed computing sector %s)bullishr   volatile)biasr   )marketsectorsmissing_indices)r   primary_indexr   r   r   overall_risksector_strengthdiagnostics))r   r   r   r   r9   rR   PRIMARY_MARKET_INDEXRuntimeErrorr   rd   r]   
EMA_PERIOD
ATR_PERIODTREND_LOOKBACKra   rl   r%   rs   minr)   r   r   r   rF   rp   rv   STRUCTURE_LOOKBACKrz   r   r   itemsSECTOR_MIN_MOVE_PCTosgetenvr?   r   loggerwarning	exceptionsortedset):r   r   r   r   r   r   token_by_namemissingr   r   	nifty_toknifty_candlescloses
ema_seriesema_lastr   
close_lastr   r{   atr_pct_histru   subrw   	vol_statevol_diagsessionr   struct_scorerefr   r   	bias_diagr  r   r   r   sectors_debugrb   closes_sema_sclose_s
ema_last_s
ema_prev_satr_s	atr_pct_satr_pct_hist_ssector_vol_statesector_vol_diagref_sret_sslope_sclsr   dnerC   quietsummaryr/   r   r0   #compute_market_intelligence_summarys  s   




(






 
(

&(

	


r7  )r*   r   r1   r2   )r*   r   r1   r<   )rC   rD   r1   rE   )rW   rX   rY   rZ   r1   rX   )rb   rE   r1   rX   )rb   rE   rY   rZ   r1   r2   )rb   rE   r1   r2   )rb   rE   rq   rZ   r1   rZ   )rw   r%   rx   r%   r1   r2   )r{   r2   r|   rX   r1   r}   )rJ   r%   r_   r%   r   r%   r   r2   r   r2   r   rZ   r   r2   r1   r}   )r   r>   r   r>   r1   r>   )r   r>   r1   r   )
r   r   r   rZ   r   r>   r   rZ   r1   rE   )r   r   r   r<   r   r>   r   rZ   r   r   r1   r   );
__future__r   loggingr6   r  dataclassesr   r   r   
statisticsr   typingr   r   r	   r
   r   r   zoneinfor   app.v1.services.zerodha.clientr   	getLoggerr+   r  r   r   r.   r  r?   r  rZ   MI_INTERVAL_SECONDSr  r  r
  r  r%   r   r   r   r   r  r#   r;   rB   rV   ra   rh   rl   rp   rv   rz   r   r   r   r   r   r7  r/   r/   r/   r0   <module>   sZ     

	










7

M