
    pj                        d dl mZ d dlZd dlmc mZ d dlm	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 Zd	d
ddd d ddddd
dZddZddZddZddZddZddZddZddZdS )    )annotationsN)Decimal)apply_manual_cash_correctioncalculate_cash_balances)calculate_positionssave_position_snapshots)connect_memory)apply_migrationsc                     t                      } t          |            |                     d           |                     d           |                     d           |                     d           | S )NzINSERT INTO platforms(platform_id,name,platform_type,default_currency,created_at) VALUES('p1','Demo Broker','broker','CHF','now')zINSERT INTO accounts(account_id,platform_id,account_name,account_type,currency,created_at) VALUES('a1','p1','Main','brokerage','CHF','now')zINSERT INTO instruments(instrument_id,asset_class,name,ticker,isin,currency,created_at) VALUES('i1','equity','Demo AG','DAG','CH0001','CHF','now')zINSERT INTO instruments(instrument_id,asset_class,name,ticker,isin,currency,created_at) VALUES('u1','equity','USD Demo Inc','UDI','US0001','USD','now'))r	   r
   execute)conns    U/home/agent/.hermes/repos/FinanceManager/tests/unit/test_ledger_cash_wac_positions.py
setup_connr      s    DTLL  U  V  V  VLL  _  `  `  `LL  f  g  g  gLL  k  l  l  lK    i1
2026-01-01CHF   	synthetic)

instrumentdateqtygrossfeetaxnetcurrencyfxnotec       
        t   |                      d||d|||t          |          nd d |t          |          nd t          |          t          |          |	t          |	          nd |
|t          |          nd |dnd|H|Ft          t          t          |                    t          t          |                    z            nd |Ft          t          t          |                    t          t          |                    z            nd |Ft          t          t          |                    t          t          |                    z            nd |	H|Ft          t          t          |	                    t          t          |                    z            nd dd|dnd|df           d S )	Na  INSERT INTO transactions(
            transaction_id, transaction_type, account_id, instrument_id, trade_date,
            quantity, price_original, gross_amount_original, fee_original, tax_original,
            net_amount_original, currency_original, fx_rate_to_chf, fx_status,
            gross_amount_chf, fee_chf, tax_chf, net_amount_chf,
            source_type, is_confirmed, quality_status, notes, created_at
        ) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)a1okmissingr   r   
incompletenow)r   strr   )r   tidttyper   r   r   r   r   r   r   r   r   r   s                r   txr)      s   LL	C j$COCQUW[+CJJJs3xxSWZWf3s888lpc"gggT2>44W`9>9Jr~CE

##GCGG$4$44555cg79~CC!!'#b''"2"22333479~CC!!'#b''"2"2233347:2>CC!!'#b''"2"22333_cBNDDdE		
    r   returnNonec            
        t                      } t          | ddd dd           t          | dddddd	
           t          | ddddddd           t          | ddd ddd           t          | ddd dd           t          | ddd dd           t          |           }d}|j        |         }|j        }d}t          |          }||k    }|st          j        d |fd!||f          t          j        |          t          j        |          d"t          j
                    v st          j        t
                    rt          j        t
                    nd"t          j        |          t          j        |          d#z  }d$d%|iz  }	t          t          j        |	                    d x}x}x}x}}|j        |         }|j        }d}t          |          }||k    }|st          j        d |fd&||f          t          j        |          t          j        |          d"t          j
                    v st          j        t
                    rt          j        t
                    nd"t          j        |          t          j        |          d#z  }d$d%|iz  }	t          t          j        |	                    d x}x}x}x}}|j        }
g }|
|k    }|st          j        d |fd'|
|f          d(t          j
                    v st          j        |          rt          j        |          nd(t          j        |
          t          j        |          d)z  }d*d+|iz  }t          t          j        |                    d x}
