o
    HiV*                     @   s`  d dl mZmZmZmZmZ d dlmZmZm	Z	 d dl
m
Z
 d dlZd dlmZ d dl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mZmZmZ e ZeeZ e !ej" eej#eefd
efddZ$ej%dddeej#eefddZ&ej'dddeej#fddZ(ej'dddeej#ee$fde)defddZ*ej'dddeej#fde)de)fdd Z+ej%d!d"ded#eej#ee$eefde)d$ee)ef defd%d&Z,ej%d'd(ded#eej#ee$eefd$ee)ef defd)d*Z-e%d+eej#eefd$e.fd,d-Z/e%d.d$e.fd/d0Z0e'd1eej#eefd2d3Z1ej%d4d5ded#fd$ee)ef fd6d0Z0ej%d7d8ded#eej#fd9e)d$ee)ef fd:d;Z2ej'd<d=dd>d? Z3ej%d@dAdedBdCifd$ee)ef fdDdEZ4ej'dFdGdedHdIdJedKdLdJeej#eeee$fdMe)dNe5defdOdPZ6dS )Q    )	APIRouterDependsHTTPExceptionBodyQuery)DictAnyOptional)datetimeN)ObjectId)database)get_current_userdetails)ZerodhaClient)refresh_movers_serviceget_top10_servicecreate_snapshot_serviceget_snapshot_servicechat_symbol_serviceplace_short_order_servicekite_postback_serviceget_live_signals_servicereturnc                 C   sN   t |d}| d d|i}|stdddt|d |d |d	d
dS )zv
    Build Zerodha client for the current user from DB settings.
    Throws HTTPException(404) if not configured.
    _idzerodha_settingsuser_id  z#Zerodha settings not found for userstatus_codedetailapi_key
api_secretaccess_token )r   r    r!   )strgetfind_oner   r   )dbcurrent_userr   settings r)   ;/var/www/html/Trade-python/app/v1/routers/tradeengineGPT.pyget_zerodha_client_from_db   s   
r+   z/movers/refreshz7Refresh movers aggregator (poll sources, merge, dedupe))summaryc              
   C   sV   z
t | }d|dW S  ty     ty* } ztd tdt|dd }~ww )Nokstatusresultzrefresh_movers failed  r   )r   r   	Exceptionlogger	exceptionr#   )r&   r'   r0   er)   r)   r*   refresh_movers1      
r6   z/movers/top10zReturn Top10 movers (cached)c              
   C   V   z
t | }d|dW S  ty     ty* } ztd tdt|dd }~ww )Nr-   )r/   top10zget_top10 failedr1   r   )r   r   r2   r3   r4   r#   )r&   topr5   r)   r)   r*   r9   =   r7   r9   z/symbol/{symbol}/snapshotz-Create and return fresh snapshot for a symbolsymbolzerodhac              
   C   sh   zt ||| }dt|d |d dW S  ty     ty3 } ztd tdt|dd }~ww )Nr-   r   snapshot)r/   snapshot_idr=   zcreate_snapshot failedr1   r   )r   r#   r   r2   r3   r4   )r;   r&   r<   docr5   r)   r)   r*   create_snapshotJ   s   
r@   z'/symbol/{symbol}/snapshot/{snapshot_id}zGet existing snapshot by idr>   c              
   C   sh   zt ||}|stdddd|dW S  ty     ty3 } ztd tdt|dd }~ww )Nr   zSnapshot not foundr   r-   )r/   r=   zget_snapshot failedr1   )r   r   r2   r3   r4   r#   )r;   r>   r&   r?   r5   r)   r)   r*   get_snapshotZ   s   

rA   z/symbol/{symbol}/chatz0Ask LLM about a symbol using snapshot + question.payloadc              
   C   sb   z|}t |||| |}d|dW S  ty     ty0 } ztd tdt|dd}~ww )zt
    payload: { "question": str, "snapshot_id": Optional[str] }
    Returns: { status: ok, response: LLM_JSON }
    r-   )r/   responsezsymbol_chat failedr1   r   N)r   r   r2   r3   r4   r#   )r;   rB   r&   r<   r'   userrespr5   r)   r)   r*   symbol_chati   s   
rF   z/orders/shortz>Place manual short order (requires explicit user_confirmation)c              
   C   s`   z|}t |||| }d|dW S  ty     ty/ } ztd tdt|dd}~ww )z\
    payload: { symbol, quantity, price(optional), order_type, user_confirmation:true }
    r-   )r/   placedzplace_short_order failedr1   r   N)r   r   r2   r3   r4   r#   )rB   r&   r<   r'   rD   r0   r5   r)   r)   r*   place_short_order   s   

