
    D\j/                       d dl mZ d dlZd dlZd dlZd dlZ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 d dlmZ d dlmZ d dlmZ dZd	d
ddddZdddZd dD             Zd<d=dZd>dZddd?d"Zddd@d#Z ed$%           G d& d'                      Z ee          fdAd*ZdBdCd-Z  ee          fd.d/dDd2Z!dEd3Z"d4d5dFd9Z#dd:dGd;Z$dS )H    )annotationsN)asdict	dataclass)datetimetimezone)Decimal)Path)Anyzexternal_market_context.v1bitcoinethereumsolana	chainlinkhyperliquid)BTCETHSOLLINKHYPEEthereumSolana)r   r   c                    i | ]}|| d 	S )USDT .0coins     'src/research/external_market_context.py
<dictcomp>r      s     QQQ44DQQQ    )r   r   r   r   0valuer
   defaultstrreturnr   c                z    	 t          t          |                     S # t          $ r t          |          cY S w xY wN)r   r#   	Exception)r!   r"   s     r   _dr(      sJ     s5zz"""      w s    ::c                 b    t          j        t          j                                                  S r&   )r   nowr   utc	isoformatr   r   r   _nowr-      s     <%%//111r      timeouturlr0   intc                   t           j                            | ddd          }t           j                            ||          5 }t	          j        |          cd d d            S # 1 swxY w Y   d S )NCryptoAgentResearch/1.0zapplication/jsonz
User-AgentAcceptheadersr/   )urllibrequestRequesturlopenjsonloadr1   r0   r:   responses       r   	_get_jsonrA   !   s    n$$SAZfx2y2y$zzG					9	9 #Xy""# # # # # # # # # # # # # # # # # #s   A''A+.A+c                  t           j                            | ddd          }t           j                            ||          5 }|                                                    d          cd d d            S # 1 swxY w Y   d S )Nr4   ztext/csvr5   r7   r/   utf-8)r9   r:   r;   r<   readdecoder?   s       r   	_get_textrF   '   s    n$$SAZfp2q2q$rrG					9	9 /X}}%%g../ / / / / / / / / / / / / / / / / /s   'A::A>A>T)frozenc                      e Zd ZU ded<   ded<   ded<   ded<   ded<   ded	<   d
Zded<   eZded<   dZded<   dZded<   dZ	ded<   ddZ
dS )SourceEnveloper#   	source_idobserved_atstatusreliabilityboolresearch_onlydict[str, Any]datar   tuple[str, ...]blockerssource_version  r2   max_age_secondsg      ?floatreliability_scoreNz
str | Noneprovider_observed_atr$   c                d   t          |           }t          | j                  |d<   | j        |d<   d|d<   d|d<   t	          j        | j        | j        | j        | j	        dddt          	                              d
          }dt          j        |                                          z   |d<   |S )NrS   collected_atr   age_secondsTfresh)rJ   rT   rY   rQ   ),:)	sort_keys
separatorsr"   rC   zsha256:snapshot_id)r   listrS   rK   r=   dumpsrJ   rT   rY   rQ   r#   encodehashlibsha256	hexdigest)selfpayloadfingerprints      r   to_dictzSourceEnvelope.to_dict;   s    ,,"4=11
"&"2!"jt~QUQd  C  X  bf  bk  "l  "l  x|  IS  ]`  a  a  a  h  h  ip  q  q!*W^K-H-H-R-R-T-T!Tr   )r$   rP   )__name__
__module____qualname____annotations__rS   SOURCE_VERSIONrT   rV   rX   rY   rl   r   r   r   rI   rI   -   s         NNNKKK "H""""(N((((O"""""'+++++     r   rI   coinsrR   c                   d | D             }t           j                            dd                    |          dd          }t	          d|           }d |D             }i }g }| D ]-}|                    t                              |d                    }|s|                    d	|            Lt          t          |                    d
                              t          |                    d          pd          t          t          |                    d                              t          t          |                    d                              t          t          |                    d                              d||<   /d |D             }	t          dt                      t          |          t          |          k    rdn|rdnddd|t          |          dd|	rt          |	          nd 
  
        S )Nc                :    g | ]}|t           v t           |         S r   )COINGECKO_IDSr   s     r   
