
    OhjiC                    4   d Z ddlmZ ddlZddlZddlmZ ddlmZm	Z	 ddl
mZmZm
Z
 ddlmZmZmZ dZd	Zd
ZdZdZddddZ ed       G d d             Z ed       G d d             Z ed       G d d             Z ed       G d d             Ze G d d             Zd,dZd-dZd.dZd/dZd0d Z 	 	 	 	 	 	 d1d!Z!	 	 	 	 	 	 d2d"Z"d3d#Z#	 	 	 	 	 	 d4d$Z$ ed       ed%      d&	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d5d'Z%d6d(Z&d7d)Z'd8d*Z(d9d+Z)y):zPure, reproducible portfolio-performance primitives.

The module never fetches live data and never substitutes missing prices or FX.
All money, rates and percentages remain :class:`~decimal.Decimal` values.
    )annotationsN)Iterable)	dataclassfield)UTCdatedatetime)DecimalInvalidOperationlocalcontextportfolio_performance_v2portfolio_performance_v1ttwror_daily_v1performance_attribution_chf_v1fifo_v1      )completepartialunavailableT)frozenc                  B    e Zd ZU ded<   dZded<   dZded<   dZded	<   y)
Qualitystrstatus tuple[str, ...]reasonsN
str | Nonecoverage_fromcoverage_to)__name__
__module____qualname____annotations__r   r    r!   r       a/home/agent/.hermes/worktrees/FinanceManager-main-deploy/src/jarvis_finance/ledger/performance.pyr   r      s%    K!G_! $M:$"K"r&   r   c                     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
<   dZded<   dZded<   dZded<    e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<   y)Activityr   activity_idkind
account_idoccurred_atbooking_datecurrencyNr   instrument_idDecimal | Nonequantitypricegrossr   r
   feetaxnetfx_rate_to_baseunknownsourceexternal_referencelineage_hashreversal_ofTbool	supported)r"   r#   r$   r%   r0   r2   r3   r4   r
   r5   r6   r7   r8   r:   r;   r<   r=   r?   r   r&   r'   r)   r)       s    
IOM $M:$#Hn# E>  E> 1:C1:CC&*O^*FC%)
)#L*#"K"Itr&   r)   c                      e Zd ZU ded<   ded<   ded<   ded<   ded<   ded	<   d
ed<   ded<   ded<   ded<   ded<   dZded<   dZded<   edd       Zy)	Valuationr   snapshot_id
scope_kindscope_idr   r,   r
   valuer/   r1   r8   valuation_atcaptured_atr:   intversionr   quality_statusr   r   quality_reasonsc                N    | j                   y | j                  | j                   z  S N)r8   rE   )selfs    r'   
value_basezValuation.value_baseG   s&    'zzD0000r&   N)returnr1   )r"   r#   r$   r%   rJ   rK   propertyrO   r   r&   r'   rA   rA   7   sd    OMNM##KL$NC$')O_)1 1r&   rA   c                  "    e Zd ZU ded<   ded<   y)ReturnResultr1   rE   r   qualityN)r"   r#   r$   r%   r   r&   r'   rS   rS   N   s    r&   rS   c                  r    e Zd ZU dZded<   dZded<   dZded<   dZded<    ed       Z	d	ed
<   dZ
ded<   y)
LotSummaryNr1   remaining_quantityremaining_cost_basisrealized_pnlunrealized_pnlc                     t        dd      S )Nr   )missing_cost_basis)r   r   r&   r'   <lambda>zLotSummary.<lambda>[   s    7N O r&   )default_factoryr   rT   r   r   lineage_activity_ids)r"   r#   r$   rW   r%   rX   rY   rZ   r   rT   r_   r   r&   r'   rV   rV   T   sM    )--+/./#'L.'%)NN)OGW  -//.r&   rV   c                  t        | t              rt        | d      	 t        | t              r| nt        t	        |             }|j                         st        | d      |S # t
        t        f$ r}t        | d      |d }~ww xY w)Nu    darf kein binärer Float seinu    ist keine gültige Dezimalzahlz muss endlich sein)
isinstancefloat
ValueErrorr
   r   r   	is_finite)rE   
