o
    ̿Si                     @   s
  d dl Z d dlZd dlmZ d dlmZmZ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 d dlmZ d d	lmZ e eZ	
ddededee dededededeeef fddZ	
ddedee dedee dedededeeeef  fddZdS )    N)datetime)AnyDictListOptional)HTTPException)ZerodhaClient)prepare_market_data_promptcall_chatgpt_analysis)TEGPT_VERBOSE_LOGS)fetch_market_data) compact_analysis_for_persistenceFzerodha_clientsymbol
timeframesquestioncontextuser_idinclude_market_datareturnc           F         s  zpd   ttdtpd    tdtdd}|dkrztdd |p1g D }	d	 j|||	d
ddgd}
|
rt|
	dt
rt
 |
d   }|dkr|t|d kr|
	dpli }t|tr|rt|}t|
	d|d< |
d  |d< |d< dt|dd|d< |r|
	d}t|tr|r||d< td| |W W S W n ty   td Y nw td tdd |pg D }t||d}dtttf dtttf fd d!}||}|	d"i  D ]&\}}|r!td#t| t||d$ pi 	d%|d$ pi 	d& q|	d'r3td(d)|d'  d*td+ d,d-  dtttf f fd.d/}| }t|||d0}td1t| dtttf dtttf ffd2d3}tr~td4 ntd5 t|}d6}zRttd7d8  d8k}ttd9d:}ttd;d8  d8k}|rt|trt|	d<pd }|d=kr||}t|	d<pd }|	d>}z|d?urt|nd@} W n ty   d@} Y nw d}!|rht|	dA}!|!sht|tr|	dBpi ni }"t|"tr"|"	dCp!i ni dD}ttr1	|nd?}#t|#trh|#	dEp@i }$|#	dFpHi }%|#	dGpPi }&|$	dHdIv pg|%	dHdJv pg|&	dHdGk}!|dKv r| |kr|!r||d<< | dLkrdMndN|dO< | dLkrdMndN|dP< tt| |d>< tt dQt!d@| |dR< |"dSg  t|	dSt#rdTtt|  dUg|dS  d?dV |dS< dW|dX< |tt| t|	dAdY|dZ< W n ty   tjd[dd\ Y nw t|tr|	d]d^krt$d_ ||}d^|d`< da|dX< d}z/t|tr|	d<nd?p!db}'t|tr-|	dOnd?p1db}(t|tr=|	dRnd?})W n tyO   dc\}'}(})Y nw |rUddnde}*tdf|*t|' t|( |)d?urm|)ndg trtdh tdi|	d<db tdj|	dOdb tdk|	dRdb tdl|	dmdb tdn|	dodb tdp|	dqi  tdr|	dsdb tdt|	dSg  |	d<duvrt$dv|	d< d=|d<< dtttf dt%t fdwdx}+|+||dy< dztdt%t fd{d|d@d}d~dtdtdtdtdtf
dddtttf dt%tttf  ffdd},d<tdt%t dt%tttf  dt%t ffdd}-dtttf dt&t ffdd}.d<tdtttf dtttf dtttf ffdd}/t|	d<pyd }0|0dKv r|,|}1|1r|1|d< |	do}2|-|0|2|1d}2|2d?urt|2|d< |.|}3|3r|3|d< |	d}4|4d?urt|4|d< |/|0|1|d}5|5	dpg |d< |5	dpd|d< n|"dd td|d<  |	di |	dBi |	di |	di d}6|6|d< zyt|	d<pd=   }0t|6tr$|6	dBni }7t|7tr4|7	dCp3i ni dt%t ffdd}8|8 }9|9rRttrR	|9ni }:t|:tr\|:ni }:tt|:	dEtrp|:	dEpoi ni 	dHpwd};tt|:	dFtr|:	dFpi ni 	dHpd}<tt|:	dGtr|:	dGpi ni 	dHpd}=tt|:	dtr|:	dpi ni 	dpd}>|0dkrd|d< |<dks|;dkrd|d< nR|=dGkrd|d< nH|>dkrd|d< n>d|d< n9|0dkr,d|d< |<dks|;dkrd|d< n!|=dGkrd|d< n|>dkr'd|d< nd|d< nd|d< d|d< t|	dtrJt|	dpEd  s|	ddkrddt|	dp[d'  |d< n|	ddkr~dt|	dpud'  |d< nd|d< W n ty   |"dd |"dd Y nw zddl(m)}? |?t|	d<pd |d}@|@d?urZ|@j*|d< |@j+|d< |@j,|d< |@j-|d< |@j.|d< |@j/|d< |@j0|d< |"d|@j* |"d|@j+ |	dd?u r|@j,d?ur|@j,|d< |	dd?u r|@j-r|@j-|d< |	dd?u r|@j.d?ur|@j.|d< |"d|@j/ t|	d|d< |@j0p3i 	dǡ}At|At#r?|Ang |d< tdɈt|	d<pOd |@j/|@j*|@j+ W n tyk   tdʈ Y nw |	dˡ}B|Bd?urz|B|d< |t1|||6||t
 d̜	}Cd	 2|C}Dt|Dj3|d< |Cd  |d< |d< |r||d< td͈ |W S  ty     ty }E ztdΈ tdt|Ed*d?}E~Eww )zAnalyze single symbol.

    Logging is intentionally minimal at INFO. Enable verbose tracing via
    `TEGPT_VERBOSE_LOGS=true`.
     GPT_ANALYSIS_CACHE_MINUTES_"GPT_ANALYSIS_CACHE_MINUTES_DEFAULTGPT_ANALYSIS_CACHE_MINUTES0r   c                 S      g | ]}t |qS  str.0tfr   r   E/var/www/html/Trade-python/app/v1/services/tegpt/analysis_services.py