x}}d S ),Nc0initial_cash_snapshot  r   r   r   b1buy   i  i  r   r   r   r   s1partial_sell   i  r   i  )r   r   r   r   r   d1dividend         r   r   r   r   f1r      t1r      r!   r   758==zU%(py3)s
{%(py3)s = %(py1)s.amount_original
} == %(py9)s
{%(py9)s = %(py5)s(%(py7)s)
}r   py1py3py5py7py9assert %(py11)spy11)zP%(py3)s
{%(py3)s = %(py1)s.amount_chf
} == %(py9)s
{%(py9)s = %(py5)s(%(py7)s)
})z>%(py2)s
{%(py2)s = %(py0)s.negative_cash_warnings
} == %(py5)sresultpy0py2rJ   assert %(py7)srK   )r   r)   r   balancesamount_originalr   
@pytest_ar_call_reprcompare	_saferepr@py_builtinslocals_should_repr_global_nameAssertionError_format_explanation
amount_chfnegative_cash_warnings)r   rO   key@py_assert0@py_assert2@py_assert6@py_assert8@py_assert4@py_format10@py_format12@py_assert1@py_assert3@py_format6@py_format8s                 r   Qtest_initial_cash_snapshot_is_start_truth_and_buy_sell_dividend_fee_tax_move_cashrl   +   s   <<DtT*t4TRRRRtT5ass;;;;tT>qsKKKKtT:4rqbAAAAtT5T::::tT5T::::$T**F
C?3A/A5A75>>A/>AAAAAAAAAA/>AAAAAAAAA/AAAAAAAAAAA7AAAAA7AAAAAA5AAAA>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA?3<*<e<genn<*n<<<<<<<<<<*n<<<<<<<<<*<<<<<<<<<<<g<<<<<g<<<<<<e<<<<n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<(.B.(B..........(B............6.....6......(....B.............................r   c            	        t                      } t          | ddd dd           t          | ddddd	d
           t          |           }|j        d         }|j        }d}t          |          }||k    }|st          j        d|fd||f          t          j        |          t          j        |          dt          j
                    v st          j        t
                    rt          j        t
                    ndt          j        |          t          j        |          dz  }dd|iz  }t          t          j        |                    d x}x}x}x}}|j        }	|	sxddt          j
                    v st          j        |          rt          j        |          ndt          j        |	          dz  }
t          t          j        |
                    d }	|                     d                                          }|d         }d}||k    }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }dd|iz  }t          t          j        |                    d x}x}}d S )Nr-   r.   d   r0   r1   r2   r7      r   r4   rB   z-100rD   rF   r   rG   rM   rN   z:assert %(py2)s
{%(py2)s = %(py0)s.negative_cash_warnings
}rO   )rQ   rR   zBSELECT priority, rule_id FROM alerts WHERE rule_id='negative_cash'prioritywarnungz%(py1)s == %(py4)srH   py4assert %(py6)spy6)r   r)   r   rT   rU   r   rV   rW   rX   rY   rZ   r[   r\   r]   r_   r   fetchone)r   rO   ra   rb   rc   rd   re   rf   rg   rh   @py_format3alertri   @py_format5@py_format7s                  r   1test_cash_negative_creates_warning_not_correctionr|   <   s   <<DtT*t3CPPPPtT5ass;;;;$T**F?=)L)9LVLWV__L9_LLLLLLLLLL9_LLLLL)LLLL9LLLLLLLLLLLWLLLLLWLLLLLLVLLLL_LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL((((((((((((((6(((((6((((((((((((((((((((((((LL]^^ggiiE)	)	))))))))))	)))))))))	)))))))))))))))))))))))))))))r   c                 4   t                      } 	 t          | ddt          d          d           t          d          # t          $ r}d}t          |          }||v }|st          j        d|fd	||f          t          j        |          d
t          j
                    v st          j        t
                    rt          j        t
                    nd
dt          j
                    v st          j        |          rt          j        |          ndt          j        |          dz  }dd|iz  }t          t          j        |                    d x}x}}Y d }~nd }~ww xY wt          | ddt          d          d          }|sedddt          j
                    v st          j        |          rt          j        |          ndiz  }t          t          j        |                    |                     d                                          d         }d}	||	k    }|slt          j        d|fd||	f          t          j        |          t          j        |	          dz  }