<listcomp>z%collect_coingecko.<locals>.<listcomp>G   s'    
J
J
J4DM4I4I=4I4I4Ir   usdr^   24h)vs_currencyidsprice_change_percentagez/https://api.coingecko.com/api/v3/coins/markets?c                ~    i | ]:}t          |t                    t          |                    d                     |;S )id
isinstancedictr#   getr   rows     r   r   z%collect_coingecko.<locals>.<dictcomp>J   s;    NNN
38M8MNSNNNr    zcoingecko_missing:
market_capmarket_cap_rankr   total_volumeprice_change_percentage_24hcirculating_supply)market_cap_usdr   total_volume_usdprice_change_24h_pctr   c                    g | ]N}t          |t                    |                    d           ,t          |                    d                     OS )last_updated)r   r   r   r#   r   s     r   rv   z%collect_coingecko.<locals>.<listcomp>Y   sR    xxxsjQTVZF[F[x`c`g`ghv`w`wxc#''.1122xxxr   zcoingecko:coins_markets:v3okpartialdegradedmediumTi  皙?)rV   rX   rY   )r9   parse	urlencodejoinrA   r   ru   appendr#   r(   r2   rI   r-   lentuplemin)
rr   rz   queryrowsby_idrQ   rS   r   r   provider_timess
             r   collect_coingeckor   F   s[   
J
J5
J
J
JCL""5#kp#q#qrrENuNNOODNNNNNEDH 
 
ii))$3344 	OO777888!"SWW\%:%:";";<<"377+<#=#=#BCC #Bsww~'>'>$?$? @ @$'3773P+Q+Q(R(R$S$S"%b1E)F)F&G&G"H"H
 
T

 yxdxxxN6D		UXY\U]U]H]H]pt  dEclcl  {E  GO  QU  W[  ]b  ck  ]l  ]l  ~B  VZ  HV  q`  qt  uC  qD  qD  qD  \`  a  a  a  ar   previousdict[str, Any] | Nonec                   t          d          }d |D             }t          | t                    r| pi                     d          pi ni }i }g }t                                          D ]\  }}|                    |          }|s|                    d|            5t          |                    d                    }	t          |                    |          pi                     d                    }
|
dk    r%|	|
z  t          d          z
  t          d	          z  nt          d
          }|t          |	          t          |          d||<   t          dt                      |rdnddd|t          |          dd	  	        S )Nzhttps://api.llama.fi/v2/chainsc                ~    i | ]:}t          |t                    t          |                    d                     |;S )namer~   r   s     r   r   z%collect_defillama.<locals>.<dictcomp>_   s;    RRRSJsD<Q<QRs3776??##SRRRr   rQ   zdefillama_chain_missing:tvltvl_usdr   1100r    )chainr   tvl_change_since_previous_pctzdefillama:v2_chains:v1r   r   r   Ti`T  g      ?rV   rX   )rA   r   r   r   DEFILLAMA_CHAINSitemsr   r(   r   r#   rI   r-   r   )r   r   by_nameprevious_datarQ   rS   r   r   r   r   priorchanges               r   collect_defillamar   ]   s   566DRRDRRRG<FxQU<V<V^hn"))&117R\^MDH'--// i iekk%   	OO>u>>???  M%%d++1r66yAABBDIAII3;'#,,.'%..@@SZ[^S_S_$S\_`f\g\ghhT

2DFFD<XDDjZbdhjnpuv~pp  RW  ko  p  p  p  pr   z1runtime/research/binance_liquidations_latest.json)liquidation_pathr   
str | Pathc                  i }g }i }d}	 t          j        t          |                              d                    }t	          j        t          |                    d                                        dd                    }t          dt          j
                    |                                z
            }|                    d          d	k    r |d