rH   z	/callbackc                 C   s   |  d}t| d}|stddd|d d|i}|s%tdd	dt|d
 |d }||}|d d|idd|d ii ddiS )Nrequest_tokenr     zMissing request tokenr   r   r   r   zZerodha settings not foundr   r    $setr!   r/   	connected)r$   r#   r   r%   r   generate_session
update_one)rB   r&   r'   rI   r   r(   clientsessionr)   r)   r*   post_callback   s   

rQ   z	/postbackc              
      sT   zt d|  t d |  ddiW S  ty) } ztdt|dd }~ww )NzZerodha postback received: %szerodha_postbacksr/   receivedr1   r   )logginginfor   get_mongo_db
insert_oner2   r   r#   )rB   r5   r)   r)   r*   kite_postback   s   
rX   z/profilec                 C   s|   | d  dt|d i}|r|dstdddt|d |d	 |d }z
| }d
|dW S  ty=   tdddw )Nr   r   r   r!   i  zNot authenticated with Zerodhar   r   r    r-   )r/   profilez$Invalid/expired Zerodha access token)r%   r#   r$   r   r   get_profiler2   )r&   r'   r(   rO   rY   r)   r)   r*   get_zerodha_profile   s   r[   z/webhook/kite/postbackz-Kite Connect postback handler (order updates)c              
   C   r8   )NrS   r.   zkite_postback failedr1   r   )r   r   r2   r3   r4   r#   )rB   resr5   r)   r)   r*   rX      r7   z/stream/feedback/{id}z Stream feedback (thumbs up/down)idc              
   C   s   | d}|dvrtdddz4z|d dt| idd	|ii W n ty9   |d d| idd	|ii Y nw W ddiS W ddiS  ty\ } ztd
 tdt|dd }~ww )Nfeedback)updownrJ   zfeedback must be 'up' or 'down'r   streamr   rK   user_feedbackzfeedback update failedr1   r/   r-   )r$   r   rN   r   r2   r3   r4   r#   )r]   rB   r&   fbr5   r)   r)   r*   stream_feedback   s$   
$ 
rd   z/healthzHealth checkc                  C   s&   ddl m}  |  }dt  |dS )Nr   )validate_openai_configr-   )r/   timeopenai_configured)app.v1.services.tradeGPTre   r
   utcnow	isoformat)re   openai_statusr)   r)   r*   health   s   
rl   z	/test/llmzTest ChatGPT integrationquestionzIs this working?c              
   C   sP   ddl m} dddidddd	d
dddgid}| dd}|||}d|dS )z+Test endpoint to verify ChatGPT integrationr   )call_chatgpt_analyze_serviceTEST
last_priceg      Y@5minutez
2023-01-01c   e   b   d   i  )tohlcv)r;   quotecandlesrm   zAnalyze this test datar-   )r/   llm_response)rh   rn   r$   )rB   rn   mock_snapshotrm   r0   r)   r)   r*   test_llm   s   

r   z/livez=(compat) Live enriched signals - fallback for legacy frontendgainersz,Which top movers to run on: gainers | losers)description2   zMax symbols to scanmoverlimitc           	   
   C   s   z&t |d}t||| ||d}t|tr|dg ng }dt||dW S  ty.     tyF } zt	d tdt |dd	}~ww )
z
    Backwards-compatible endpoint returning rich strategy results.
    Delegates to get_live_signals_service in services (implement there).
    r   )r&   r<   r   r   r   resultssuccess)r/   scannedr   ztrade_live failedr1   r   N)
r#   r$   r   
isinstancedictlenr   r2   r3   r4   )	r   r   r&   r'   r<   r   rE   r   r5   r)   r)   r*   
trade_live  s   
r   )7fastapir   r   r   r   r   typingr   r   r	   r
   rT   bsonr   app.dbr   app.v1.dependencies.authr   app.v1.services.zerodha.clientr   rh   r   r   r   r   r   r   r   r   router	getLogger__name__r3   setLevelINFOrV   r+   postr6   r$   r9   r#   r@   rA   rF   rH   r   rQ   rX   r[   rd   rl   r   intr   r)   r)   r)   r*   <module>   s   (




 ,
	$