dd|
iz  }t          t          j        |                    d x}x}}	d S )Nr!   r   10 )
account_idr   amountr   zexpected note validationr   in)z0%(py1)s in %(py6)s
{%(py6)s = %(py3)s(%(py4)s)
}r&   exc)rH   rI   rt   rv   zassert %(py8)spy8zSynthetic reconciliationzassert %(py0)srQ   audit_idzISELECT COUNT(*) AS n FROM audit_log WHERE action='manual_cash_correction'nr   rD   rr   rs   ru   rv   )r   r   r   r\   
ValueErrorr&   rV   rW   rX   rY   rZ   r[   r]   r   rw   )r   r   ra   @py_assert5rb   r{   @py_format9r   @py_format1ri   rz   s              r   3test_manual_cash_correction_requires_note_and_auditr   I   s   <<D9$TdUSZ[_S`S`gijjjj 7888  " " "!S!v!!!!!!!!!!v!!!!!v!!!!!!!!!!!!!!!!!!!!!!!!!!!!!S!!!!!S!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
 ,DTEZabfZgZg  oI  J  J  JHOOOOOOOOOOOO8OOOOO8OOOOOOOOOOOOOOOO<<cddmmoopstyxyytxyyyyyyyyyyytxyyyyyytyyyyxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyys   !A   E$DEE$c                    t                      } t          | dddddddddd	
           t          | dddddddddd
           t          | dddddddddd
           t          |           }|j        d         }|j        }d}t          |          }||k    }|st          j        d|fd||f          dt          j	                    v st          j
        |          rt          j        |          ndt          j        |          dt          j	                    v st          j
        t
                    rt          j        t
                    ndt          j        |          t          j        |          dz  }d d!|iz  }t          t          j        |                    d x}x}x}}|j        }d"}t          |          }||k    }|st          j        d|fd#||f          dt          j	                    v st          j
        |          rt          j        |          ndt          j        |          dt          j	                    v st          j
        t
                    rt          j        t
                    ndt          j        |          t          j        |          dz  }d d!|iz  }t          t          j        |                    d x}x}x}}|j        }d$}t          |          }||k    }|st          j        d|fd%||f          dt          j	                    v st          j
        |          rt          j        |          ndt          j        |          dt          j	                    v st          j
        t
                    rt          j        t
                    ndt          j        |          t          j        |          dz  }d d!|iz  }t          t          j        |                    d x}x}x}}|j        }d&}t          |          }||k    }|st          j        d|fd'||f          dt          j	                    v st          j
        |          rt          j        |          ndt          j        |          dt          j	                    v st          j
        t
                    rt          j        t
                    ndt          j        |          t          j        |          dz  }d d!|iz  }t          t          j        |                    d x}x}x}}|j        }d(}t          |          }||k    }|st          j        d|fd)||f          dt          j	                    v st          j
        |          rt          j        |          ndt          j        |          dt          j	                    v st          j
        t
                    rt          j        t
                    ndt          j        |          t          j        |          dz  }d d!|iz  }t          t          j        |                    d x}x}x}}|j        }d*}t          |          }||k    }|st          j        d|fd+||f          dt          j	                    v st          j
        |          rt          j        |          ndt          j        |          dt          j	                    v st          j
        t
                    rt          j        t
                    ndt          j        |          t          j        |          dz  }d d!|iz  }t          t          j        |                    d x}x}x}}d S ),Nr1   r2   u1r   
   r/   i  USDz0.90)r   r   r   r   r   r   r   r   b2
2026-01-02i     i  z0.80r5   r6   z
2026-01-03r3   i  r;   i  z0.85)r!   r   15rD   zN%(py2)s
{%(py2)s = %(py0)s.quantity
} == %(py8)s
{%(py8)s = %(py4)s(%(py6)s)
}posr   rQ   rR   rt   rv   r   assert %(py10)spy10z1666.5)zY%(py2)s
{%(py2)s = %(py0)s.cost_basis_original
} == %(py8)s
{%(py8)s = %(py4)s(%(py6)s)
}z1408.95zT%(py2)s
{%(py2)s = %(py0)s.cost_basis_chf
} == %(py8)s
{%(py8)s = %(py4)s(%(py6)s)
}z111.1)z[%(py2)s
{%(py2)s = %(py0)s.average_cost_original
} == %(py8)s
{%(py8)s = %(py4)s(%(py6)s)
}z119.40zV%(py2)s
{%(py2)s = %(py0)s.realized_pnl_chf
} == %(py8)s
{%(py8)s = %(py4)s(%(py6)s)
}z24.55)zN%(py2)s
{%(py2)s = %(py0)s.fees_chf
} == %(py8)s
{%(py8)s = %(py4)s(%(py6)s)
})r   r)   r   	positionsquantityr   rV   rW   rY   rZ   r[   rX   r\   r]   cost_basis_originalcost_basis_chfaverage_cost_originalrealized_pnl_chffees_chf)	r   r   r   rh   r   @py_assert7ri   r   @py_format11s	            r   Gtest_weighted_average_cost_buy_fee_usd_fx_and_partial_sell_realized_pnlr   W   s$   <<DtT5T"DVX^bmrw}~~~~tT5T"DVX^bmrw}~~~~tT>d1TW]^dgrw  }C  D  D  D  D#D))I