k    r|                    d          pi }d}n|                    d           n%# t          $ r |                    d           Y nw xY w| D ]}	t                              |	          }
|
s 	 t          d|
           }t          d|
           }t          d|
 d          }t!          |t"                    r
|r|d         ni }|                    |	          pi }t          t%          |                    d                              t          t%          |                    d                              t          t%          |                    d                              t          t%          |                    d                              t          t%          |                    d                              t          t%          |                    d                    t'          d          z            t          t%          |                    d                    t'          d          z            |r/t          t%          |                    d                              nd |r/t          t%          |                    d                              nd |r/t          t%          |                    d                              nd |r$t)          |                    d          pd          nd d ||	<   # t          $ r8}|                    d!|	 d"t+          |          j                    Y d }~d }~ww xY wt/          d#t1                      |r|sd	n|rd$nd%d&d|t3          |          d'd()	  	        S )*NFrC   encodinggenerated_atZ+00:00r   rL   r   x   rr   T"liquidation_feed_stale_or_degradedliquidation_feed_unavailablez5https://fapi.binance.com/fapi/v1/premiumIndex?symbol=z5https://fapi.binance.com/fapi/v1/openInterest?symbol=zIhttps://fapi.binance.com/futures/data/globalLongShortAccountRatio?symbol=z&period=15m&limit=2lastFundingRate	markPrice
indexPriceopenInterestlongShortRatiolongAccountr   shortAccountliquidation_notional_usdlong_liquidated_usdshort_liquidated_usdevent_count)funding_rate
mark_priceindex_priceopen_interest_contractsglobal_long_short_ratiolong_account_pctshort_account_pctr   r   r   liquidation_event_countzbinance_crowding_error:r_   z)binance_usdm:crowding_and_force_orders:v1r   r   r   rU   gffffff?r   )r=   loadsr	   	read_textr   fromisoformatr#   r   replacemaxtime	timestampr   r'   BINANCE_SYMBOLSrA   r   rc   r(   r   r2   typerm   rI   r-   r   )rr   r   rQ   rS   liquidation_rowsliquidation_availableliquidation_payload	generatedager   symbolpremiumoiratioslatest_ratioliquidationexcs                    r   collect_binance_crowdingr   o   s   DH')!
8"j.>)?)?)I)ISZ)I)[)[\\*3/B/F/F~/V/V+W+W+_+_`cem+n+noo	!TY[[9#6#6#8#8899""8,,44266w??E2$(!!OO@AAA 8 8 86777778 S S $$T** 		S `X^ ` `aaG[SY[[\\B   Gkq   G   G   G  H  HF)3FD)A)ATfT6"::RTL*..t44:K #Bw{{3D'E'E$F$F G G!"W[[%=%=">">??"2gkk,&?&?#@#@AA+.r"&&2H2H/I/I+J+J+.r,2B2BCS2T2T/U/U+V+V$'<+;+;M+J+J(K(KgV[nn(\$]$]%(L,<,<^,L,L)M)MPWX]P^P^)^%_%_dy  -DC;??C]3^3^0_0_,`,`,`  @DZo'ys2koo>S.T.T+U+U'V'V'Vuy\q({B{?U/V/V,W,W(X(X(Xw{Wl+v3{}/M/M/RQR+S+S+Srv DJJ  	S 	S 	SOOQdQQT#YY=OQQRRRRRRRR	SEtvvW[  PTdl  PTtt  @D  sTr{r{  JT  V^  `d  fj  lq  rz  l{  l{  MP  dh  i  i  i  is+   DD D.-D.JO**
P,4-P''P,c                    i } g }	 t          d          }|                    d          pi                     d          pd gd         pi }|                    d          pg }|                    d          pi                     d          pi gd                             d          pg }d	 t          ||          D             }|r||d
         \  }}t          j        t          |          t          j                                                  	                                t          t          |                    d| d<   n|                    d           nA# t          $ r4}	|                    dt          |	          j                    Y d }	~	nd }	~	ww xY w	 t!          dd          }
