
    cjy                        d Z ddlmZ ddlmZmZ ddlmZmZ  ed      Z	 ed      Z
ddZddZe G d	 d
             Ze G d d             Z ed       G d d             Ze G d d             Z	 	 	 	 ddZy)zDeterministic cost-basis engines.

``WeightedAverageLot`` remains available for legacy position views. New portfolio
performance calculations use ``fifo_v1`` and keep lot lineage to the originating
canonical activity.
    )annotations)	dataclassfield)DecimalROUND_HALF_UPz0.01z
0.00000001c                8    | j                  t        t              S Nrounding)quantizeMONEYr   values    `/home/agent/.hermes/worktrees/FinanceManager-main-deploy/src/jarvis_finance/ledger/cost_basis.pyqmoneyr      s    >>%->88    c                T    | j                  t        t              j                         S r	   )r   QTYr   	normalizer   s    r   qqtyr      s    >>#>6@@BBr   c                      e Zd ZU  ed      Zded<    ed      Zded<    ed      Zded<    ed      Zded<   e	dd       Z
e	dd       Zdd	Zdd
Zy)WeightedAverageLot0r   quantitycost_basis_originalcost_basis_chfrealized_pnl_chfc                    | j                   dk(  ry | j                  | j                   z  j                  t        t              j                         S Nr   r
   )r   r   r   r   r   r   selfs    r   average_cost_originalz(WeightedAverageLot.average_cost_original    s@    ==A((4==8BB3Q^B_iikkr   c                    | j                   dk(  ry | j                  | j                   z  j                  t        t              j                         S r   )r   r   r   r   r   r   r    s    r   average_cost_chfz#WeightedAverageLot.average_cost_chf&   s?    ==A##dmm3==cM=Zddffr   c                    |dk  rt        d      | xj                  |z  c_        | xj                  |z  c_        | xj                  |z  c_        y )Nr   zbuy quantity must be > 0)
ValueErrorr   r   r   )r!   r   cost_originalcost_chfs       r   buyzWeightedAverageLot.buy,   sE    q=788!  M1 x'r   c                   |dk  rt        d      | j                  dk  s|| j                  kD  rt        d      || j                  z  }| j                  |z  }| j                  |z  }| xj                  |z  c_        | xj                  |z  c_        | xj                  |z  c_        | xj                  ||z
  z  c_        | j                  dk(  r!t        d      | _        t        d      | _        y y )Nr   zsell quantity must be > 0z&sell quantity exceeds current positionr   )r&   r   r   r   r   r   )r!   r   proceeds_chfratioremoved_originalremoved_chfs         r   sellzWeightedAverageLot.sell3   s    q=899==ADMM!9EFF4==(33e;))E1!  $44 {*!;;==A'.s|D$")#,D r   N)returnzDecimal | None)r   r   r'   r   r(   r   r0   None)r   r   r+   r   r0   r1   )__name__
__module____qualname__r   r   __annotations__r   r   r   propertyr"   r$   r)   r/    r   r   r   r      sp    Hg$#*3</%clNG* 'g,l l
 g g
(/r   r   c                  6    e Zd ZU ded<   ded<   ded<   ded<   y)FifoLotstractivity_idr   quantity_openedquantity_remainingcost_basis_baseNr2   r3   r4   r5   r7   r   r   r9   r9   D   s    r   r9   T)frozenc                  6    e Zd ZU ded<   ded<   ded<   ded<   y)FifoDisposalr:   sale_activity_idlot_activity_idr   r   allocated_cost_basisNr?   r7   r   r   rB   rB   L   s    !!r   rB   c                      e Zd ZU  ee      Zded<    ee      Zded<    ed      Z	ded<   e
dd	       Ze
dd
       Zy)
FifoResult)default_factoryzlist[FifoLot]lotszlist[FifoDisposal]	disposalsr   r   realized_pnlc                N    t        d | j                  D        t        d            S )Nc              3  4   K   | ]  }|j                     y wN)r=   .0lots     r   	<genexpr>z0FifoResult.remaining_quantity.<locals>.<genexpr>\   s     @sC**@   r   sumrI   r   r    s    r   remaining_quantityzFifoResult.remaining_quantityZ   s    @dii@'#,OOr   c                N    t        d | j                  D        t        d            S )Nc              3  4   K   | ]  }|j                     y wrN   )r>   rO   s     r   rR   z2FifoResult.remaining_cost_basis.<locals>.<genexpr>`   s     =CC''=rS   r   rT   r    s    r   remaining_cost_basiszFifoResult.remaining_cost_basis^   s    =499=ws|LLr   N)r0   r   )r2   r3   r4   r   listrI   r5   rJ   r   rK   r6   rV   rY   r7   r   r   rG   rG   T   sY    5D-5$)$$?I!?#CLL'(P P M Mr   rG   c           
        t               }| D ]  }t        |d         }t        |d         }t        |d         }t        |d         }t        |j                  dt        d                  }t        |j                  dt        d                  }|dk  rt	        d	      |d
k(  r0||z   |z   }	|j
                  j                  t        ||||	             |dk7  r|j                  }
||
kD  rt	        d      |}t        d      }|j
                  D ]  }|dk(  r n|j                  dk(  rt        ||j                        }|j                  }|j                  }||z  |z  }|xj                  |z  c_	        |xj                  |z  c_        |j                  dk(  rt        d      |_        ||z  }|j                  j                  t        ||j                  ||             ||z  } |xj                  ||z
  |z
  |z
  z  c_         |S )au  Apply FIFO to normalized buy/sell events in deterministic input order.

    Every event needs ``activity_id``, ``kind``, ``quantity`` and base-currency
    ``gross``, ``fee`` and ``tax`` Decimals. Buy fees/taxes increase basis;
    sell fees/taxes reduce proceeds. Unsupported or incomplete events must be
    rejected by the caller before invoking this pure function.
    kindr;   r   grossfeer   taxr   u!   Menge muss grösser als null seinr)   r/   u4   Verkauf überschreitet den verfügbaren FIFO-Bestand)rG   r:   r   getr&   rI   appendr9   rV   r=   minr>   rJ   rB   r;   rK   )eventsresulteventr\   r;   r   r]   r^   r_   basis	available	remaining	allocatedrQ   consumedlot_basis_beforelot_qty_beforeconsumed_basiss                     r   fifo_v1rn   c   s	    \F $=5=!%./5,-g'eiiws|45eiiws|45q=@AA5=CK#%EKKw{HhNO6>--	iSTT	CL	;; 	"CA~%%*9c&<&<=H"22 33N-8>IN""h.">1%%*&-cl#'I##LcooxYg$hi!I	"  	us{S09<<I$=J Mr   N)r   r   r0   r   )rc   zlist[dict[str, object]]r0   rG   )__doc__
__future__r   dataclassesr   r   decimalr   r   r   r   r   r   r   r9   rB   rG   rn   r7   r   r   <module>rs      s    # ( *l9C '/ '/ '/T    $" " " M M M1#11r   