
    VOj+                    @   d dl m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
 d dlmZ h dZh d	Zh d
Zh dZ ed           G d d                      Zd<dZd=d>dZd?d@dZdAdBd#Zdd$dCd%Z e
d&          fdd$dDd*Zd+d,d-dEd4Zd+d,d-dFd5ZdGd:ZdHd;ZdS )I    )annotationsN)	dataclass)datetimetimezone)Decimal)Path)Any>   mixedbearishbullishneutralunknown>   r
   alignedr   conflict>   weaknormalr   breakout>   	high-riskr   squeezer   	expandingT)frozenc                      e Zd ZU ded<   ded<   dZded<   dZded<    ed          Zd	ed
<   dZded<   dZ	ded<   dZ
ded<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded<   edd            ZdS )TradingViewContextstrcoinsymbolBINANCEexchanger   bias0r   
confidencetrend_alignmentvolume_statevolatility_state ztuple[str, ...]no_trade_reasonsNDecimal | Nonenearest_supportnearest_resistance
int | Nonesource_age_secondsTboolresearch_onlytradingview_mcpsourcereturnc                *    | j         d u p
| j         dk    S )N  )r+   )selfs    #src/research/tradingview_context.pystalezTradingViewContext.stale!   s    &$.P$2ID2PP    )r0   r,   )__name__
__module____qualname____annotations__r   r   r   r!   r"   r#   r$   r&   r(   r)   r+   r-   r/   propertyr5   r%   r6   r4   r   r      s$        IIIKKKHD!'#,,J&&&&$O$$$$!L!!!!%%%%%(*****&*O****)-----%)))))M#F####Q Q Q XQ Q Qr6   r   valuer	   r0   r'   c                r    | | dk    rd S 	 t          t          |                     S # t          $ r Y d S w xY w)N )r   r   	Exception)r<   s    r4   _decimal_or_noner@   &   sO    }ts5zz"""   tts   ( 
66r    defaultr   r   c                F    t          |           }||nt          |          S N)r@   r   )r<   rA   parseds      r4   _decimalrE   /   s&    e$$F'66WW-=-==r6   r   allowedset[str]c                |    t          | p|                                                                          }||v r|n|S rC   )r   striplower)r<   rF   rA   vals       r4   _clean_choicerL   4   s>    
ew


%
%
'
'
-
-
/
/C..33g-r6   rowdict[str, Any]nowdatetime | Noner*   c           	     B   |pt          j        t          j                  }|                     d          p)|                     d          p|                     d          }|sd S 	 t          j        t          |                              dd                    }|j         |                    t          j                  }t          dt          ||                    t          j                  z
                                                      S # t          $ r Y d S w xY w)Nts	timestamp
created_atZz+00:00)tzinfor   )r   rO   r   utcgetfromisoformatr   replacerV   maxint
astimezonetotal_secondsr?   )rM   rO   rawstamps       r4   _age_secondsra   9   s    

+hl++C
''$--
H377;//
H377<3H3HC t&s3xx'7'7X'F'FGG<MMM66E1c3!1!1(,!?!??NNPPQQRRR   tts   %B*D 
DDrO   c               t   t          |                     d          p+|                     d          p|                     d          pd                                                              dd                              dd          }t          |                     d          p| d                                          }|                     d          }t	          |t
                    r|ni }|                     d          }t	          |t                    r|ng }t          ||t          |                     d	          pd
                                          t          |                     d          t                    t          t          d          t          t          d          t          |                     d                                        t          |                     d          t                    t          |                     d          t                    t          |                     d          t                     t#          d |D                       t%          |                    d          p|                     d                    t%          |                    d          p|                     d                    t'          | |          t)          |                     dd                    du t          |                     d          pd          dk    rdnd          S )zWhitelist and normalize a TradingView MCP research row.

    Free text, tool prose, and non-whitelisted fields are intentionally ignored.
    r   baser   r>   USDTz
