o
    ͿSi*X                     @  sj   d dl mZ d dlmZmZmZ zd dlZdZW n e	y%   dZdZY nw ddl
mZ G dd	 d	ZdS )
    )annotations)DictAnyOptionalNTF   )IndicatorCalculatorc                   @  s  e Zd ZdZed<ddZed=ddZed=ddZed>d?ddZed@dAd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 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?d*d+ZedBd0d1Ze	2dCdDd6d7Ze	2dCdEd:d;Zd2S )FStrategyFeatureCalculatora6  Numeric/enum strategy features for GPT consumption.

    This is intentionally read-only and does not emit trading signals.
    It summarizes trend, volatility, range/ORB breakouts, HOD/LOD
    proximity, momentum bursts, volume climaxes, Fibonacci zones and
    simple candlestick patterns per timeframe.
    candlesr   returnOptional[pd.DataFrame]c                 C  sP   t sd S | sd S zt| }h d}||jsW d S |W S  ty'   Y d S w )N>   lowhighopenclose)
_PANDAS_OKpd	DataFrameissubsetcolumns	Exception)r	   dfrequired_cols r   G/var/www/html/Trade-python/app/v1/services/zerodha/strategy_features.py_safe_df   s   
z"StrategyFeatureCalculator._safe_dfr   pd.DataFrameDict[str, Any]c                 C  s  | d u s| j rdddS | d }t|dk rdddS |jddd }|jddd }t|jd	 }t|jd	 |jd
  }|t|jd	   krTt|jd	 kr]n n|d
