o
    ̿Si\\                     @   s  d dl Z d dlZd dlZd dlmZ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mZmZmZ d dlmZ d dlmZ e eZd	ed
efddZ		ddedededede	e ded
eeef fddZ		ddede de	e de	e d
eeeef  f
ddZ!dS )    N)datetime	timedelta)AnyDictListOptional)HTTPException)ZerodhaClient)OPENAI_MODELREQUEST_TIMEOUTget_openai_clientprepare_market_data_promptcall_chatgpt_analysis)fetch_market_data) compact_analysis_for_persistenceexcreturnc                 C   sH   t | pd }|sdS d|v o#d|v p#d|v p#d|v p#d|v p#d|v S )	N Fmodelz	not foundzdoes not existzno such modelmodel_not_foundzunsupported model)strlower)r   msg r   A/var/www/html/Trade-python/app/v1/services/tegpt/chat_services.py_looks_like_model_error   s   r   Tzerodha_clientsymbolmessageuser_idconversation_idinclude_fresh_datac           /         s   zss
t t dd  dt dtt tf f fdd}dtt dtdtfd	d
}p.d	 
 ttdtdd}	td|	}	dtdtt fdddtt tf dtt tf fdd}
dt dtt tf dtt tf dt ffdd}dttt tf  ffdd}dtt tf f fdd}| }t|tr |dnd}|||	}d }d }t|tr|d!nd}t|tr|d"nd}|r|st|g d#d$}d%}|
|}| }zt|d&d'|d(}t|}|d)pi |d*pi |d+pi |d,pi d-|d.< zGd/d0lm} |t |d1p d
 |d2}|durV|d3|j |d4|j |d5|j |d6|j |d7|j |d8|j W n tyf   t d9 Y nw t! d:t"|||d.pwi d;}zd< #|}t |j$}W n ty   t d= Y nw |||}d>d%||t! d?}z	d@ #| W n ty   t dA Y nw d%}W n ty   t dB Y nw t%d@ &dCd%idD'dd(dE}t|t r|	 sdF dG}d>dHdId>|dIg} |dJd D ]&}!|!dK}"|"dLvrq|!d!p$d	 }#|#s,q| )|"|#dI q| )dM|p=d	 dI zt* }$tdNt+}%tdOtdPdQ}&ttdRdSdTt dtt tf ffdUdV}'z|$j,j-j.dn|%| ttdWdXdY|'|%dZt/i}(W nl ty }) z_t |)}*d[|*v rd\|*v rt0d]|% |$j,j-j.|%| ttdWdXtt/d^}(n0|&r|&|%krt1|)rt0d_|%|& |$j,j-j.dn|&| ttdWdXdY|'|&dZt/i}(n W Y d})~)nd})~)ww |(j2d/ j3j4	 }+W n. ty/ }) z!t d` t1|)rdatdNt+ db}+ndc dd}+W Y d})~)nd})~)ww dM|t! de},d@ #|, df|+t|||||	dgt! dh}-d@ #|-}.|+t |.j$|-d 5 tdNt+|-didjW S  ty }) zt dk t6dlt |)dmd})~)ww )oz)Interactive chat about a specific symbol.c                 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)
isinstancer   r   fromisoformatreplace	Exception)vr   r   r   
_as_utc_dt6   s   

z+chat_with_stock_service.<locals>._as_utc_dtsymr   c                    s~   z3d j d| ig dd}|si W S  |dp|d}||dp&i |dp,i |d	d
W S  ty>   i  Y S w )Nstock_analysis_snapshotsr   ))	timestamp
created_atr-   _idr-   sortr,   r/   analysisfeaturessource)r,   r4   r5   r6   )find_onegetr'   )r*   docts)r)   dbr   r   _get_latest_snapshotB   s    z5chat_with_stock_service.<locals>._get_latest_snapshotr:   minutesc                 S   s   | sdS t  |  t|dkS )NF)r=   )r   utcnowr   )r:   r=   r   r   r   	_is_freshU   s   z*chat_with_stock_service.<locals>._is_freshr   CHAT_CONTEXT_REFRESH_MINUTESCHAT_CONTEXT_FRESHNESS_MINUTES5   r(   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infz-inf)r$   boolfloatr'   )r(   fr   r   r   _safe_float_   s   z,chat_with_stock_service.<locals>._safe_floatmdc                 S   s:   i }t | ts	|S dD ]}| |}|d ur|||< q|S )N)
indicators
strategiespivotsfibinstrument_token)r$   dictr8   )rI   outkr(   r   r   r   _compact_market_data_onlyj   s   

z:chat_with_stock_service.<locals>._compact_market_data_onlyr4   
md_compactc                    s<  | dpd}| dpd}| d}| dpd}t| dtr'| dnd }d}t|trZ| d	p:| d
}	| dpF| d}
|	d urZ|
d urZd|	dd|
d}| dpd| d}t| dtrs| dn| d}g }t|tr|D ]}|}|d ur|| t|dkr nqt| dtr| dpi ni  dtdtf fdd}dd |d|d|dfD }d|  d }|d!| d"| 7 }|d urz|d#t|d$d%7 }W n	 ty   Y nw |r|d&| 7 }|d'7 }|r	|d(| d'7 }|d ur|d)|dd'7 }|r*|d*d+	d,d |D  d'7 }|r8|d-d'	| d' 7 }| d.}t|trt| d/trQ| d/nd }t| d0tra| d0nd }|rn|d1| d'7 }|ri }d2D ]}t| |tr| |r| |||< qu|r|d3| d'7 }|
 S )4NdecisionHOLD