field_nameparsedexcs       r'   parse_decimalrh   `   s    %J<'EFGGR$UG4'#e*:M J<'9:;;M	 j) RJ<'FGHcQRs   &A& &B	5BB	c                x   | j                         }t        |      dk(  rEt        j                  t	        j
                  |      t        j                  j                               S t        j
                  |j                  dd            }|j                  %|j                  t              j                  d       S |S )N
   Zz+00:00)tzinfo)striplenr	   combiner   fromisoformatmintimereplacerl   
astimezoner   )rE   textrf   s      r'   _instantrv   l   s    ;;=D
4yB 2 24 8(,,:K:K:MNN##DLLh$?@F:@--:S6S!)))6_Y__r&   c                N    t        j                  | j                         dd       S )zDReturn the source calendar day used by the daily valuation contract.Nrj   )r   rp   rm   )rE   s    r'   _calendar_dayrx   t   s     ekkmCR011r&   c                <   t        | d       }|D ci c]  }|j                  | }}t               }t               }|D ]  }|j                  dk(  rc|j                  r|j                  |vr|j                  d       >|j                  |j                         |j                  |j                         u|j                  r|j                  d        |D cg c]   }|j                  |vs|j                  s|" c}t        t        |            fS c c}w c c}w )Nc                D    t        | j                        | j                  fS rM   )rv   r-   r*   items    r'   r]   z&effective_activities.<locals>.<lambda>z   s    8D<L<L3MtO_O_2` r&   keyreversalunsupported_activity)sortedr*   setr+   r=   addr?   tuple)
activitiesorderedr|   by_idneutralizedr   s         r'   effective_activitiesr   y   s    Z%`aG078Tt#8E8EKG 099
"##t'7'7u'D23OOD,,-OOD,,-KK./0 !D$4$4K$GDNNVG_  9s   DD,D9Dc                   | j                   dvry | j                  | j                  n| j                  }|y | j                  |k(  rt	        d      }n| j
                  }|y t        ||z        }| j                   dk(  r|S | S )N>   external_depositexternal_withdrawalr   r   )r+   r7   r4   r/   r
   r8   abs)activitybase_currencyamountratesigneds        r'   external_cashflowr      s    }}GG%\\5X\\8>>F~M)qz''|$F]]&886EvgEr&   c                   t        | d       }|st        dt        dd            S t        |      dk  r$t        dt        dd|d   d   |d   d               S |d   d	   dk  r$t        dt        dd
|d   d   |d   d               S |dd D ch c]  \  }}t	        |       c}}t        fd|D              r$t        dt        dd|d   d   |d   d               S i }|D ]1  \  }}t	        |      }|j                  |t        d            |z   ||<   3 t        d	      }t        d	t        |            D ]o  }	||	d	z
     \  }
}||	   \  }}||j                  t	        |
      t        d            z   }|dk  r&t        dt        dd|d   d   |d   d               c S |||z  z  }q t        |t        d	      z
  t        dd|d   d   |d   d               S c c}}w )a@  Geometrically link subperiods.

    A cashflow must occur exactly at a valuation boundary and is treated as
    happening immediately *after* that boundary. It therefore changes the next
    subperiod's opening capital. This explicit convention makes the result
    reproducible and avoids Modified-Dietz estimates.
    c                (    t        | d         | d   fS Nr   rv   r{   s    r'   r]   ztwr_v1.<locals>.<lambda>       (472CT!W1M r&   r}   Nr   missing_opening_valuationmissing_closing_valuationr   r   r   r   invalid_opening_valuationc              3  >   K   | ]  \  }}t        |      v  y wrM   r   ).0at_boundary_timess      r'   	<genexpr>ztwr_v1.<locals>.<genexpr>   s     
E%"a8B<~-
Es   missing_cashflow_valuationinvalid_subperiod_capitalr   r   )	r   rS   r   rn   rv   anygetr
   range)