<listcomp>0       z*analyze_symbol_service.<locals>.<listcomp>analyses)r   r   r   r   r   )	timestamp_idr'   sortr&   g      N@analysisr)   analysis_idr   T   )hitage_secondscachemarket_datau3   ♻️ USING CACHED GPT ANALYSIS for %s (age=%.1fs)zCache lookup failed for %su   🔍 STARTING ANALYSIS for %sc                 S   r   r   r   r   r   r   r"   r#   S   r$   )dbmdr   c                 S   sD   t | tsi S i }dD ]}|| v r| |d ur| |||< q|S )N)instrument_tokenstock_id
indicators
strategiespivotsfiberror
isinstancedictget)r4   outkr   r   r"   _compact_market_dataW   s   
	z4analyze_symbol_service.<locals>._compact_market_datacandlesu*      📊 %s: %d candles, Latest: O:%s, C:%sr'   opencloser;   i  zMarket data error: )status_codedetailu%   🤖 CHATGPT ANALYSIS STARTING for %sc                 S   sZ   | d u rd S t | tr| S t | tr+zt| ddjd dW S  ty*   Y d S w d S )NZz+00:00)tzinfo)r=   r   r   fromisoformatreplace	Exception)vr   r   r"   
_as_utc_dty   s   

z*analyze_symbol_service.<locals>._as_utc_dtc               	      st  z,d j ddig dd} | si W S | dpi }| dp*| dp*| d	}d
tdtfdd dtdtttf dtt f fdd}i }|rT| d |d< t|tr+|ddurh|d|d< |ddurv|d|d< |ddur|d|d< |ddur|d|d< zd  didddddd}W n t	y   d}Y nw t|tr+|d pd!
 }|d"pd!
 }|r||d#< |r||d$< t|tr|d%pi d&pi ni }t|tr||p||nd}	|	r+t||	tr+||	pi }
t|
d'tr|
d'ni }|	|
d(|
d)|d*d+|d,< |W S  t	y9   i  Y S w )-z4Best-effort broad market context for the GPT prompt.market_intelligence_summarytypelatest))
updated_atr'   )captured_atr'   r(   r*   payloadrS   rR   
created_atrM   r   c                 S   sL   t | pd  }g }|D ]}|| r|nd qdd| S )Nr    )r   stripupperappendisalnumjoinsplit)rM   s	out_charschr   r   r"   	_norm_key   s
   zRanalyze_symbol_service.<locals>._get_latest_market_intelligence.<locals>._norm_keysector_valuesectors_debugc           	         s   | r	t |tr	|sd S | }|sd S t| }d }d}| D ],}|  s*q!t  }t||@ }t fdd|D rE|d7 }||krM|}|}q!|dkrT|S d S )Nr   c                 3   s    | ]}| v V  qd S )Nr   )r    tkkr   r"   	<genexpr>   s    znanalyze_symbol_service.<locals>._get_latest_market_intelligence.<locals>._best_sector_match.<locals>.<genexpr>r.   )r=   r>   setr\   keyslenany)	ra   rb   targettarget_tokensbest