/USDC:USDCsupport_resistancer&   r   r   r   r    1r!   r"   r#   r$   c              3  n   K   | ]0}t          |t                    t          |          d d         V  1d S )NP   )
isinstancer   .0xs     r4   	<genexpr>z0normalize_tradingview_context.<locals>.<genexpr>[   s?      RRqz!S?Q?QRs1vvcrc{RRRRRRr6   r(   r)   rb   r-   Tr/   r.   r   )r   r   r   r   r!   r"   r#   r$   r&   r(   r)   r+   r-   r/   )r   rX   upperrZ   rj   dictlistr   rL   _ALLOWED_BIASr[   r   minrE   _ALLOWED_TREND_ALLOWED_VOLUME_ALLOWED_VOLATILITYtupler@   ra   r,   )rM   rO   r   r   
levels_rawlevelsreasons_rawreasonss           r4   normalize_tradingview_contextr|   G   s   
 swwvL#''&//LSWWX5F5FL"MMSSUU]]^dfhiiqqr~  AC  D  DD""3mmm44::<<F-..J+5j$+G+GOZZRF'',--K(2;(E(EM2GSWWZ((5I66<<>>3776??M::ws||Sx@U@U7V7V%W%WXX%cgg.?&@&@.QQ"377>#:#:OLL&sww/A'B'BDWXXRRGRRRRR(4E)F)F)d#''RcJdJdee+FJJ7K,L,L,mPSPWPWXlPmPmnn'555377?D99::dB$'(9(9(N=N$O$OSd$d$d  js   r6   z(runtime/research/tradingview_latest.jsonpath
Path | strdict[str, TradingViewContext]c                  t          |           } |                                 si S 	 t          j        |                     d                    }n# t          j        t          f$ r i cY S w xY wt          |t                    r;t          |	                    d          t                    rd |d         D             }n$t          |t                    rd |D             }ng }i }|D ]$}t          ||          }|j        r
|||j        <   %|S )Nzutf-8)encodingcoinsc                <    g | ]}t          |t                    |S r%   rj   rp   rk   s     r4   
<listcomp>z+load_tradingview_latest.<locals>.<listcomp>n   s'    ???a:a+>+>????r6   c                <    g | ]}t          |t                    |S r%   r   rk   s     r4   r   z+load_tradingview_latest.<locals>.<listcomp>p   s'    666a*Q"5"56666r6   rb   )r   existsjsonloads	read_textJSONDecodeErrorOSErrorrj   rp   rX   rq   r|   r   )r}   rO   r_   rowsoutrM   ctxs          r4   load_tradingview_latestr   d   s)   ::D;;== 	j99:: '*   			 #t CGGG,<,<d!C!C ??3w<???	C		 663666)+C    +CS9998 	 CMJs   (A A+*A+longr2   sidemax_age_secondsr   TradingViewContext | Noner   r   r\   	list[str]c                  | g S g }| j         s|                    d           | j        dk    r|                    d           | j        | j        |k    r|                    d           |                                }|dk    ra| j        dk    r|                    d           | j        dk    r|                    d	           | j        d
k    r|                    d           nF|dk    r@| j        dk    r|                    d           | j        dk    r|                    d	           |                    d | j	        d d         D                        t          t                              |                    S )Ntv_context_not_research_onlyr.   tv_context_untrusted_sourcetv_context_staler   r   tv_bias_bearishr   tv_mtf_conflictr   tv_volume_not_confirmedshortr   tv_bias_bullishc              3      K   | ]	}d | V  
dS )tv_no_trade_Nr%   )rl   reasons     r4   rn   z'tradingview_blockers.<locals>.<genexpr>   s+      SS+6++SSSSSSr6      )r-   appendr/   r+   rJ   r   r"   r#   extendr&   rq   rp   fromkeys)r   r   r   blockerss       r4   tradingview_blockersr   {   s   
{	H 86777
z&&&5666
%)?/)Q)Q*+++::<<Dv~~8y  OO-...*,,OO-...v%%OO5666	8y  OO-...*,,OO-...OOSS#:NrPQr:RSSSSSSh''(((r6   c                  | ddddgddddS t          | ||          }g }|r5|                                d	k    rd
nd}d}|                    |           n%|                                d	k    r| j        dk    r| j        dk    r| j        t          d          k    rm| j        dv rd| j        dv r[d}d}|	                    d           | j        dk    r|	                    d           | j        dk    r|	                    d           nr|                                d	k    r<| j        dv r3| j        t          d          k    rd}d}|	                    d           n|                                dk    r| j        dk    r| j        dk    r| j        t          d          k    rl| j        dv rc| j        dv rZd }d}|	                    d!           | j        dk    r|	                    d           | j        dk    r|	                    d           nl|                                dk    r;| j        d"v r2| j        t          d          k    rd#}d}|	                    d$           nd%}d&}|	                    d'           d(||t          t                              |                    | j        t          | j                  | j        | j        | j        | j        | j        | j        ddd)S )*a  Classify TradingView MCP context into deterministic paper-decision categories.

    MCP rows stay research-only.  This category lets scorecards measure whether a
    bullish/bearish TradingView impulse helped, blocked, or only provided context;
    it never grants live permission.
    NFmissing_contextignoretv_context_missingr    )	availablecategoryactionr{   r!   live_order_allowedmainnet_signed_actionr   r   
avoid_longavoid_shortblock_or_demoter   r   z0.70>   r   r   >   r   r   r   buy_opportunity#paper_candidate_if_other_gates_passtv_bullish_aligned_confidentr   tv_volume_breakoutr   tv_squeeze_watch>   r
   r   z0.55
watch_long
watch_only!tv_constructive_but_not_confirmedr   r   sell_opportunitytv_bearish_aligned_confident>   r
   r   watch_shorttv_bearish_but_not_confirmedneutral_contextcontext_onlytv_no_actionable_impulseT)r   r   r   r{   r   r!   r"   r#   r$   r-   r/   r+   r   r   )r   rJ   r   r   r"   r!   r   r#   r$   r   rq   rp   r   r   r-   r/   r+   )r   r   r   r   r{   r   r   s          r4   classify_tradingview_impulser      s    {),-"'%*
 
 	
 $CdOTTTHG 3#'::<<6#9#9<<}"x    			CH	$9$9c>QU^>^>^cfcqu|  ~D  vE  vE  dE  dE  JM  JZ  ^t  Jt  Jt  y|  yM  Qs  ys  ys$65666z))NN/0009,,NN-...			CH0D$D$D[bci[j[jIjIj:;;;;		 	 SX%:%:s?RV_?_?_dgdrv}  E  wF  wF  eF  eF  KN  K[  _u  Ku  Ku  z}  zN  Rt  zt  zt%65666z))NN/0009,,NN-...		 	 SX1E%E%E#.\cdj\k\kJkJk 56666$1222g..//#.)).(0**!4#!&  r6   candidate_coinspaper_pnl_by_coindict[str, float]tv_contextsc                d    d
fdd t          fd| D             d	          D             S )zRank coins by measured evidence first, then TV context quality.

    This is intentionally conservative: prior paper/shadow evidence dominates, TV
    context can only break ties or demote conflicted/stale markets.
    r   r   r0   tuple[Decimal, str]c                   |                                  }t          t                              |d                              }                    |          }|rtt	          |d          s+|t          d          |j        t          d          z  z   z  }n8dt	          |d          v r|t          d          z  }n|t          d          z  }||fS )	Ng        r   )r   z0.254r   z0.10z0.50)ro   r   r   rX   r   r!   )r   csr   r   r   s       r4   scorez#rank_tradeable_coins.<locals>.score   s    JJLLC)--a556677ooa   	%'&999 %WV__s~'DDD#';Cf'M'M'MMMWV__$WV__$1vr6   c                    g | ]\  }}|S r%   r%   )rl   _r   s      r4   r   z(rank_tradeable_coins.<locals>.<listcomp>   s    ZZZWQDZZZr6   c              3  .   K   | ]} |          V  d S rC   r%   )rl   r   r   s     r4   rn   z'rank_tradeable_coins.<locals>.<genexpr>   s+      'J'JQa'J'J'J'J'J'Jr6   T)reverse)r   r   r0   r   )sorted)r   r   r   r   s    ``@r4   rank_tradeable_coinsr      sb           [Z'J'J'J'J/'J'J'JTX Y Y YZZZZr6   c                   | ddddS i ddd| j         d| j        d| j        d	| j        d
