
    hjy                    6   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dS )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.00000001valuer   returnc                D    |                      t          t                    S Nrounding)quantizeMONEYr   r   s    /home/agent/.hermes/worktrees/FinanceManager-sprint16-smart-household-inbox-real-data-onboarding-v2/src/jarvis_finance/ledger/cost_basis.pyqmoneyr      s    >>%->888    c                h    |                      t          t                                                    S r   )r   QTYr   	normalizer   s    r   qqtyr      s$    >>#>66@@B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dS )WeightedAverageLot0r   quantitycost_basis_originalcost_basis_chfrealized_pnl_chfr	   Decimal | Nonec                    | j         dk    rd S | j        | j         z                      t          t                                                    S Nr   r   )r   r   r   r   r   r   selfs    r   average_cost_originalz(WeightedAverageLot.average_cost_original    sD    =A4(4=8BB3Q^B__iikkkr   c                    | j         dk    rd S | j        | j         z                      t          t                                                    S r!   )r   r   r   r   r   r   r"   s    r   average_cost_chfz#WeightedAverageLot.average_cost_chf&   sC    =A4#dm3==cM=ZZddfffr   cost_originalcost_chfNonec                    |dk    rt          d          | xj        |z  c_        | xj        |z  c_        | xj        |z  c_        d S )Nr   zbuy quantity must be > 0)
ValueErrorr   r   r   )r#   r   r'   r(   s       r   buyzWeightedAverageLot.buy,   sX    q==7888!  M1  x'r   proceeds_chfc                   |dk    rt          d          | j        dk    s|| j        k    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          | _        d S d S )Nr   zsell quantity must be > 0z&sell quantity exceeds current positionr   )r+   r   r   r   r   r   )r#   r   r-   ratioremoved_originalremoved_chfs         r   sellzWeightedAverageLot.sell3   s    q==8999=ADM!9!9EFFF4=(3e;)E1!  $44  {*!;;=A'.s||D$")#,,D r   N)r	   r   )r   r   r'   r   r(   r   r	   r)   )r   r   r-   r   r	   r)   )__name__
__module____qualname__r   r   __annotations__r   r   r   propertyr$   r&   r,   r2    r   r   r   r      s         H$$$$#*73<<////%gcllN**** ',,,,l l l Xl
 g g g Xg
( ( ( (/ / / / / /r   r   c                  8    e Zd ZU ded<   ded<   ded<   ded<   dS )FifoLotstractivity_idr   quantity_openedquantity_remainingcost_basis_baseNr3   r4   r5   r6   r8   r   r   r:   r:   D   sB         r   r:   T)frozenc                  8    e Zd ZU ded<   ded<   ded<   ded<   dS )FifoDisposalr;   sale_activity_idlot_activity_idr   r   allocated_cost_basisNr@   r8   r   r   rC   rC   L   sB         !!!!!!r   rC   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dS )
FifoResult)default_factoryzlist[FifoLot]lotszlist[FifoDisposal]	disposalsr   r   realized_pnlr	   c                Z    t          d | j        D             t          d                    S )Nc              3  $   K   | ]}|j         V  d S N)r>   .0lots     r   	<genexpr>z0FifoResult.remaining_quantity.<locals>.<genexpr>\   s%      @@sC*@@@@@@r   r   sumrJ   r   r"   s    r   remaining_quantityzFifoResult.remaining_quantityZ   s)    @@di@@@'#,,OOOr   c                Z    t          d | j        D             t          d                    S )Nc              3  $   K   | ]}|j         V  d S rO   )r?   rP   s     r   rS   z2FifoResult.remaining_cost_basis.<locals>.<genexpr>`   s%      ==CC'======r   r   rT   r"   s    r   remaining_cost_basiszFifoResult.remaining_cost_basis^   s)    ==49===ws||LLLr   N)r	   r   )r3   r4   r5   r   listrJ   r6   rK   r   rL   r7   rV   rY   r8   r   r   rH   rH   T   s         %555D5555$)E$$?$?$?I????#GCLLL((((P P P XP M M M XM M Mr   rH   eventslist[dict[str, object]]c           
     T   t                      }| D ]}t          |d                   }t          |d                   }t          |d                   }t          |d                   }t          |                    dt          d                              }t          |                    dt          d                              }|dk    rt	          d	          |d
k    r4||z   |z   }	|j                            t          ||||	                     |dk    r|j        }
||
k    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                            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,   r2   u4   Verkauf überschreitet den verfügbaren FIFO-Bestand)rH   r;   r   getr+   rJ   appendr:   rV   r>   minr?   rK   rC   r<   rL   )r[   resulteventr^   r<   r   r_   r`   ra   basis	available	remaining	allocatedrR   consumedlot_basis_beforelot_qty_beforeconsumed_basiss                     r   fifo_v1ro   c   sF    \\F $= $=5=!!%.//5,--g''eiiws||4455eiiws||4455q==@AAA5==CK#%EKw{HhNNOOO6>>-	iSTTT	CLL	; 	" 	"CA~~%**9c&<==H"2 3N-8>IN""h."">1%**&-cll#'I##LcoxYg$h$hiii!IIus{S09<<Mr   N)r   r   r	   r   )r[   r\   r	   rH   )__doc__
__future__r   dataclassesr   r   decimalr   r   r   r   r   r   r   r:   rC   rH   ro   r8   r   r   <module>rt      s    # " " " " " ( ( ( ( ( ( ( ( * * * * * * * *gl9 9 9 9C C C C '/ '/ '/ '/ '/ '/ '/ '/T         $" " " " " " " " M M M M M M M M1 1 1 1 1 1r   