best_scorerA   	kk_tokensoverlapr`   rd   r"   _best_sector_match   s*   z[analyze_symbol_service.<locals>._get_latest_market_intelligence.<locals>._best_sector_matchrH   as_ofmarket_biasNoverall_riskrisk_regimevolatility_statevolatility_regimesector_strengthstocksr   r   r.   )r)   r   sectorindustrynamer{   r   r|   symbol_sectorsymbol_industrydiagnosticssectors
volatilityclassretstate)indexr   r   rw   symbol_sector_trend)find_oner?   r   r   r   r   	isoformatr=   r>   rL   rW   )docrT   tsrr   r@   stock
sector_valindustry_valrb   	match_keydiagvol)rN   r3   r   rq   r"   _get_latest_market_intelligence   sl   "&   
z?analyze_symbol_service.<locals>._get_latest_market_intelligence)market_intelligenceu.   📝 PROMPT PREPARED for %s - Length: %d charsc                    s  dt ttf dtfdd}|| }| dpi |i pi }| dp$i }t|tr1|dp0i ni }t|tr>||i ni }|d}|d	}|d
}	|d}
|dpZi }t|dpbd  }|dv rod}n|dv rvd}n	|dv r}d}n|}|dpd}|dpi }|dpd}|dpi }|dpd}|dpi }|dpd}d}g }|dkr|d7 }|| d n|dkr|d7 }|| d zt	|dkr|d 7 }|d! W n	 t
y   Y nw |d"v r|d7 }|d#|  |d$v r|d%7 }|d&|  |d'v r#|d%7 }|d(|  z(|d)urJt	|}|d*kr<|d 7 }|d+ n|d,krJ|d 7 }|d- W n
 t
yU   Y nw z(|d)ur}t	|}|dkro|d.7 }|d/ n|dk r}|d.7 }|d0 W n
 t
y   Y nw z1|	d)ur|
d)urt	|	}t	|
}||kr|d.7 }|d1 n||k r|d.7 }|d2 W n
 t
y   Y nw td3td4|}d5} d6kr|dkr|d*krd7}nc|dkr|d8krd9}nV d:kr|dkr |d*kr d9}nD|dkr|d8krd7}n7|d"v p|d$v p|d;v }|dks(|r0|d<kr0|d=kr0d7}n|dks=|rD|d>krD|d=krDd9}d?}|d@krNdA}n|d*krUdB}t	|}|s_dCg}||tt|||d8k rndDndEt|d"v p}|d$v p}|d;v dF|d)dG |dkrdn|dkrdnd|d8krdHn|dIkrdJndKdLd)d)dJt|dMpi dMpdNd)dO dPdQdRdSdTS )UzIDeterministic, non-GPT fallback using computed indicators/strategy flags.md_r   c                 S   sL   dD ]}|  dp
i  |r|  S qt|  dpi  }|r$|d S dS )N5minute15minute30minutedayr7   r   r   )r?   listrh   )r   tf_rh   r   r   r"   _pick_tf   s   zRanalyze_symbol_service.<locals>._fallback_analysis_from_features.<locals>._pick_tfr7   r8   per_timeframersi	macd_histrE   vwaptrend	directionsideways>   upbullishuptrendr   >   downbearish	downtrendr   >   n/ar   naunknownstrengthr   range_breakoutstatusnoneopening_rangemomentum_burstg      I@
   z trend bullishz trend bearish      ztrend strength elevated>   breakout_upbreakout_downzrange breakout: >   orb_breakout_uporb_breakout_down   zopening-range breakout: >   strong	strong_upstrong_downr   zmomentum burst: N<   z
RSI strong(   zRSI weak   zMACD momentum positivezMACD momentum negativezprice above VWAPzprice below VWAP              Y@HOLDlong_buyBUYF   SELL
short_sell>   r   r   A   r   LOWK   HIGHMEDIUMz0Computed fallback from indicators/strategy flagsconservative
aggressivez#fallback computed (GPT unavailable)   r   7   neutralweaknormalpatternr   x   )r   momentumvolumesupport
resistanceaccumulation_distributionpattern_summaryg      ?intradayz,GPT unavailable; deterministic fallback used)decision
confidencescoredecision_probabilityrisk_profileearly_breakoutearly_breakout_comment	rationaletechnical_indicatorsrisk_reward_ratiotime_horizonnotes)r   r   r   r?   r=   r>   rW   lowerrY   floatrL   maxminintroundbool)r4   r   r!   indstper_tfflagsr   r   rE   r   r   raw_trend_dir	trend_dirtrend_strengthrb	rb_statusorb
orb_statusmb
mom_statusr   r   rmhcvwr   has_triggerr   r   )r   r   r"    _fallback_analysis_from_features   s"   




















$$




&	z@analyze_symbol_service.<locals>._fallback_analysis_from_featuresu!   🚀 SENDING TO CHATGPT for %s...z[teGPT] Sending to GPT | %sFTEGPT_RULE_OVERRIDE_ENABLED1TEGPT_RULE_OVERRIDE_MIN_SCORE65#TEGPT_RULE_OVERRIDE_REQUIRE_TRIGGERr   r   r   Nr   r   r8   r   r   r   r   r   r   >   r   r   >   r   r   >   r   r   U   r   r   r   
convictionr   r   r   z>Decision overridden from HOLD using rule-based signals (score=z).r   RULE_OVERRIDEdecision_source)r   r   r   rule_signalsz'[teGPT] Rule override evaluation failed)exc_info
error_typeinsufficient_quotau9   ⚠️ GPT quota exceeded for %s; using fallback analysisgpt_error_typeFALLBACK_QUOTAN/A)r  r  NzGPT FALLBACKzGPT OKz7[teGPT] %s | %s | decision=%s | confidence=%s | prob=%su   —u   🎯 CHATGPT RESPONSE for %s:u      📊 Decision: %su      🎯 Confidence: %su      🎯 Decision %%: %su      💰 Price Target: %sprice_targetu      🛡️ Stop Loss: %s	stop_lossu      🛡️ SL Zone: %sstop_loss_zoneu      📈 Entry Price: %sentry_priceu      🔍 Rationale: %s)r   r   r   u7   ⚠️ Invalid decision '%s' for %s, defaulting to HOLDc           
   	   S   s   z|  dpi }| d}|d urt|}|dkr|W S W n	 ty&   Y nw |  dp-i }dD ]3}| |p8g }|s<q0|d pAi }| d}z|d urYt|}	|	dkrY|	W   S W q0 tyc   Y q0w d S )Nquote
last_pricer   rC   r   r'   rE   )r?   r   rL   )
r4   qr  lpcandles_by_tfr!   rC   lastrE   r   r   r   r"   _infer_current_price  s8   


z4analyze_symbol_service.<locals>._infer_current_pricecurrent_pricerM   c                 S   s^   z$| d u s
t | trW d S t| }||ks|tdtdfv r"W d S |W S  ty.   Y d S w )Ninf-inf)r=   r   r   rL   )rM   fr   r   r"   _safe_float  s   z+analyze_symbol_service.<locals>._safe_floatg    eA	min_value	max_valuer}   defaultr%  r&  c                S   s   t | }|d u st| dkrt|S z
tt| }W n ty,   t| Y S w ||ks;|tdtdfv r?t|S tt|t||S )Nr   r   r!  )osgetenvr   rW   r   rL   r   r   )r}   r'  r%  r&  rawrM   r   r   r"   
_env_float"  s   
z*analyze_symbol_service.<locals>._env_floatac                    s   |  d}t|tr:| d}| d}|d ur:|d ur:|dkr:|dkr:||k r1||}}t|t|dS |  d}|d u rG}|d u sO|dkrQd S  ddd	d
d}t|d|  t|d|  dS )N
entry_zonelowhighr   )r.  r/  r  AI_ENTRY_ZONE_BUFFER_PCTMbP?r   {Gz?r$        ?)r?   r=   r>   r   )r,  zr.  r/  entrybuf)r+  r#  r  r   r"   _normalize_entry_zone.  s   

 
"z5analyze_symbol_service.<locals>._normalize_entry_zoneslzonec           	         s   |d u s|s|S | d}| d}|d u s&|d u s&|dks&|dkr(|S  ddddd}| p3d	 }|d
krUt|dt|  }t|t|k sN|S tt||S |dkrtt|dt|  }t|t|ksm|S tt||S |S )Nr.  r/  r   ENTRY_SL_BUFFER_PCTr1  r   r2  r$  r   r   r3  r   )r?   rX   r   r   r   )	r   r8  r9  zlzhsl_buffer_pctdmax_okmin_ok)r+  r#  r   r"   _ensure_sl_side@  s&    z/analyze_symbol_service.<locals>._ensure_sl_sidec                    sX   |  d}t|tr*g }|D ]} |}|d ur#|dkr#|t| q|d d S g S )Ntargetsr   r   )r?   r=   r   rY   r   )r,  arrvalsxr"  r#  r   r"   _normalize_targetsU  s   

z2analyze_symbol_service.<locals>._normalize_targetsc                    s  g }d}| pd  }|dpi }t|tr|dnd }t|tr'|dnd }d }	d }
t|tr9|r9d}	|}
nt|trE|rEd}	|}
n||dS t|
d trU|
d ni }t|
dkrht|
d	 trh|
d	 nd } fd
d}||d}||d}||d}||d}t|dpd}t|dpd}|dks|dkr||dS |dkr|d ur||kr||	dkrdnd n|d ur||kr||	dkrdnd |d ur||d}|d ur||kr|d ur||kr|d ur||kr||	dkrdnd nf|dkra|d ur||kr||	dkrdnd n|d ur-||k r-||	dkr*dnd |d ura||d}|d ura||kra|d ura||kra|d ura||k ra||	dkr^dnd |rfd }||dS )!NWAITING_FOR_ENTRYr   rC   r   r   )reasonsr   r'   r   c                    s.   t | tsd S  | |p| |d d S )Nr.   r<   )r   keyrF  r   r"   _cnumv  s   
 zFanalyze_symbol_service.<locals>._evaluate_entry_trigger.<locals>._cnumrD   rE   r/  r.  r   r   r   5M_CLOSE_ABOVE_ZONE15M_CLOSE_ABOVE_ZONE5M_GAP_OPEN_ABOVE_ZONE15M_GAP_OPEN_ABOVE_ZONEBREAKOUT_RETEST_HOLDBREAKOUT_RETEST_HOLD_15Mr   5M_CLOSE_BELOW_ZONE15M_CLOSE_BELOW_ZONE5M_GAP_OPEN_BELOW_ZONE15M_GAP_OPEN_BELOW_ZONEBREAKDOWN_RETEST_HOLDBREAKDOWN_RETEST_HOLD_15MENTRY_ACTIVATED)rX   r?   r=   r>   r   ri   r   rY   )r   r9  r4   rI  r   r>  r  	series_5m
series_15m
trigger_tfseriesr  prevrL  c_openc_closec_highc_lowzone_low	zone_high
prev_closerF  r   r"   _evaluate_entry_trigger`  st   
&