l
+C<(4(74==(<=((((((((((<=((((((((((((3(((((3((((((<(((((((((((7(((((7((((((4((((=((((((((((((((((((((((((((((("7h7gh&7&77"&77777777777"&77777777777773777773777777"77777777777g77777g777777h7777&77777777777777777777777777777733!3!33!33333333333!3333333333333333333333333333333333333333333333333333!333333333333333333333333333333$88(8(88$(88888888888$(88888888888883888883888888$88888888888888888888888888(88888888888888888888888888888848478#4#44#44444444444#4444444444444344444344444444444444444744444744444484444#444444444444444444444444444444<+7+77+++<+++++++++++<+++++++++++++3+++++3++++++<+++++++++++7+++++7++++++7++++++++++++++++++++++++++++++++++++r   c            	        t                      } t          | dddddd           t          | dddd	dd	           t          |           j        d
         }|j        }d}t          |          }||k    }|st          j        d|fd||f          dt          j	                    v st          j
        |          rt          j        |          ndt          j        |          dt          j	                    v st          j
        t
                    rt          j        t
                    ndt          j        |          t          j        |          dz  }dd|iz  }t          t          j        |                    d x}x}x}}|j        }d}t          |          }||k    }|st          j        d|fd||f          dt          j	                    v st          j
        |          rt          j        |          ndt          j        |          dt          j	                    v st          j
        t
                    rt          j        t
                    ndt          j        |          t          j        |          dz  }dd|iz  }t          t          j        |                    d x}x}x}}|j        }d}t          |          }||k    }|st          j        d|fd||f          dt          j	                    v st          j
        |          rt          j        |          ndt          j        |          dt          j	                    v st          j
        t
                    rt          j        t
                    ndt          j        |          t          j        |          dz  }dd|iz  }t          t          j        |                    d x}x}x}}d S )Nr1   r2   r?   i,  r   r4   r5   	full_selliJ  r!   r   0rD   r   r   r   r   r   r   r   30r   )r   r)   r   r   r   r   rV   rW   rY   rZ   r[   rX   r\   r]   r   r   r   r   rh   r   r   ri   r   r   s           r   Gtest_full_sell_sets_quantity_zero_and_keeps_historical_position_visibler   h   s
   <<DtT5ass;;;;tT;ASaSAAAA
d
#
#
-l
;C<'3'73<<'<<''''''''''<<''''''''''''3'''''3''''''<'''''''''''7'''''7''''''3''''<'''''''''''''''''''''''''''''-------------------------3-----3-------------------------------------------------------------04074==0=0000000000=000000000000300000300000000000000000700000700000040000=0000000000000000000000000000000r   c            	     
   t                      } t          | dddddd           t          | ddd d	d
d           t          |           j        d         }|j        }d}t          |          }||k    }|st          j        d|fd||f          dt          j	                    v st          j
        |          rt          j        |          ndt          j        |          dt          j	                    v st          j
        t
                    rt          j        t
                    ndt          j        |          t          j        |          dz  }dd|iz  }t          t          j        |                    d x}x}x}}|j        }d}t          |          }||k    }|st          j        d|fd||f          dt          j	                    v st          j
        |          rt          j        |          ndt          j        |          dt          j	                    v st          j
        t
                    rt          j        t
                    ndt          j        |          t          j        |          dz  }dd|iz  }t          t          j        |                    d x}x}x}}|j        }d}t          |          }||k    }|st          j        d|fd||f          dt          j	                    v st          j
        |          rt          j        |          ndt          j        |          dt          j	                    v st          j
        t
                    rt          j        t
                    ndt          j        |          t          j        |          dz  }dd|iz  }t          t          j        |                    d x}x}x}}|j        }d}t          |          }||k    }|st          j        d|fd||f          dt          j	                    v st          j
        |          rt          j        |          ndt          j        |          dt          j	                    v st          j
        t
                    rt          j        t
                    ndt          j        |          t          j        |          dz  }dd|iz  }t          t          j        |                    d x}x}x}}d S )Nr1   r2   rA   i  i  r4   r8   r9   (         r=   r   4rD   r   r   r   r   r   r   404r   26)zP%(py2)s
{%(py2)s = %(py0)s.income_chf
} == %(py8)s
{%(py8)s = %(py4)s(%(py6)s)
}14)zO%(py2)s
{%(py2)s = %(py0)s.taxes_chf
} == %(py8)s
{%(py8)s = %(py4)s(%(py6)s)
})r   r)   r   r   r   r   rV   rW   rY   rZ   r[   rX   r\   r]   r   
income_chf	taxes_chfr   s           r   7test_dividend_changes_income_not_quantity_or_cost_basisr   t   s<   <<DtT5ass;;;;tT:4rrrBBBB
d
#
#
-l
;C<'3'73<<'<<''''''''''<<''''''''''''3'''''3''''''<'''''''''''7'''''7''''''3''''<'''''''''''''''''''''''''''''/////////////////////////3/////3/////////////////////////////////////////////////////////////>*T*WT]]*>]**********>]************3*****3******>***********W*****W******T****]*****************************=)D)GDMM)=M))))))))))=M))))))))))))3)))))3))))))=)))))))))))G)))))G))))))D))))M)))))))))))))))))))))))))))))))r   c            
        t                      } t          | ddddddd            t          |           }|j        d         }|j        }d}||k    }|st          j        d	|fd
||f          dt          j                    v st          j	        |          rt          j
        |          ndt          j
        |          t          j
        |          dz  }dd|iz  }t          t          j        |                    d x}x}}d}|j        }||v }	|	st          j        d|	fd||f          t          j
        |          dt          j                    v st          j	        |          rt          j
        |          ndt          j
        |          dz  }dd|iz  }t          t          j        |                    d x}x}	}d}|j        }||v }	|	st          j        d|	fd||f          t          j
        |          dt          j                    v st          j	        |          rt          j
        |          ndt          j
        |          dz  }dd|iz  }t          t          j        |                    d x}x}	}|j        }d }||u }|st          j        d|fd||f          dt          j                    v st          j	        |          rt          j
        |          ndt          j
        |          t          j
        |          dz  }dd|iz  }t          t          j        |                    d x}x}}|                     d                                          d         }d}||k    }	|	slt          j        d|	fd||f          t          j
        |          t          j
        |          dz  }