confidenceLOWdecision_probabilitytrend_labelr   
entry_zonelowr   highupperzentry_zone=.2f-exec_sl	stop_lossexec_targetstargets   rJ   tfr   c                    s   t tr
| nd }t |tsdS  |d} |d} |d} |d}g }|d ur>|d|d |d urK|d|d |d urX|d	|d
 |d ure|d|d |rrd|  dd| S dS )Nr   rsivwapclose	macd_histzclose=r^   zvwap=zrsi=z.1fz
macd_hist=z.3f- z: , )r$   rO   r8   appendjoin)re   srf   rg   rh   ri   parts)rH   indsr   r   _tf_line   s"   
zMchat_with_stock_service.<locals>._summarize_compact_context.<locals>._tf_linec                 S   s   g | ]}|r|qS r   r   .0xr   r   r   
<listcomp>       zOchat_with_stock_service.<locals>._summarize_compact_context.<locals>.<listcomp>5minute15minuteday	CONTEXT (z)
z- decision=z confidence=z decision_probability=z.0f%z trend_label=
rj   z
- exec_sl=z- exec_targets=rk   c                 S   s   g | ]}|d qS )r^   r   rr   r   r   r   ru      rv   zINDICATORS:
rK   multi_timeframeper_timeframezMTF: rw   rx   ry   zSTRATEGY_FLAGS: )r8   r$   rO   listrl   lenr   rF   r'   rm   strip)r*   r4   rS   decconfprobrY   zoneztxtlohisltrc   rt   fxrq   tf_linespstmtperslimrQ   )rH   )rp   r   _summarize_compact_contextt   sz   

$

  
 
  z;chat_with_stock_service.<locals>._summarize_compact_contextc                      s8   zd j  ddddgdW S  ty   Y d S w )NchatsTr   r   r    is_context_snapshotr.   r0   r2   )r7   r'   r   )r    r;   r   r   r   r   _get_latest_context_doc   s   	z8chat_with_stock_service.<locals>._get_latest_context_docc               	      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 ),Nmarket_intelligence_summarytypelatest))
updated_atr-   )captured_atr-   r0   r2   payloadr   r   r/   r(   r   c                 S   sL   t | pd  }g }|D ]}|| r|nd qdd| S )Nr    )r   r   r]   rl   isalnumrm   split)r(   rn   	out_charschr   r   r   	_norm_key   s
   zSchat_with_stock_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   )rs   r   kkr   r   	<genexpr>   s    zochat_with_stock_service.<locals>._get_latest_market_intelligence.<locals>._best_sector_match.<locals>.<genexpr>rC   )r$   rO   setr   keysr   any)	r   r   targettarget_tokensbest
