diff --git a/hledger/Hledger/Cli/Commands/Roi.hs b/hledger/Hledger/Cli/Commands/Roi.hs index a69dd3dc8..b4d839ab1 100644 --- a/hledger/Hledger/Cli/Commands/Roi.hs +++ b/hledger/Hledger/Cli/Commands/Roi.hs @@ -176,7 +176,7 @@ timeWeightedReturn showCashFlow prettyTables investmentsQuery trans mixedAmountV -- one for the given date, by construction. zeroUnitsNeedsCashflowAtTheFront $ sort - $ dailyCashflows ++ datedPnls + $ datedCashflows ++ datedPnls where zeroUnitsNeedsCashflowAtTheFront changes = if initialUnits > 0 then changes @@ -185,16 +185,18 @@ timeWeightedReturn showCashFlow prettyTables investmentsQuery trans mixedAmountV (firstCashflow, rest') = splitAt 1 rest in firstCashflow ++ leadingPnls ++ rest' - datedPnls = map (\(date,amt) -> (date,Left $ maNegate amt)) pnl + datedPnls = map (second Left) $ aggregateByDate pnl - dailyCashflows = + datedCashflows = map (second Right) $ aggregateByDate cashFlow + + aggregateByDate datedAmounts = + -- Aggregate all entries for a single day, assuming that intraday interest is negligible sort - -- Aggregate all entries for a single day, assuming that intraday interest is negligible - $ map (\date_cash -> let (dates, cash) = unzip date_cash in (head dates, Right (maSum cash))) + $ map (\date_cash -> let (dates, cash) = unzip date_cash in (head dates, maSum cash)) $ groupBy ((==) `on` fst) $ sortOn fst $ map (second maNegate) - $ cashFlow + $ datedAmounts let units = tail $ @@ -216,7 +218,9 @@ timeWeightedReturn showCashFlow prettyTables investmentsQuery trans mixedAmountV $ dbg3 "changes" changes let finalUnitBalance = if null units then initialUnits else let (_,_,_,u) = last units in u - finalUnitPrice = if finalUnitBalance == 0 then initialUnitPrice + finalUnitPrice = if finalUnitBalance == 0 then + if null units then initialUnitPrice + else let (_,_,lastUnitPrice,_) = last units in lastUnitPrice else (unMix valueAfter) / finalUnitBalance -- Technically, totalTWR should be (100*(finalUnitPrice - initialUnitPrice) / initialUnitPrice), but initalUnitPrice is 100, so 100/100 == 1 totalTWR = roundTo 2 $ (finalUnitPrice - initialUnitPrice) diff --git a/hledger/test/roi.test b/hledger/test/roi.test index 237d68a5e..dfc1dcfdd 100644 --- a/hledger/test/roi.test +++ b/hledger/test/roi.test @@ -255,11 +255,11 @@ hledger -f- roi -p 2019-11 --inv Investment --pnl PnL --cost --value=then,A --in Assets:Checking 101 A Unrealized PnL >>> -+---++------------+------------++---------------+----------+-------------+-----++----------+-------+ -| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR | -+===++============+============++===============+==========+=============+=====++==========+=======+ -| 1 || 2019-11-01 | 2019-11-30 || 0 | -1 A | 0 | 1 A || 3678.34% | 0.00% | -+---++------------+------------++---------------+----------+-------------+-----++----------+-------+ ++---++------------+------------++---------------+----------+-------------+-----++----------+--------+ +| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR | ++===++============+============++===============+==========+=============+=====++==========+========+ +| 1 || 2019-11-01 | 2019-11-30 || 0 | -1 A | 0 | 1 A || 3678.34% | 12.87% | ++---++------------+------------++---------------+----------+-------------+-----++----------+--------+ >>>=0 @@ -306,3 +306,42 @@ P 2021-01-01 $ 73.88 +---++------------+------------++---------------+----------+-------------+-----++---------+---------+ >>>=0 + +# 13. Several PnL transactions on a single date are aggregated together +hledger -f - roi --inv saving --pnl dividend +<<< +2010-01-01 A1 + savingA 100.00 € + checking + +2011-12-31 A2 + savingA 0.00 € + dividendA -8.00 € + checking + +2012-03-29 A3 + savingA -100.00 € + checking + +# ======================================== + +2010-01-01 B1 + savingB 100.00 € + checking + +2011-12-31 B2 + savingB 0.00 € + dividendB -8.00 € + checking + +2012-03-29 B3 + saving -100.00 € + checking +>>> ++---++------------+------------++---------------+----------+-------------+---------++-------+-------+ +| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR | ++===++============+============++===============+==========+=============+=========++=======+=======+ +| 1 || 2010-01-01 | 2012-03-29 || 0 | -16.00 € | 0 | 16.00 € || 3.52% | 3.49% | ++---++------------+------------++---------------+----------+-------------+---------++-------+-------+ + +>>>=0