z7analyze_symbol_service.<locals>._evaluate_entry_triggerr-  )r   r8  r9  exec_slexec_targetsr   exec_rr_ratio)r   r9  r4   rI  entry_trigger_reasonr   rH  signal_stateu4   ✅ CHATGPT ANALYSIS FORMATTED for %s - Decision: %sr7   r9   r:   )r7   r8   r9   r:   featuresc                     s`   dD ]} t  | tr | r|   S q pi  D ]\}}t |tr-|r-t|  S qd S )N)r   r   r   r   weekmonth)r=   r?   r>   itemsr   )r!   rA   rM   )r   r   r"   _pick_tf_for_taxonomy  s   z5analyze_symbol_service.<locals>._pick_tf_for_taxonomyr   r   r   BULLISHr   r   BREAKOUTsetupRALLYr   TRENDr   BEARISHr   r   	BREAKDOWNWEAKNESSr   NO_TRENDNONEtrend_labelz
Bullish - Trendz
Bearish - Weakness)build_execution_plan)r   r2   entry_engine_entry_zone!entry_engine_entry_trigger_reasonentry_engine_exec_slentry_engine_exec_targetsentry_engine_exec_rr_ratioentry_engine_signal_stateentry_engine_diagnosticsentry_trigger_firedmissed_trade_reasonsentry_missed_trade_reasonsz0[EntryEngine] %s %s state=%s zone=%s triggers=%sz5[EntryEngine] Failed to compute execution plan for %sr5   )	r   r   r,   r2   rl  r   r   r   r&   u+   ✅ ANALYSIS COMPLETE for %s - Testing ModezSymbol analysis failed for %si  )4rW   rX   r   r(  r)  r   sortedr   r=   r?   r   utcnowtotal_secondsr   r>   r   r   loggerinforL   	exceptionr   r   r   ro  ri   r   r	   r   debugr
   r   r   r   
setdefaultr   warningr   r   titleapp.v1.services.entry_enginer~  r-  rj  r8  rB  rr_ratior   r   r   
insert_oneinserted_id)Fr3   r   r   r   r   r   r   r   cache_minuteskey_timeframescachedage_scached_analysisr4   r2   rB   market_data_compactr!   rC   r   r   promptr  r,   used_gpt_fallbackenable_rule_overrideoverride_min_scoreoverride_require_triggerd0rulerdrsrs_f
ok_triggerr   featsr   r   r   r   confproblog_tagr  r7  rA  rG  rf  decision_upperr9  r8  rc   rrtrigrl  r8   rp  tf_taxr   r   r   r   r   r~  planmissedr5   analysis_docresulter   )rN   r+  r#  r   r  r3   r   r   r"   analyze_symbol_service   s~  
	
"
Y& %

  

  

	&.4"6M






 	 " " " " 













,$$ 












r  symbolsanalysis_typemax_concurrentc                 C   sB  t dt|| t d| |st d g S dddd}|||d }	t d	| g }
d
}d
}t|d}t d| td
t||D ]}||||  }|| d }t|| d | }t d||| t|dD ]i\}}z.t d||t| t| ||||	d|t	|d}|

| |d7 }t d||dd W ql ty } z+|d7 }t d|t| |

|dddt| gt|t  d W Y d}~qld}~ww || t|k rd
dl}|d qEt d t d| t d| t dt|
 i }|
D ]}|dd}||d
d ||< qt d| |
S ) z=Bulk analyze multiple symbols with detailed progress logging.u1   🔄 BULK ANALYSIS STARTED - %d symbols, Type: %su   📋 SYMBOLS TO ANALYZE: %su,   ⚠️ NO SYMBOLS PROVIDED for bulk analysisa  Provide comprehensive intraday trading analysis for this TOP GAINER. Decide between BUY (intraday long), SELL (intraday short), or HOLD (no trade). Use HOLD only when the setup is clearly low quality (score < 30) or the evidence is very mixed. When the up-move is strong and healthy, prefer BUY; when there are multiple objective reversal/exhaustion signals (e.g. RSI>70 at resistance, bearish patterns, volume/price divergence), prefer SELL.a  Provide comprehensive intraday trading analysis for this TOP LOSER / beaten-down stock. Decide between BUY (intraday long), SELL (intraday short), or HOLD (no trade). Use HOLD only when the setup is clearly low quality (score < 30) or there is no clear edge. When price is deeply oversold near support with improving momentum/accumulation, prefer BUY; reserve SELL for cases where the downtrend remains very strong with fresh breakdowns.zProvide comprehensive intraday trading analysis with a clear decision: BUY (intraday long), SELL (intraday short), or HOLD (no trade). Score the setup 0-100 and avoid HOLD on high-quality setups (score >= 60) unless there is a very specific risk.)r   r   generalr  u   ❓ ANALYSIS QUESTION TYPE: %sr   r   u+   📦 PROCESSING IN BATCHES - Batch size: %dr.   u   📦 BATCH %d/%d: %su"   🎯 ANALYZING %s (%d/%d in batch))r3   r   r   r   r   r   r   r   u   ✅ COMPLETED %s - Decision: %sr   r  u   ❌ FAILED %s: %sr   r   zAnalysis failed: )r   r   r   r   r;   r&   Nu   🏁 BULK ANALYSIS COMPLETEu      ✅ Successful: %du      ❌ Failed: %du      📊 Total Results: %dUNKNOWNu   🎯 DECISION BREAKDOWN: %s)r  r  ri   r  r?   r   range	enumerater  r   rY   rL   r;   r   r   r  r   timesleep)r3   r   r  r  r   r  r   r   	questionsr   resultssuccessful_analysesfailed_analyses
batch_sizeibatch_symbols	batch_numtotal_batches
symbol_idxsymr,   r  r  	decisionsr  r   r   r   r"   bulk_analyze_serviceZ  s   





r  )F)loggingr(  r   typingr   r   r   r   fastapir   app.v1.services.zerodha.clientr   app.v1.services.gpt_enginer	   r
   app.v1.services.tegpt.configr   &app.v1.services.tegpt.zerodha_servicesr   app.v1.utils.snapshot_sanitizer   	getLogger__name__r  r   r   r  r   r  r   r   r   r"   <module>   sj    

	
      W	