t#          t%          j        t)          j        |
                              }t-          d t/          |          D             d           }|rI|                    d          t          t          |                    d                              d| d<   n|                    d           nA# t          $ r4}	|                    dt          |	          j                    Y d }	~	nd }	~	ww xY wt1          dt3                      d| v rdnddd| t5          |          dd	  	        S ) NzMhttps://query1.finance.yahoo.com/v8/finance/chart/%5EVIX?range=5d&interval=1dchartresultr   r   
indicatorsquoteclosec                     g | ]\  }}|||fS r&   r   )r   tsr!   s      r   rv   z&collect_fred_macro.<locals>.<listcomp>   s%    [[[UIZ"eIZIZIZr   r   )dater!   	vix_closevix_series_emptyzvix_series_error:z6https://fred.stlouisfed.org/graph/fredgraph.csv?id=DFFr.   r/   c              3  H   K   | ]}|                     d           dv|V  dS )DFF>   Nr   .Nr   r   s     r   	<genexpr>z%collect_fred_macro.<locals>.<genexpr>   s6      ^^so8]8]s8]8]8]8]^^r   observation_dater   fed_funds_effective_pctzfred_series_empty:DFFzfred_series_error:DFF:zmacro:yahoo_vix_fred_dff:v1r   r   highTiQ r   r   )rA   r   zipr   fromtimestampr2   r   r+   r   r,   r#   r(   r   r'   r   rm   rF   rc   csv
DictReaderioStringIOnextreversedrI   r-   r   )rQ   rS   yahoor   
timestampsclosespairsr   r!   r   textr   latests                r   collect_fred_macror	     s?   DHBijjIIg&&,"11(;;EvqIORZZ,,2
ZZ--388AAIbT1MRRSZ[[a_a[[c*f.E.E[[[ 	0b	IB)1)?B)V)V)[)[)])])g)g)i)itwxz  |A  yB  yB  uC  uC  !D  !DDOO./// B B B@DII,>@@AAAAAAAAB	GQ[]^^^CN2;t#4#45566^^htnn^^^`dee 	57=zzBT7U7U`cdfgmgqgqrwgxgxdydy`z`z.{.{D*++OO3444 G G GEc1CEEFFFFFFFFG7X\I\I\blntvz  }A  CH  IQ  CR  CR  di  }A  B  B  B  Bs1   EE 
F!*FFCI% %
J#/*JJ#i  )rV   pathrV   rP   c               h   t          |           }|                                sdddgi dS 	 t          j        |                    d                    }n# t
          $ r dddgi dcY S w xY w|                    d	          }	 t          d
t          j                    t          j
        t          |                              dd                                                    z
            }n# t
          $ r t          d          }Y nw xY wt          |                    d          pg           }|                    d          pi }|                                D ]\  }}		 t          d
t          j                    t          j
        t          |	                    d          p|	                    d                                        dd                                                    z
            }
n# t
          $ r t          d          }
Y nw xY w|
|	d<   |
t#          |	                    d          pd
          k    |	d<   |	d         s|                    d|            
||k    r|                    d           i ||||k    t          t&                              |                    dS )NmissingFexternal_context_missing)rL   r]   rS   sourcesrC   r   invalidexternal_context_invalidr   r   r   r   infrS   r  r[   rK   r\   rV   r]   zsource_stale:external_context_stale)r\   r]   rS   )r	   existsr=   r   r   r'   r   r   r   r   r   r#   r   r   rW   rc   r   r2   r   r   fromkeys)r
  rV   targetrj   r   r   rS   r  keysource