valuations	cashflowspointsr   r   flow_by_timer   r~   linkedindexprevious_atprevious_valueclosing_valuecapitalr   s                 @r'   twr_v1r      sO    J$MNF'-)cd
 	
 6{Q'-)GPQSTW]^_W`abWcd
 	
 ay|qM#A6!9Q<QWXZQ[\]Q^_
 	
 17s<ur1hrl<N

E9
EEM#BF1IaLRXY[R\]^R_`
 	
 -/L G
Frl(,,S'!*=FSG QZFq#f+& 	*&,UQY&7#^!%== <#3#3H[4I7ST:#VVa<'EvayQR|U[\^U_`aUbc  	-'))	* +WZVAYq\SYZ\S]^_S`-abb+ =s   Gc                   t        | d       }|st        dt        dd            S t        |      dk  r$t        dt        dd|d   d   |d   d               S |d   d	   dk  r$t        dt        dd
|d   d   |d   d               S |D ch c]  \  }}t	        |       c}}t              t        |      k7  r$t        dt        dd|d   d   |d   d               S t        fd|D              r$t        dt        dd|d   d   |d   d               S t	        |d   d         t	        |d   d         }}i }i }|D ]  \  }}	}
t	        |      }|
dk(  rR|	dkD  rM||k(  r&t        dt        dd|d   d   |d   d               c S |j                  |t        d            |	z   ||<   j|
dk(  r[|	dk  rV||k(  r&t        dt        dd|d   d   |d   d               c S |j                  |t        d            t        |	      z   ||<   |
dv r&t        dt        dd|d   d   |d   d               c S t        dt        dd|d   d   |d   d               c S  t        d	      }t        d	t        |            D ]  }||d	z
     \  }}||   \  }}||j                  t	        |      t        d            z   }||j                  t	        |      t        d            z   }|dk  s|dk  r&t        dt        dd|d   d   |d   d               c S |||z  z  } t        |t        d	      z
  t        dd|d   d   |d   d               S c c}}w )ay  True time-weighted return with explicit cashflow-boundary timing.

    Deposits are included in the opening capital of the subperiod beginning on
    their valuation boundary. Withdrawals are added back to the closing value of
    the subperiod ending on their boundary. Every cashflow date must have a
    stored valuation; no Modified-Dietz or provider fallback is used.
    c                (    t        | d         | d   fS r   r   r{   s    r'   r]   z!ttwror_daily_v1.<locals>.<lambda>   r   r&   r}   Nr   r   r   r   r   r   r   r   )ambiguous_daily_valuationc              3  @   K   | ]  \  }}}t        |      v  y wrM   )rx   )r   r   r   boundary_dayss      r'   r   z"ttwror_daily_v1.<locals>.<genexpr>   s!     
Lhb!Q=M1
Ls   r   r   )!cashflow_outside_return_subperiodr   >   r   r   )invalid_cashflow_sign)unsupported_external_cashflowr   r   r   )
r   rS   r   rn   rx   r   r   r
   r   r   )r   r   r   r   r   first_boundarylast_boundarydepositswithdrawalsr   r+   r~   r   r   r   r   
closing_atr   r   proceedsr   s                       @r'   r   r      s    J$MNF'-)cd
 	
 6{Q'-)GPQSTW]^_W`abWcd
 	
 ay|qM#A6!9Q<QWXZQ[\]Q^_
 	
 5;;52q]2&;M
=S[(M#A6!9Q<QWXZQ[\]Q^_
 	
 
L)
LLM#BF1IaLRXY[R\]^R_`
 	
 %2&)A,$?vVXzZ[}A]MN$&H')K% %FDB%%&1*m##%>q	!r
1	  %LLgaj9FBHSM**vzn$#%>q	!r
1	   +sGAJ?#f+MK@@'A6!9Q<QWXZQ[\]Q^_ 
  !#EvayQR|U[\^U_`aUb A%L QZFq#f+& 