dd|
iz  }t          t          j        |                    d x}x}	}d S )Nr1   r2   r7   ro   r   )r   r   r   r   r   r   r$   rD   )z;%(py2)s
{%(py2)s = %(py0)s.data_quality_status
} == %(py5)sr   rP   rS   rK   missing_market_pricer   )z8%(py1)s in %(py5)s
{%(py5)s = %(py3)s.quality_warnings
})rH   rI   rJ   
missing_fx)is)z8%(py2)s
{%(py2)s = %(py0)s.total_return_chf
} is %(py5)szWSELECT COUNT(*) AS n FROM alerts WHERE rule_id IN ('missing_market_price','missing_fx')r   )>=)z%(py1)s >= %(py4)srs   ru   rv   )r   r)   r   r   data_quality_statusrV   rW   rY   rZ   r[   rX   r\   r]   quality_warningstotal_return_chfr   rw   )r   rO   r   rh   re   ri   rj   rk   ra   rb   rz   r{   s               r   Jtest_missing_market_price_warns_and_missing_fx_blocks_precise_total_returnr      sN   <<DtT5asstDDDD &&F

<
(C"2l2"l2222222222"l2222222222223222223222222"2222l222222222222222222222222222!9S%99!%99999999999!%999999!99999999999S99999S999999%9999999999999999999999999999/3//<///////////<//////<///////////3/////3//////////////////////////////////'4'4''''''''''4''''''''''''3'''''3''''''''''4'''''''''''''''''''''''''''<<qrr{{}}  B  C  H  GH  H  C  GH  H  H  H  H  H  H  H  H  H  H  C  GH  H  H  H  H  H  C  H  H  H  H  GH  H  H  H  H  H  H  H  H  H  H  H  H  H  H  H  H  H  H  H  H  H  H  H  H  H  H  H  H  Hr   c            	     
   t                      } t          | dddddd           |                     d           t          | d	          }|j        d
         }|j        }d}t          |          }||k    }|st          j        d|fd||f          dt          j
                    v st          j        |          rt          j        |          ndt          j        |          dt          j
                    v st          j        t                    rt          j        t                    ndt          j        |          t          j        |          dz  }dd|iz  }t          t          j        |                    d x}x}x}}|j        }d}t          |          }||k    }|st          j        d|fd||f          dt          j
                    v st          j        |          rt          j        |          ndt          j        |          dt          j
                    v st          j        t                    rt          j        t                    ndt          j        |          t          j        |          dz  }dd|iz  }t          t          j        |                    d x}x}x}}|j        }d}t          |          }||k    }|st          j        d|fd||f          dt          j
                    v st          j        |          rt          j        |          ndt          j        |          dt          j
                    v st          j        t                    rt          j        t                    ndt          j        |          t          j        |          dz  }dd|iz  }t          t          j        |                    d x}x}x}}t#          | |d           |                     d                                          d         }	d}|	|k    }