source_ages              r   load_external_contextr     s
   $ZZF==?? n#eB\A]jlmmmn*V--w-??@@ n n n#eB\A]jlmmmmmn;;~..L!TY[[8#9#l:K:K:S:STWYa:b:b#c#c#m#m#o#oopp   EllGKK
++1r22Hkk)$$*G}} 3 3V	&Q	h.DSTbIcIc  JAgmgqgqr  hA  hA  FB  FB  FJ  FJ  KN  PX  FY  FY  /Z  /Z  /d  /d  /f  /f  !f  g  gJJ 	& 	& 	&uJJJ	& *}$FJJ7H,I,I,NQ(O(OOwg 	3OO1C11222
_0111vgvcC?4JX\]a]j]jks]t]tXuXuvvvvs7   (A A+*A+A)C. .D
	D
#BG55HHr   c                    i }g }dd fd fdfdd fdd ff}|D ]\  }}	  |                                             }n`# t          $ rS}t          |t                      d	d
di dt	          |          j         f                                           }Y d }~nd }~ww xY w|||<   |                    |                    d          pg            t          d |	                                D                       }t          t                      |t          |          k    rdn|rd	ndddd|t          t                              |                    dS )N	coingeckoc                     t                      S r&   )r   r   r   r   <lambda>z build_snapshot.<locals>.<lambda>   s    /11 r   	defillamac                 v    t           pi                     d          pi                     d                    S )Nr  r  )r   r   r  s   r   r  z build_snapshot.<locals>.<lambda>   s7    /(.b1E1Ei1P1P1VTV0[0[\g0h0hii r   binance_crowdingc                     t                      S r&   )r   r   r   r   r  z build_snapshot.<locals>.<lambda>   s    %=%?%? r   
fred_macroc                     t                      S r&   )r	  r   r   r   r  z build_snapshot.<locals>.<lambda>   s    133 r   r   lowTzsource_error:rS   c              3  D   K   | ]}|                     d           dV  dS )rQ      Nr   )r   r  s     r   r   z!build_snapshot.<locals>.<genexpr>   s3      HHvVZZ5G5GHHHHHHHr   r   unavailableF)schemar   rL   rO   live_order_allowedmainnet_signed_actionr  rS   )rl   r'   rI   r-   r   rm   extendr   sumvaluesrq   r   rc   r   r  )	r   r  rS   
collectorsr  	collectorenveloper   usables	   `        r   build_snapshotr3     s    GH	112	iiiij	??@	334	J % 8 8Y	C y{{**,,HH 	C 	C 	C%c466:udBQuaefiajajasQuQuPwxx  A  A  C  CHHHHHH	CZ006B7777HH!1!1HHHHHF  CLL00$$F6]jjP]#!&x0011	 	 	s   ?
B	A	BB)r    )r!   r
   r"   r#   r$   r   )r$   r#   )r1   r#   r0   r2   r$   r
   )r1   r#   r0   r2   r$   r#   )rr   rR   r$   rI   r&   )r   r   r$   rI   )rr   rR   r   r   r$   rI   )r$   rI   )r
  r   rV   r2   r$   rP   )r   r   r$   rP   )%
__future__r   r   rf   r   r=   r   urllib.parser9   urllib.requestdataclassesr   r   r   r   decimalr   pathlibr	   typingr
   rq   ru   r   r   r(   r-   rA   rF   rI   r   r   r   r   r	  r  r3  r   r   r   <module>r;     s   " " " " " " 



  				           ) ) ) ) ) ) ) ) ' ' ' ' ' ' ' '                  -!*X{dqrr%h77 QQ3PQQQ         2 2 2 2 +- # # # # # # +- / / / / / / $       0 05u]/C/C a a a a a.p p p p p$ 7<eO6L6L )i  qd )i )i )i )i )i )iXB B B B: GK w w w w w w: 9=        r   