%&,UQY&7#^$*5M!
M 8<<k0JGTUJ#WW ;??=3LgVWj#YYa<8a<'EvayQR|U[\^U_`aUbc  	(W$$
% +WZVAYq\SYZ\S]^_S`-abbA <s   Mc                   |dk  ry | t        d      k  ry t               5 }d|_        t        d      | z   t        d      t        |      z  z  t        d      z
  j                  t        d            cd d d        S # 1 sw Y   y xY w)Nm  r   *   r   0.000000000001)r
   r   precquantize)
cumulativedayscontexts      r'   annualize_returnr   *  sz    s{WR[ 	 
7j(gclWT].JKgVWjXbb$%

 
 
s   AA;;Bc                    | rt        |       t        |      k7  ryt        d      }t        d      }t        |       D ]4  }| |   \  }}||   \  }}|dk  s|dk  r y|||z
  |z  z  }||||z
  z  z  }6 ||fS )zKSplit unchanged-position local-value movement, assigning interaction to FX.Nr   )r   r
   r   )	openingclosingr3   fxr~   opening_local
opening_fxclosing_local
closing_fxs	            r'   price_fx_attribution_v1r   6  s     c'lc'l2AJE	Bg 8$+CL!z$+CL!z?jAo--/:==
mzJ6778 "9r&   z0.01)other_effects	tolerancec        
            || z
  |z
  }
||z
  |z
  |z   }|||z  }|||z  }|
|z
  }|duxr |du}|rt        |      |	k  rdnd}|
|||| | ||||	d
S )zCBuild an explicit CHF value bridge; unknown effects remain visible.Nr   r   )
investment_resultmarket_pricer   dividends_and_interestfeestaxesr   unattributed_residualr   tolerance_chf)r   )opening_valuer   net_external_cashflowsr   r   r   r   r   r   r   r   knownresidual
decomposedr   s                  r'   attribution_bridge_v1r   J  s     &58NN"T)E1MAE	~ 5(HT)<bnJ%#h-9*DZ)F.$"8&!)" r&   c                <   | t        d      k  rt        d      |d   d   }t        d      | z   }t        d      }t               5 }d|_        |D ]4  \  }}t        ||z
  j                        t        d      z  }||||z  z  z  }6 	 d d d        |S # 1 sw Y   |S xY w)Nr   zrate out of ranger   r   r   r   )r
   rc   r   r   r   )	r   r   originbasetotalr   	cash_dater   yearss	            r'   _xnpvr   p  s    wr{,--q\!_F1:DAJE	 ,7!* 	,IvY/556EEVtU{++E	,,
 L,
 Ls   ABBc                   t        | D cg c]  \  }}t        j                  |d d       |f! c}}d       }t        |      dk  s$t	        d |D              rt	        d |D              st        d t        dd            S |D cg c]  \  }}|d	k7  s|d	kD   }}}t        d
 t        ||dd        D              dkD  rt        d t        dd            S t        d      t        d      t        d      t        d      t        d      t        d      t        d	      g}|j                  d t        ddd      D               |j                  t        d      t        d      t        d      t        d      t        d      t        d      t        d      t        d      g       d }d }|d	   }	t        |	|      }
t        d      }t        |
      |k  r-t        |	j                  t        d            t        d            S |dd  D ]`  }t        ||      }t        |      |k  r/t        |j                  t        d            t        d            c S |
d	k  |d	k  k7  r|	|}} n||}
}	b ||t        d t        dd            S ||k(  rt        |t        d            S t        ||      }t        d      D ]  }||z   t        d      z  }t        ||      }t        |      t        d      k  st        ||z
        t        d      k  r/t        |j                  t        d            t        d            c S |d	k  |d	k  k(  r||}}|} t        d t        dd            S c c}}w c c}}w ) Nrj   c                    | d   S r   r   r{   s    r'   r]   zxirr_v1.<locals>.<lambda>  s
    a r&   r}   r   c              3  ,   K   | ]  \  }}|d k    ywr   Nr   r   r   r   s      r'   r   zxirr_v1.<locals>.<genexpr>       5)!V6A:5   c              3  ,   K   | ]  \  }}|d kD    ywr   r   r   s      r'   r   zxirr_v1.<locals>.<genexpr>  r   r   r   )insufficient_cashflowsr   c              3  ,   K   | ]  \  }}||k7    y wrM   r   )r   leftrights      r'   r   zxirr_v1.<locals>.<genexpr>  s     
