
    j                    T   d dl mZ d dlmZ d dlmZmZmZmZ d dlm	Z	 e	d   Z
e	d   Z ed      Z ed	      Z ed
      Z ed      ZdZ ed       G d d             ZddZddZddZd dZd!dZd"dZdddd	 	 	 	 	 	 	 	 	 	 	 d#dZdedd	 	 	 	 	 	 	 	 	 	 	 d$dZd%dZy)&    )annotations)	dataclass)UTCdatedatetime	timedelta)Literal)freshstalepartialunavailableunknown)genericmarketcrypto_24_7bank_balancemanaged_portfolio   days         T)frozenc                  6    e Zd ZU ded<   ded<   ded<   ded<   y	)
FreshnessAssessmentFreshnessStatusstatusstrreason_code
str | Noneexpected_as_ofFreshnessSourceKindsource_kindN)__name__
__module____qualname____annotations__     o/home/agent/.hermes/worktrees/FinanceManager-current-import-performance/src/jarvis_finance/quality/freshness.pyr   r      s    $$r*   r   c                   | sy| j                         }	 t        |      dk(  rKt        j                  t	        j
                  |      t        j                  j                         t              S t        j
                  |j                  dd            }|j                  |j                  t              S |j                  t              S # t        $ r Y yw xY w)zDParse a source date/time as UTC without substituting a receive time.N
   tzinfoZz+00:00)striplenr   combiner   fromisoformatmintimer   replace
ValueErrorr/   
astimezone)valuerawparseds      r+   parse_source_timer=      s    
++-Cs8r>##D$6$6s$;X\\=N=N=PY\]]''C(BC *0)>6>>>%ZFDUDUVYDZZ  s   AC
 .%C
 
	CCc                J   | dz  }| dz  }| dz  }|dz  }|dz  }|dz   dz  }||z
  dz   dz  }d|z  |z   |z
  |z
  dz   d	z  }|dz  }	|dz  }
d
d|z  z   d|	z  z   |z
  |
z
  dz  }|d|z  z   d|z  z   dz  }||z   d|z  z
  dz   dz  }||z   d|z  z
  dz   dz  dz   }t        | ||      S )zFAnonymous Gregorian algorithm, used only for the SIX holiday calendar.   d            r                r   r         i  r   r   )r   )yearabcdefghiklengthmmonthdays                  r+   _easter_sundayrZ   -   s   r	AAs
A	QA	AA	
Q2A	
QqA	a!a!	b	 B&A	QA	AA1q5j1q5 1$q(A-F	
R!Vb6k	!c)AZ!a%#%",Ev:A#r
)A
-CeS!!r*   c                ^   t        |       }t        t        | dd      t        | dd      |t        d      z
  |t        d      z   t        | dd      |t        d      z   |t        d      z   t        | dd      t        | dd	      t        | dd
      t        | dd      t        | dd      h      S )zDeterministic Swiss Stock Exchange full-day closures.

    The policy mirrors the recurring SIX holiday calendar. Weekend dates are
    harmless because market-day evaluation excludes weekends independently.
    r   r   r      '   2   rB         rC      r   )rZ   	frozensetr   r   )rK   easters     r+   six_market_holidaysrd   @   s     D!Fq!q!YA&&YA&&q!YB''YB''q!r2r2r2r2	
 r*   c                Z    | j                         dk  xr | t        | j                        vS )Nr\   )weekdayrd   rK   )rY   s    r+   _is_market_dayrg   Y   s'    ;;=1I,?,I!IIr*   c                V    | }t        |      s|t        d      z  }t        |      s|S )Nr   r   )rg   r   )	reference	candidates     r+   _latest_market_dayrk   ]   s.    IY'YA&&	 Y'r*   c                    | |k\  ryd}| t        d      z   }||k  r%t        |      r|dz  }|t        d      z  }||k  r%|S )Nr   r   r   )r   rg   )sourceexpectedsessionscursors       r+   _market_sessions_afterrq   d   sZ    HiQ''F
H
&!MH)## H
 Or*   Nr   )nowr$   max_agec                   | st        ddd |      S t        |      }|t        ddd |      S |xs t        j                  t              }|j
                  |j                  t              n|j                  t              }||kD  r*t        dd|j                         j                         |      S |dk(  ret        |j                               }t        |j                         |      }t        |t        kD  rdnd	|t        kD  rd
nd|j                         |      S t        ddft        ddft        ddf|xs t         ddfd|   \  }	}
}||z
  |	kD  }t        |rdnd	|r|n|
|j                         j                         |      S )Nr   value_unavailabler   business_date_missingr.   source_date_in_futurer   r   r
   market_session_overduewithin_market_session_lagwithin_crypto_update_rhythmcrypto_update_overduewithin_bank_update_rhythmbank_update_overduewithin_managed_update_rhythmmanaged_update_overduewithin_generic_age_limitgeneric_update_overdue)r   r   r   r   )r   r=   r   rr   r   r/   r7   r9   r   	isoformatrk   rq   MARKET_MAX_SESSION_LAGCRYPTO_MAX_AGEBANK_BALANCE_MAX_AGEMANAGED_PORTFOLIO_MAX_AGEDEFAULT_FRESHNESS_MAX_AGE)	availableas_ofrr   r$   rs   source_timeri   rn   lag
policy_agefresh_reasonstale_reasonr   s                r+   assess_freshnessr   p   s    "=2Et[YY#E*K"9.Et[YY(x||C(I # 	%!!#& 
 Y".	0@0J0J0Lk
 	
 h%inn&67$[%5%5%7B"33G(+.D(D$Je 	
 	
 '(EG^_-/JLab%*$
 00&$
. .*Jl #j0Eg<""$	 r*   )rr   rs   r$   c                6    t        | ||||      j                  S )N)r   r   rr   r$   rs   )r   r   )r   r   rr   rs   r$   s        r+   freshness_statusr      s'      fr*   c                    | D cg c]
  }|dk7  s	| }}|syt        |      t        |       k7  sd|v ryd|v ryd|v ryyc c}w )zICollapse read-model sources without claiming availability that is absent.r   r   r   r   r
   )r2   )statusesr   presents      r+   combined_freshnessr      s[    $,H&-0GvHGH
7|s8}$	W(<'G Is
   
A A )r:   r!   returndatetime | None)rK   intr   r   )rK   r   r   zfrozenset[date])rY   r   r   bool)ri   r   r   r   )rm   r   rn   r   r   r   )r   r   r   r!   rr   r   r$   r#   rs   ztimedelta | Noner   r   )r   r   r   r!   rr   r   rs   r   r$   r#   r   r   )r   zlist[FreshnessStatus]r   r   )
__future__r   dataclassesr   r   r   r   r   typingr	   r   r#   r   r   r   r   r   r   r=   rZ   rd   rg   rk   rq   r   r   r   r)   r*   r+   <module>r      s:   " ! 3 3 OP  &1-  a( %2. "  $% % %["&2J	   '0 $66 6 
	6
 %6 6 6z  2'0  
	
  % "r*   