t	          | j                  d| j        d| j        d| j        dt          | j
                  d| j        t	          | j                  nd d| j        t	          | j                  nd d| j        d| j        d| j        ddddS )NFnoneT)r   r/   r-   r   r   r   r   r   r!   r"   r#   r$   r&   r(   r)   r+   r-   r/   r   r   )r   r   r   r   r   r!   r"   r#   r$   rq   r&   r(   r)   r+   r-   r/   )r   s    r4   context_to_journal_dictr      sI   
{"ftLLLT 	#* 	CL	
 	 	c#.)) 	3. 	( 	C0 	D!566 	s7J7V3s2333\` 	S=S=_c#"8999ei 	c4 	* 	#*  	e!" 	 # r6   )r<   r	   r0   r'   )r    )r<   r	   rA   r   r0   r   )r   )r<   r	   rF   rG   rA   r   r0   r   rC   )rM   rN   rO   rP   r0   r*   )rM   rN   rO   rP   r0   r   )r}   r~   rO   rP   r0   r   )r   r   r   r   r   r\   r0   r   )r   r   r   r   r   r\   r0   rN   )r   r   r   r   r   r   r0   r   )r   r   r0   rN   )
__future__r   r   dataclassesr   r   r   decimalr   pathlibr   typingr	   rr   rt   ru   rv   r   r@   rE   rL   ra   r|   r   r   r   r   r   r%   r6   r4   <module>r      s>   " " " " " "  ! ! ! ! ! ! ' ' ' ' ' ' ' '                  EEE<<<;;;PPP  $Q Q Q Q Q Q Q Q*   > > > > >
. . . . .
     RV      : 04t4^/_/_ {      . IOgk ) ) ) ) ) )6 QWos B B B B B BJ[ [ [ [*     r6   