B[T545=
Br   r   )mwr_multiple_solutionsz-0.9999z-0.99z-0.9z-0.75z-0.5z-0.25c              3  J   K   | ]  }t        |      t        d       z    yw)d   N)r
   )r   rE   s     r'   r   zxirr_v1.<locals>.<genexpr>  s     M5'#,.Ms   !#   i   z1.5      r   i  z
0.00000001r   r   )mwr_not_converged   )r   r   rp   rn   r   rS   r   sumzipr
   extendr   r   r   r   )r   r   r   datedr   signsrateslowhighr   
left_valuer   r   right_value	low_valuemidrE   s                    r'   xirr_v1r  ~  s;   AJK:2v$

RW
%v	.K E
 	E
Q5u555u55D'-9T"UVV */>IAv&A+VaZ>E>

BCuQRy,A
BBQFD'-9T"UVV	
E 
LLME!S!<LMM	LLENAJAJAJBKBKCLDM		
 CD8DtU#J%I
:)#DMM'2B*CDgjFYZZqr .E5){y(w7G/H I7S]K^__Na0eC +j. {dlD'-9O"PQQ
d{C!455c5!I3Z TzWQZ'c5!u:..#dSj/WM]E^2^W5E-F GQ[I\]]Muqy) %CD gm5KLMMC 	L ?s   $M
M!M!c                    t        j                  | dddt              }t        j                  |j                  d            j                         S )NT),:F)	sort_keys
separatorsensure_asciidefaultzutf-8)jsondumpsr   hashlibsha256encode	hexdigest)payload	canonicals     r'   stable_input_fingerprintr!    sA    

4JUTWI >>)**734>>@@r&   c           
        t        |       }|st        dd      S t        |d       j                  }t	        t        |D ch c]  }|j                  D ]  }|  c}}            }|D cg c]  }|j                  s|j                   }}|D cg c]  }|j                  s|j                   }}t        |||rt        |      nd |rt        |            S d       S c c}}w c c}w c c}w )Nr   )insufficient_datac                (    t         | j                     S rM   )QUALITY_ORDERr   r{   s    r'   r]   z"combined_quality.<locals>.<lambda>  s    -*D r&   r}   )
listr   rq   r   r   r   r   r    r!   max)	qualitiesvaluesr   r|   reasonr   startsendss           r'   combined_qualityr-    s    )_F}&<==DELLFFvQtDLLQ&FQFQRSG-3JTt7I7Id  JFJ)/D43C3CDDDD676CKtRVSYaa\`aa RJDs   C+C%=C%C*#C*)rE   objectre   r   rP   r
   )rE   r   rP   r	   )rE   r   rP   r   )r   zIterable[Activity]rP   z&tuple[list[Activity], tuple[str, ...]])r   r)   r   r   rP   r1   )r   list[tuple[str, Decimal]]r   r/  rP   rS   )r   r/  r   zlist[tuple[str, Decimal, str]]rP   rS   )r   r
   r   rH   rP   r1   )r   "dict[str, tuple[Decimal, Decimal]]r   r0  rP   ztuple[Decimal, Decimal] | None)r   r
   r   r
   r   r
   r   r1   r   r1   r   r
   r   r
   r   r
   r   r
   r   r
   rP   zdict[str, Decimal | str | None])r   r
   r   zlist[tuple[date, Decimal]]rP   r
   )r   r/  rP   rS   )r  r.  rP   r   )r(  zIterable[Quality]rP   r   )*__doc__
__future__r   r  r  collections.abcr   dataclassesr   r   r	   r   r   decimalr
   r   r   ENGINE_VERSIONLEGACY_ENGINE_VERSIONTTWROR_VERSIONATTRIBUTION_VERSIONCOST_BASIS_VERSIONr%  r   r)   rA   rS   rV   rh   rv   rx   r   r   r   r   r   r   r   r   r  r!  r-  r   r&   r'   <module>r;     s   #   $ ( ( ( ; ;+2 "6  1Q? $# # # $  , $1 1 1, $  
 / / /	`2
&F .c).c6O.c.cbZc)Zc-Zc Zcz	
// $< %QZ ## # $	#
 !# 	# $# # # # # %#LCNLAbr&   