kr]d}n|t|jd	   k rqt|jd	 k rzn n|d
k rzd}nd}t|d| krdnd}||dS )Nunknown)	directionstrengthr      	   Fspanadjust   r   uptrend	downtrendsidewaysMb`?strongnormal)emptylenewmmeanfloatilocabs)r   closesema_fastema_slow
last_closesloper   r   r   r   r   _trend_structure'   s    

44
z*StrategyFeatureCalculator._trend_structurec                 C  s   | d u s| j rddiS | d t}t|dk rddiS |  }|j r)ddiS |d  }|j r9ddiS t|jd }t|dkrLt|	 n|}|d| krZd}d|iS |d	| k rfd
}d|iS d}d|iS )Nregimer   r      r&   r         ?r   ffffff?r   r,   )
r-   astyper1   r.   
pct_changedropnarollingstdr2   median)r   r4   returnsrA   currentrC   r:   r   r   r   _volatility_regimeA   s*   z,StrategyFeatureCalculator._volatility_regimer;   lookbackintc           	      C  s   | d u s| j rddiS t| |d k rddiS | j|d  d }| jd }t|d  }t|d  }t|d }d| }||| krId	}n!||| k rRd
}nt|| |kr]d}nt|| |krhd}nd}|||dS )Nstatusr   r   r&   r   r   r   r*   breakout_upbreakout_downnear_range_highnear_range_lowinside_range)rI   
range_high	range_lowr-   r.   r2   r1   maxminr3   )	r   rG   windowlast
high_range	low_ranger7   tolrI   r   r   r   _range_breakout^   s.   
z)StrategyFeatureCalculator._range_breakout   candles_in_openc           	      C  s   | d u s| j st| |krddiS | jd | }| jd }t|d  }t|d  }t|d }d| }||| kr@d}n!||| k rId	}nt|| |krTd
}nt|| |kr_d}nd}|||dS )NrI   r   r&   r   r   r   r*   orb_breakout_uporb_breakout_downnear_or_highnear_or_lowinside_open_range)rI   or_highor_lowrQ   )	r   r[   firstrU   ra   rb   r7   rX   rI   r   r   r   _opening_range_breakout   s$   
z1StrategyFeatureCalculator._opening_range_breakoutc                 C  s   | d u s| j rdddS t| d  }t| d  }t| d jd }|| | }|| | }|dko8|dk }|dko@|dk }t|t|t|t|d	S )
NF)near_hodnear_lodr   r   r   r&   r   g~jth?)re   rf   distance_to_hoddistance_to_lod)r-   r1   rR   rS   r2   bool)r   high_daylow_dayr7   dist_hdist_lre   rf   r   r   r   _hod_lod_proximity   s   
z,StrategyFeatureCalculator._hod_lod_proximityc                 C  s  | d u s| j st| dk rddiS | d t}| d t}| d t}d| jv r2| d tnd }|| d t  }||  }t|d	krU|d	 jd
 n| }t|jd
 }t|jd
 }	d}
d }|d urt|dkrt|d	krt|d	 jd
 nt| }|dkrt|jd
 | }|dk}
|dko|d| k}|dko|	d| k}|r|r|
rd}nd}||dS )N
   rI   r   r   r   r   volumer   r;   r&   Fr    r   r<   r=   momentum_burstr,   )rI   volume_ratio)	r-   r.   r>   r1   r   r3   rA   r0   r2   )r   r4   highslowsvolumesbodyrange_	avg_range	last_body
last_range	vol_spikerr   avg_volstrong_bodyexpanded_rangerI   r   r   r   _momentum_burst   s4   (0z)StrategyFeatureCalculator._momentum_burstc                 C  s   | d u s| j sd| jvst| dk rddiS | d t}t|d jd }|dkr1ddiS t|jd }|| }|dkoG|t| k}t	||dS )	Nrp      climaxFr&   r          @)r   rr   )
r-   r   r.   r>   r1   rA   r0   r2   rR   ri   )r   ru   r|   last_vol	vol_ratio	is_climaxr   r   r   _volume_climax   s   $z(StrategyFeatureCalculator._volume_climaxc                 C  s^  | du s| j st| dk rddiS | d t}| d t}| d t}|jddd	 }|d
}tj|| 	 || 	 || 	 gd
dj
d
d}|d }t|jd }t|jd }	t|jd srt|jd nd}
||	 }|
dkr||
 nd}t	|dkrd}nt	|dkrd}nd}|dkrdn|dk rdnd}||t|t|dS )zHow far price is stretched from a recent mean (non-VWAP).

        Uses EMA(20) and ATR-like true range to express stretch in ATR multiples.
        Nr;   stretchr   r   r   r   Fr"   r   axis   r&   g        r   r   extremeg      ?mildnoneabovebelowat_mean)r   sidedistance_from_emaatr_multiples)r-   r.   r>   r1   r/   r0   shiftr   concatr3   rR   rA   r2   isna)r   r4   rs   rt   ema20
prev_closetratr14r7   last_emalast_atrdistanceatr_multr   r   r   r   r   _mean_reversion_stretch   sB   



"z1StrategyFeatureCalculator._mean_reversion_stretchc                 C  s  | du s| j st| dk rddiS | d t}| d t}| d t}|d}tj||  ||  ||  gdd	jdd	}|j	d
d }|j	dd
 }|j sY|j r]ddiS t|
 }t|
 }	|	dkrqddiS ||	 }
|
dk r|d}n	|
dkrd}nd}||
dS )z8Detect compression vs expansion using recent true range.N(   phaser   r   r   r   r   r   iir   r=   compressionr<   	expansionstable)r   recent_to_prior_ratio)r-   r.   r>   r1   r   r   r   r3   rR   r2   r0   )r   rs   rt   r4   r   r   recentprior
recent_avg	prior_avgratior   r   r   r   _volatility_shift  s<   



	
z+StrategyFeatureCalculator._volatility_shiftc                 C  s  | d u s| j st| dk rddiS | d t}| d t}| d t}| d t}|jd |jd |jd |jd f\}}}}|jd	 |jd	 |jd	 |jd	 f\}	}
}}t|| }|| }|d
kol|| dk }d}|rt|| d| krd}d|iS ||kr|
|	k r||kr||krd}d|iS ||k r|
|	kr||kr||krd}d|iS |t|| }t||| }|d| kr||k rd}d|iS |d| kr||k rd}d|iS )N   patternr   r   r   r   r   r&   r   g?g?dojibullish_engulfingbearish_engulfinghammershooting_star)r-   r.   r>   r1   r2   r3   rR   rS   )r   ohlco1c1h1l1o2c2h2l2rv   rw   
small_bodyr   
upper_wick
lower_wickr   r   r   _basic_patternsC  s:   ,,  	z)StrategyFeatureCalculator._basic_patternsc                 C  s  | du s| j st| dk rdddS d| jvsd| jvr!dddS | d t}| d t}| d t}|jdd }t|dk rHdddS |jdd	 }|jd	d }t|j|  }t|j|  }t|j|j| 	  }	t|j|j| 	  }
t|j|j| 	  }t|j|j| 	  }d}d}||kr|
|	k rd
}t|j| 
 }t|j| 
 }t|j|j|   }t|j|j|   }||k r||krd}||kr||k rd
}t|j|j|   }t|j|j|   }||k r||krd}||dS )zVery simple regular divergence detection on last two swings.

        Looks at price vs RSI and MACD highs in two recent windows.
        Nr   r   )rsimacdr   r   r      bearishbullish)r-   r.   r   r>   r1   r2   indexlocrR   idxmaxrS   idxmin)r   r4   r   r   rT   	older_idx
recent_idxprice_old_highprice_recent_highrsi_old_at_highrsi_recent_at_highmacd_old_at_highmacd_recent_at_highrsi_divmacd_divprice_old_lowprice_recent_lowrsi_old_at_lowrsi_recent_at_lowmacd_old_at_lowmacd_recent_at_lowr   r   r   _rsi_macd_divergencef  sF   



z.StrategyFeatureCalculator._rsi_macd_divergencec                 C  s  | du s| j sd| jvst| dk rddiS | d t}| d t}|jdd }t|dk r5ddiS |jdd }|jdd }|j|  }|j|  }t|j| }t|j| }	t|j| }
t|j| }d}d}|	|kr||
d	 k rd
}|
dkr||
 nd}||dS )zEPrice makes a new extreme but volume fades relative to prior extreme.Nrp   r   
divergencer   r   r   r   g?bearish_price_up_vol_downr   )r   volume_ratio_vs_prev_high)	r-   r   r.   r>   r1   r2   r   r   r   )r   r4   ru   rT   r   r   price_old_high_idxprice_recent_high_idxr   r   vol_old_highvol_recent_highdivr   r   r   r   _volume_divergence  s*   $
z,StrategyFeatureCalculator._volume_divergencec                 C  s  | du s| j st| dk ri S | d t}| d t}| d t}t|jd }t|dkr8|jdd n|}t|dkrG|jdd n|}g }g }td	t|d	 D ]:}	|j|	 |j|	d
 |	d	   krt|t|j|	  |j|	 |j|	d
 |	d	   kr|t|j|	  qV|s|si S d}
d}|D ]}||kr|du s||k r|}q|D ]}||kr|
du s||
kr|}
qi }|
dur|
|d< ||
 | |d< |dur||d< || | |d< |S )zGApproximate horizontal support/resistance from recent swing highs/lows.Nr;   r   r   r   r&   2   ir   r   supportdistance_to_support
resistancedistance_to_resistance)	r-   r.   r>   r1   r2   rangerR   appendrS   )r   r4   rs   rt   r7   window_highswindow_lowspivot_highs
pivot_lowsisupresphplinfor   r   r   _support_resistance_zones  sH   $$z3StrategyFeatureCalculator._support_resistance_zonesc           
      C  s   | du s| j st| |d k rddiS | j|d  d }| jd }t|d  }t|d  }t|d }t|d }t|d	 }d}	||krQ||k rQd
}	n
||k r[||kr[d}	|	||dS )zGDetect simple buy/sell-side liquidity sweeps around obvious highs/lows.Nr   sweepr   r   r&   r   r   r   buy_side	sell_side)r   ref_highref_low)r-   r.   r2   r1   rR   rS   )
r   rG   rT   rU   	prev_highprev_low	last_highlast_lowr7   r   r   r   r   _liquidity_sweep  s   
z*StrategyFeatureCalculator._liquidity_sweeppricer1   
fib_levelsOptional[Dict[str, Any]]c                 C  s   |r| d u r
ddiS | di pi }zt| d}t| d}t| d}t| d}W n ty=   ddi Y S w d}| |krK| |k rKd}n#| |krV| |k rVd	}n| |kra| |krad
}n| |krhd}n| |k rnd}|||||ddS )Nzoner   retracements038.261.8100between_0_38between_38_62between_62_100	above_100below_0)r	  r
  r  r  )r  
ref_levels)getr1   r   )r  r  retrr0r382r618r100r  r   r   r   _fib_zone_for_price  s.   z-StrategyFeatureCalculator._fib_zone_for_priceN	timeframestrfib_dayc                 C  sH  | d u s| j r	i S z	t|  }W n ty   | }Y nw t|}t|}t|}t	|}t
|}t|}	t|}
t|}t|}t|}t|}t|}t|}| }d|v rmt|}nddi}i }zt|d jd }t||}W n ty   ddi}Y nw |||||||	|
|||||||dS )	NminuterI   not_applicabler   r&   r  r   )trend
volatilityrange_breakoutopening_rangehod_lodrq   volume_climaxr   fib_zonemean_reversionvolatility_shiftrsi_macd_divergencevolume_divergencesupport_resistanceliquidity_sweep)r-   r   add_all_indicatorscopyr   r   r9   rF   rY   rn   r   r   r   r   r   r   r   r   r  lowerrd   r1   r2   r  )r   r  r  df_indr  
vol_regime	range_brkr#  momentum
vol_climaxpatternsmean_rev	vol_shiftrsi_macd_divvol_divsup_res	liquiditytf_normorbr%  r  r   r   r   summarize_timeframe!  s^   












z-StrategyFeatureCalculator.summarize_timeframecandles_by_timeframefibc           
      C  s   t s	i ddidS d}|r"t|tr"d|v rd|v r|}n|d}i }|  D ]\}}t|}tj|||d}|r?|||< q(d	d
 | D }d}	|rgt	dd |D rYd}	nt	dd |D red}	nd}	|d|	idS )z@Build per-timeframe and multi-timeframe strategy-style features.trend_alignmentr   )per_timeframemulti_timeframeN
swing_highr  day)r  c                 S  s(   g | ]}| d r| d i  dqS )r  r   )r  ).0vr   r   r   
<listcomp>x  s   ( zBStrategyFeatureCalculator.summarize_strategies.<locals>.<listcomp>c                 s      | ]}|d kV  qdS )r'   Nr   rE  dr   r   r   	<genexpr>{      zAStrategyFeatureCalculator.summarize_strategies.<locals>.<genexpr>
aligned_upc                 s  rH  )r(   Nr   rI  r   r   r   rK  }  rL  aligned_downmixed)
r   
isinstancedictr  itemsr   r   r=  valuesall)
r>  r?  r  per_tftfr	   r   summary
directions	alignmentr   r   r   summarize_strategies\  s6   

z.StrategyFeatureCalculator.summarize_strategies)r	   r   r
   r   )r   r   r
   r   )r;   )r   r   rG   rH   r
   r   )rZ   )r   r   r[   rH   r
   r   )r  r1   r  r  r
   r   )N)r   r   r  r  r  r  r
   r   )r>  r   r?  r  r
   r   )__name__
__module____qualname____doc__staticmethodr   r9   rF   rY   rd   rn   r   r   r   r   r   r   r   r   r  r  r=  rZ  r   r   r   r   r      sP    !%1)"6 .:r   )
__future__r   typingr   r   r   pandasr   r   r   
indicatorsr   r   r   r   r   r   <module>   s    