|
slt          j        d|
fd|	|f          t          j        |	          t          j        |          dz  }dd|iz  }t          t          j        |                    d x}	x}
}|                     d                                          d         }	d}|	|k    }
|
slt          j        d|
fd|	|f          t          j        |	          t          j        |          dz  }dd|iz  }t          t          j        |                    d x}	x}
}d S ) Nr1   r2   r7   ro   r   r4   zINSERT INTO market_prices(market_price_id,instrument_id,price_date,close,currency,provider,quality_status,created_at) VALUES('mp1','i1','2026-01-02',120,'CHF','synthetic','ok','now')r   )
as_of_dater   240rD   )zV%(py2)s
{%(py2)s = %(py0)s.market_value_chf
} == %(py8)s
{%(py8)s = %(py4)s(%(py6)s)
}r   r   r   r   r   40)zX%(py2)s
{%(py2)s = %(py0)s.unrealized_pnl_chf
} == %(py8)s
{%(py8)s = %(py4)s(%(py6)s)
})zV%(py2)s
{%(py2)s = %(py0)s.total_return_chf
} == %(py8)s
{%(py8)s = %(py4)s(%(py6)s)
}zSynthetic calculated snapshot)r   z,SELECT COUNT(*) AS n FROM positions_snapshotr   r   rr   rs   ru   rv   zNSELECT COUNT(*) AS n FROM audit_log WHERE action='calculate_position_snapshot')r   r)   r   r   r   market_value_chfr   rV   rW   rY   rZ   r[   rX   r\   r]   unrealized_pnl_chfr   r   rw   )r   rO   r   rh   r   r   ri   r   r   ra   rb   rz   r{   s                r   Htest_market_price_enables_unrealized_pnl_total_return_and_snapshot_auditr      s   <<DtT5ass;;;;LL  J  K  K  K ,???F

<
(C15175>>1>1111111111>111111111111311111311111111111111111711111711111151111>11111111111111111111111111111!2T2WT]]2!]2222222222!]2222222222223222223222222!22222222222W22222W222222T2222]2222222222222222222222222222204074==0=0000000000=000000000000300000300000000000000000700000700000040000=00000000000000000000000000000D&/NOOOO<<FGGPPRRSVW\[\\W[\\\\\\\\\\\W[\\\\\\W\\\\[\\\\\\\\\\\\\\\\\\\\\\\\\\\\<<hiirrttuxy~}~~y}~~~~~~~~~~~y}~~~~~~y~~~~}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~r   )r*   r+   )
__future__r   builtinsrY   _pytest.assertion.rewrite	assertionrewriterV   decimalr   jarvis_finance.ledger.cashr   r   jarvis_finance.ledger.positionsr   r   jarvis_finance.storage.databaser	   !jarvis_finance.storage.migrationsr
   r   r)   rl   r|   r   r   r   r   r   r    r   r   <module>r      s   " " " " " "                     \ \ \ \ \ \ \ \ X X X X X X X X : : : : : : > > > > > >   (,,DPTZ[abhlw|  BC  JU     ,/ / / /"
* 
* 
* 
*z z z z, , , ,"	1 	1 	1 	1
* 
* 
* 
*H H H H     r   