best_scorerQ   	kk_tokensoverlapr   r   r   _best_sector_match   s*   z\chat_with_stock_service.<locals>._get_latest_market_intelligence.<locals>._best_sector_matchr"   as_ofmarket_biasoverall_riskrisk_regimevolatility_statevolatility_regimesector_strengthstocksr   r   rC   )r1   r   sectorindustrynamer   r   r   symbol_sectorsymbol_industrydiagnosticssectors
volatilityclassretstate)indexr   r   r   symbol_sector_trend)r7   r8   r   r   r   r   	isoformatr$   rO   r'   r   )r9   r   r:   r   rP   stock
sector_valindustry_valr   	match_keydiagvol)r)   r;   r   r   r   _get_latest_market_intelligence   sl   "&   
z@chat_with_stock_service.<locals>._get_latest_market_intelligencer/   NFr   context_snapshot_idr   )r;   Tzgeneral intraday analysisgeneral)questioncontextmarket_intelligencerJ   rK   rL   rM   )rJ   rK   rL   rM   r5   r   )build_execution_planrT   )rT   market_datarZ   entry_trigger_reasonr`   rb   exec_rr_ratiosignal_statez'[Chat] Failed to compute execution planCHAT)r   r,   r6   r4   r   r5   r+   z&[Chat] Failed to persist chat snapshotsystem)r   r   r    roler   r   r   r/   r   z/[Chat] Failed to store context snapshot messagez)[Chat] Failed to refresh analysis contextz$ner      rz   z-)
- No fresh computed snapshot available yet.zYou are an expert intraday trader and coach. Be concise and practical. Use Markdown bullets. Do NOT invent prices/indicators; use only provided context.)r   contentir   )user	assistantr   OPENAI_CHAT_MODELOPENAI_CHAT_MODEL_FALLBACKOPENAI_MODEL_FALLBACKzgpt-4o-miniOPENAI_CHAT_MAX_TOKENS800
model_namec                    s.   | pd   drdt iS dt iS )Nr   zgpt-5max_completion_tokens
max_tokens)r   r   
startswithint)r   )chat_max_tokensr   r   _max_tok_kwargs_for  s   z4chat_with_stock_service.<locals>._max_tok_kwargs_forOPENAI_CHAT_TEMPERATUREz0.2)r   messagestemperaturetimeoutr   r   zXRetrying chat completion with max_completion_tokens due to parameter mismatch (model=%s))r   r   r   r   r   z7Chat model failed (%s). Retrying with fallback model=%szChatGPT call failed in chatzxChat is unavailable because the configured model is invalid or not accessible. Please check OPENAI_CHAT_MODEL (current: z).zI'm having trouble analyzing z) right now. Please try again in a moment.)r   r   r    r   r   r/   r   )computed_snapshot_refreshedr   zerodha_usedrefresh_minutes)r   r   r    r   r   market_data_includedr   r/   r   )r    r   
message_idr,   r   r   zChat service failed for %s  status_codedetailr   )7r   uuiduuid4r   r   r   r   r   rE   r   r]   osgetenvmaxrF   r$   rO   r8   r   r   r   app.v1.services.entry_enginer   
setdefaultrZ   r   r   rc   rr_ratior   r'   logger	exceptionr>   r   
insert_oneinserted_idr   findr3   limitrl   r   r
   chatcompletionscreater   warningr   choicesr   r   r   r   )/r;   r   r   r   r   r    r!   r<   r?   r   rR   r   r   r   ctx_docctx_ts	ctx_freshused_zerodha	refreshedcontext_summaryr   md_rawrS   r   promptr4   r   plansnapshot_docins	ctx_storehistoryr   r	  r   txtclient
chat_modelchat_model_fallbackr   responseer   assistant_messageuser_chat_docassistant_chat_docresultr   )r)   rH   r   r    r;   r   r   r   chat_with_stock_service'   s   
".
$RW

 
	










	r%  r  rT   c                 C   s4  zd|i}|r|  |d< |r|  |d< t| d |dd|}g }|D ]T}|di }	t|d |d |	d	d
|	dd|	dpId|	d|	dpSg |	d|	dp]g |	d|	dg |	di |d  |ddd}
||
 q)|W S  t	y } zt
d tdt|dd}~ww )z"Get user's latest trading signals.r   r   zanalysis.decisionanalysesr,   r-   r4   r1   rT   rU   rV   rW   r   WAITING_FOR_ENTRYrZ   r   r`   rb   r   	rationaletechnical_indicatorsr   r   )idr   rT   rV   r   rZ   r   r   rc   r  r(  r)  r,   r   zFailed to get user signalsr   r   N)r]   r   r  r3   r  r8   r   r   rl   r'   r  r  r   )r;   r   r  r   rT   querysignalsformatted_signalssignalr4   formatted_signalr   r   r   r   get_user_signals_service  s@   	 







r0  )NT)NN)"loggingr   r   r   r   typingr   r   r   r   fastapir   app.v1.services.zerodha.clientr	   app.v1.services.gpt_enginer
   r   r   r   r   &app.v1.services.tegpt.zerodha_servicesr   app.v1.utils.snapshot_sanitizer   	getLogger__name__r  r'   rE   r   r   r%  r   r0  r   r   r   r   <module>   sZ    


   h