From 588d0dfd26dd4f3d2a2a5fde1e77a1c7b04d73a3 Mon Sep 17 00:00:00 2001 From: Dmitry Astapov Date: Tue, 1 Aug 2023 14:39:53 +0100 Subject: [PATCH] fix:cli:roi: report TWR per period and overall TWR for multi-period reports (fix #2068) --- hledger/Hledger/Cli/Commands/Roi.hs | 114 +++++++++++++---------- hledger/test/roi.test | 138 ++++++++++++++-------------- 2 files changed, 133 insertions(+), 119 deletions(-) diff --git a/hledger/Hledger/Cli/Commands/Roi.hs b/hledger/Hledger/Cli/Commands/Roi.hs index 29834e7e8..810ab254a 100644 --- a/hledger/Hledger/Cli/Commands/Roi.hs +++ b/hledger/Hledger/Cli/Commands/Roi.hs @@ -89,65 +89,78 @@ roi CliOpts{rawopts_=rawopts, reportspec_=rspec@ReportSpec{_rsReportOpts=ReportO putStrLn "No relevant transactions found. Check your investments query" exitFailure - let spans = snd $ reportSpan filteredj rspec + let (fullPeriod, spans) = reportSpan filteredj rspec let priceDirectiveDates = dbg3 "priceDirectiveDates" $ map pddate $ jpricedirectives j - tableBody <- forM spans $ \spn@(DateSpan (Just begin) (Just end)) -> do - -- Spans are [begin,end), and end is 1 day after the actual end date we are interested in - let - b = fromEFDay begin - e = fromEFDay end - cashFlowApplyCostValue = map (\(d,amt) -> (d,mixedAmountValue e d amt)) + let processSpan (DateSpan Nothing _) = error "Undefined start of the period - will be unable to compute the rates of return" + processSpan (DateSpan _ Nothing) = error "Undefined end of the period - will be unable to compute the rates of return" + processSpan spn@(DateSpan (Just begin) (Just end)) = do + -- Spans are [begin,end), and end is 1 day after the actual end date we are interested in + let + b = fromEFDay begin + e = fromEFDay end + cashFlowApplyCostValue = map (\(d,amt) -> (d,mixedAmountValue e d amt)) - valueBefore = - mixedAmountValue e b $ - total trans (And [ investmentsQuery - , Date (DateSpan Nothing (Just begin))]) + valueBefore = + mixedAmountValue e b $ + total trans (And [ investmentsQuery + , Date (DateSpan Nothing (Just begin))]) - valueAfter = - mixedAmountValue e e $ - total trans (And [investmentsQuery - , Date (DateSpan Nothing (Just end))]) + valueAfter = + mixedAmountValue e e $ + total trans (And [investmentsQuery + , Date (DateSpan Nothing (Just end))]) - priceDates = dbg3 "priceDates" $ nub $ filter (spanContainsDate spn) priceDirectiveDates - cashFlow = - ((map (,nullmixedamt) priceDates)++) $ - cashFlowApplyCostValue $ - calculateCashFlow wd trans (And [ Not investmentsQuery - , Not pnlQuery - , Date spn ] ) + priceDates = dbg3 "priceDates" $ nub $ filter (spanContainsDate spn) priceDirectiveDates + cashFlow = + ((map (,nullmixedamt) priceDates)++) $ + cashFlowApplyCostValue $ + calculateCashFlow wd trans (And [ Not investmentsQuery + , Not pnlQuery + , Date spn ] ) + pnl = + cashFlowApplyCostValue $ + calculateCashFlow wd trans (And [ Not investmentsQuery + , pnlQuery + , Date spn ] ) - pnl = - cashFlowApplyCostValue $ - calculateCashFlow wd trans (And [ Not investmentsQuery - , pnlQuery - , Date spn ] ) + thisSpan = dbg3 "processing span" $ + OneSpan b e valueBefore valueAfter cashFlow pnl - thisSpan = dbg3 "processing span" $ - OneSpan b e valueBefore valueAfter cashFlow pnl + irr <- internalRateOfReturn showCashFlow prettyTables thisSpan + (periodTwr, annualizedTwr) <- timeWeightedReturn showCashFlow prettyTables investmentsQuery trans mixedAmountValue thisSpan + let cashFlowAmt = maNegate . maSum $ map snd cashFlow + let smallIsZero x = if abs x < 0.01 then 0.0 else x + return [ showDate b + , showDate (addDays (-1) e) + , T.pack $ showMixedAmount valueBefore + , T.pack $ showMixedAmount cashFlowAmt + , T.pack $ showMixedAmount valueAfter + , T.pack $ showMixedAmount (valueAfter `maMinus` (valueBefore `maPlus` cashFlowAmt)) + , T.pack $ printf "%0.2f%%" $ smallIsZero irr + , T.pack $ printf "%0.2f%%" $ smallIsZero periodTwr + , T.pack $ printf "%0.2f%%" $ smallIsZero annualizedTwr ] - irr <- internalRateOfReturn showCashFlow prettyTables thisSpan - twr <- timeWeightedReturn showCashFlow prettyTables investmentsQuery trans mixedAmountValue thisSpan - let cashFlowAmt = maNegate . maSum $ map snd cashFlow - let smallIsZero x = if abs x < 0.01 then 0.0 else x - return [ showDate b - , showDate (addDays (-1) e) - , T.pack $ showMixedAmount valueBefore - , T.pack $ showMixedAmount cashFlowAmt - , T.pack $ showMixedAmount valueAfter - , T.pack $ showMixedAmount (valueAfter `maMinus` (valueBefore `maPlus` cashFlowAmt)) - , T.pack $ printf "%0.2f%%" $ smallIsZero irr - , T.pack $ printf "%0.2f%%" $ smallIsZero twr ] + periodRows <- forM spans processSpan + totalRow <- processSpan fullPeriod + + let rowTitles = Tab.Group Tab.NoLine (map (Header . T.pack . show) (take (length periodRows) [1..])) + + let isSingleSpan = length spans == 1 let table = Table - (Tab.Group Tab.NoLine (map (Header . T.pack . show) (take (length tableBody) [1..]))) + (if isSingleSpan + then rowTitles + else Tab.Group Tab.SingleLine [ rowTitles, Tab.Group Tab.NoLine [ Header "Total" ]] + ) (Tab.Group Tab.DoubleLine [ Tab.Group Tab.SingleLine [Header "Begin", Header "End"] , Tab.Group Tab.SingleLine [Header "Value (begin)", Header "Cashflow", Header "Value (end)", Header "PnL"] - , Tab.Group Tab.SingleLine [Header "IRR", Header "TWR"]]) - tableBody + , Tab.Group Tab.SingleLine [Header "IRR"] + , Tab.Group Tab.SingleLine [Header "TWR/period", Header "TWR/year"]]) + (if isSingleSpan then periodRows else periodRows ++ [totalRow]) TL.putStrLn $ Tab.render prettyTables id id id table @@ -174,7 +187,7 @@ timeWeightedReturn showCashFlow prettyTables investmentsQuery trans mixedAmountV where zeroUnitsNeedsCashflowAtTheFront changes1 = if initialUnits > 0 then changes1 - else + else let (leadingEmptyCashFlows, rest) = span isEmptyCashflow changes1 (leadingPnls, rest') = span (isLeft . snd) rest (firstCashflow, rest'') = splitAt 1 rest' @@ -185,10 +198,10 @@ timeWeightedReturn showCashFlow prettyTables investmentsQuery trans mixedAmountV Left _ -> False datedPnls = map (second Left) $ aggregateByDate pnl - + datedCashflows = map (second Right) $ aggregateByDate cashFlow - aggregateByDate datedAmounts = + aggregateByDate datedAmounts = -- Aggregate all entries for a single day, assuming that intraday interest is negligible sort $ map (\date_cash -> let (dates, cash) = unzip date_cash in (head dates, maSum cash)) @@ -223,7 +236,8 @@ timeWeightedReturn showCashFlow prettyTables investmentsQuery trans mixedAmountV 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) - years = fromIntegral (diffDays end begin) / 365 :: Double + (startYear, _, _) = toGregorian begin + years = fromIntegral (diffDays end begin) / (if isLeapYear startYear then 366 else 365) :: Double annualizedTWR = 100*((1+(realToFrac totalTWR/100))**(1/years)-1) :: Double when showCashFlow $ do @@ -257,7 +271,7 @@ timeWeightedReturn showCashFlow prettyTables investmentsQuery trans mixedAmountV printf "Final unit price: %s/%s units = %s\nTotal TWR: %s%%.\nPeriod: %.2f years.\nAnnualized TWR: %.2f%%\n\n" (showMixedAmount valueAfter) (showDecimal finalUnitBalance) (showDecimal finalUnitPrice) (showDecimal totalTWR) years annualizedTWR - return annualizedTWR + return ((realToFrac totalTWR) :: Double, annualizedTWR) internalRateOfReturn showCashFlow prettyTables (OneSpan begin end valueBefore valueAfter cashFlow _pnl) = do let prefix = (begin, maNegate valueBefore) @@ -314,5 +328,3 @@ showDecimal :: Decimal -> String showDecimal d = if d == rounded then show d else show rounded where rounded = roundTo 2 d - - diff --git a/hledger/test/roi.test b/hledger/test/roi.test index 93a6d648c..6179e7e7f 100644 --- a/hledger/test/roi.test +++ b/hledger/test/roi.test @@ -8,11 +8,11 @@ assets:cash -$100 investment $ hledger -f- roi --inv investment --pnl pnl -b 2017 -e 2018 -Y -+---++------------+------------++---------------+----------+-------------+-----++-------+-------+ -| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR | -+===++============+============++===============+==========+=============+=====++=======+=======+ -| 1 || 2017-01-01 | 2017-12-31 || 0 | $200 | $200 | 0 || 0.00% | 0.00% | -+---++------------+------------++---------------+----------+-------------+-----++-------+-------+ ++---++------------+------------++---------------+----------+-------------+-----++-------++------------+----------+ +| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR || TWR/period | TWR/year | ++===++============+============++===============+==========+=============+=====++=======++============+==========+ +| 1 || 2017-01-01 | 2017-12-31 || 0 | $200 | $200 | 0 || 0.00% || 0.00% | 0.00% | ++---++------------+------------++---------------+----------+-------------+-----++-------++------------+----------+ >= 0 @@ -26,11 +26,11 @@ $ hledger -f- roi --inv investment --pnl pnl -b 2017 -e 2018 -Y investment = $112 pnl $ hledger -f- roi --inv investment --pnl pnl -b 2017 -e 2018 -Y -+---++------------+------------++---------------+----------+-------------+-----++--------+--------+ -| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR | -+===++============+============++===============+==========+=============+=====++========+========+ -| 1 || 2017-01-01 | 2017-12-31 || 0 | $100 | $112 | $12 || 12.00% | 12.00% | -+---++------------+------------++---------------+----------+-------------+-----++--------+--------+ ++---++------------+------------++---------------+----------+-------------+-----++--------++------------+----------+ +| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR || TWR/period | TWR/year | ++===++============+============++===============+==========+=============+=====++========++============+==========+ +| 1 || 2017-01-01 | 2017-12-31 || 0 | $100 | $112 | $12 || 12.00% || 12.00% | 12.00% | ++---++------------+------------++---------------+----------+-------------+-----++--------++------------+----------+ >= 0 @@ -89,11 +89,11 @@ $ hledger -f- roi --inv investment --pnl pnl -b 2017 -e 2018 -Y pnl $ hledger -f- roi --inv investment --pnl pnl -b 2017 -e 2018 -Y -+---++------------+------------++---------------+----------+-------------+-----++--------+--------+ -| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR | -+===++============+============++===============+==========+=============+=====++========+========+ -| 1 || 2017-01-01 | 2017-12-31 || 0 | $100 | $112 | $12 || 12.00% | 12.00% | -+---++------------+------------++---------------+----------+-------------+-----++--------+--------+ ++---++------------+------------++---------------+----------+-------------+-----++--------++------------+----------+ +| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR || TWR/period | TWR/year | ++===++============+============++===============+==========+=============+=====++========++============+==========+ +| 1 || 2017-01-01 | 2017-12-31 || 0 | $100 | $112 | $12 || 12.00% || 12.00% | 12.00% | ++---++------------+------------++---------------+----------+-------------+-----++--------++------------+----------+ >= 0 @@ -111,11 +111,11 @@ $ hledger -f- roi --inv investment --pnl pnl -b 2017 -e 2018 -Y investment = $220 pnl $ hledger -f- roi --inv investment --pnl pnl -b 2017 -e 2018 -Y -+---++------------+------------++---------------+----------+-------------+-----++--------+--------+ -| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR | -+===++============+============++===============+==========+=============+=====++========+========+ -| 1 || 2017-01-01 | 2017-12-31 || 0 | $200 | $220 | $20 || 12.72% | 10.00% | -+---++------------+------------++---------------+----------+-------------+-----++--------+--------+ ++---++------------+------------++---------------+----------+-------------+-----++--------++------------+----------+ +| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR || TWR/period | TWR/year | ++===++============+============++===============+==========+=============+=====++========++============+==========+ +| 1 || 2017-01-01 | 2017-12-31 || 0 | $200 | $220 | $20 || 12.72% || 10.00% | 10.00% | ++---++------------+------------++---------------+----------+-------------+-----++--------++------------+----------+ >= 0 @@ -133,11 +133,11 @@ $ hledger -f- roi --inv investment --pnl pnl -b 2017 -e 2018 -Y investment = $20 pnl $ hledger -f- roi --inv investment --pnl pnl -b 2017 -e 2018 -Y -+---++------------+------------++---------------+----------+-------------+-------++---------+---------+ -| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR | -+===++============+============++===============+==========+=============+=======++=========+=========+ -| 1 || 2017-01-01 | 2017-12-31 || 0 | $200 | $20 | $-180 || -95.73% | -90.00% | -+---++------------+------------++---------------+----------+-------------+-------++---------+---------+ ++---++------------+------------++---------------+----------+-------------+-------++---------++------------+----------+ +| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR || TWR/period | TWR/year | ++===++============+============++===============+==========+=============+=======++=========++============+==========+ +| 1 || 2017-01-01 | 2017-12-31 || 0 | $200 | $20 | $-180 || -95.73% || -90.00% | -90.00% | ++---++------------+------------++---------------+----------+-------------+-------++---------++------------+----------+ >= 0 @@ -163,14 +163,16 @@ $ hledger -f- roi --inv investment --pnl pnl -b 2017 -e 2018 -Y investment = $155 pnl $ hledger -f- roi --inv investment --pnl pnl -b 2017 -e 2018 -Q -+---++------------+------------++---------------+----------+-------------+-----++---------+---------+ -| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR | -+===++============+============++===============+==========+=============+=====++=========+=========+ -| 1 || 2017-01-01 | 2017-03-31 || 0 | $100 | $100 | 0 || 0.00% | 0.00% | -| 2 || 2017-04-01 | 2017-06-30 || $100 | 0 | $110 | $10 || 46.56% | 46.56% | -| 3 || 2017-07-01 | 2017-09-30 || $110 | $100 | $210 | 0 || 0.00% | 0.00% | -| 4 || 2017-10-01 | 2017-12-31 || $210 | $-50 | $155 | $-5 || -11.83% | -11.82% | -+---++------------+------------++---------------+----------+-------------+-----++---------+---------+ ++-------++------------+------------++---------------+----------+-------------+-----++---------++------------+----------+ +| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR || TWR/period | TWR/year | ++=======++============+============++===============+==========+=============+=====++=========++============+==========+ +| 1 || 2017-01-01 | 2017-03-31 || 0 | $100 | $100 | 0 || 0.00% || 0.00% | 0.00% | +| 2 || 2017-04-01 | 2017-06-30 || $100 | 0 | $110 | $10 || 46.56% || 10.00% | 46.56% | +| 3 || 2017-07-01 | 2017-09-30 || $110 | $100 | $210 | 0 || 0.00% || 0.00% | 0.00% | +| 4 || 2017-10-01 | 2017-12-31 || $210 | $-50 | $155 | $-5 || -11.83% || -3.12% | -11.82% | ++-------++------------+------------++---------------+----------+-------------+-----++---------++------------+----------+ +| Total || 2017-01-01 | 2017-12-31 || 0 | $150 | $155 | $5 || 3.64% || 6.56% | 6.56% | ++-------++------------+------------++---------------+----------+-------------+-----++---------++------------+----------+ >= 0 @@ -196,11 +198,11 @@ $ hledger -f- roi --inv investment --pnl pnl -b 2017 -e 2018 -Q investment = $155 pnl $ hledger -f- roi --inv investment --pnl pnl -b 2017-06 -e 2018 -+---++------------+------------++---------------+----------+-------------+-----++-------+--------+ -| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR | -+===++============+============++===============+==========+=============+=====++=======+========+ -| 1 || 2017-06-01 | 2017-12-31 || $100 | $50 | $155 | $5 || 5.24% | 11.45% | -+---++------------+------------++---------------+----------+-------------+-----++-------+--------+ ++---++------------+------------++---------------+----------+-------------+-----++-------++------------+----------+ +| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR || TWR/period | TWR/year | ++===++============+============++===============+==========+=============+=====++=======++============+==========+ +| 1 || 2017-06-01 | 2017-12-31 || $100 | $50 | $155 | $5 || 5.24% || 6.56% | 11.45% | ++---++------------+------------++---------------+----------+-------------+-----++-------++------------+----------+ >= 0 @@ -210,11 +212,11 @@ $ hledger -f- roi --inv investment --pnl pnl -b 2017-06 -e 2018 Assets:Checking 1 Income:Salary -1 $ hledger -f- roi -p 2019-11 -+---++------------+------------++---------------+----------+-------------+-----++-------+-------+ -| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR | -+===++============+============++===============+==========+=============+=====++=======+=======+ -| 1 || 2019-11-01 | 2019-11-30 || 0 | 0 | 0 | 0 || 0.00% | 0.00% | -+---++------------+------------++---------------+----------+-------------+-----++-------+-------+ ++---++------------+------------++---------------+----------+-------------+-----++-------++------------+----------+ +| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR || TWR/period | TWR/year | ++===++============+============++===============+==========+=============+=====++=======++============+==========+ +| 1 || 2019-11-01 | 2019-11-30 || 0 | 0 | 0 | 0 || 0.00% || 0.00% | 0.00% | ++---++------------+------------++---------------+----------+-------------+-----++-------++------------+----------+ >= 0 @@ -246,11 +248,11 @@ For example, "--cost --value=end, --infer-market-prices", where commo Assets:Checking 101 A Unrealized PnL $ hledger -f- roi -p 2019-11 --inv Investment --pnl PnL --cost --value=then,A --infer-market-prices -+---++------------+------------++---------------+----------+-------------+-----++----------+--------+ -| || 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% | -+---++------------+------------++---------------+----------+-------------+-----++----------+--------+ ++---++------------+------------++---------------+----------+-------------+-----++----------++------------+----------+ +| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR || TWR/period | TWR/year | ++===++============+============++===============+==========+=============+=====++==========++============+==========+ +| 1 || 2019-11-01 | 2019-11-30 || 0 | -1 A | 0 | 1 A || 3678.34% || 1.00% | 12.87% | ++---++------------+------------++---------------+----------+-------------+-----++----------++------------+----------+ >= 0 @@ -267,11 +269,11 @@ P 2021-01-01 $ 73.88 assets:investment =11000 income:investment $ hledger -f - roi --inv assets:investment --pnl income:investment --value=then,'$' -+---++------------+------------++---------------+----------+-------------+-----++---------+---------+ -| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR | -+===++============+============++===============+==========+=============+=====++=========+=========+ -| 1 || 2020-12-02 | 2021-01-02 || 0 | $131 | $149 | $18 || 321.99% | 321.81% | -+---++------------+------------++---------------+----------+-------------+-----++---------+---------+ ++---++------------+------------++---------------+----------+-------------+-----++---------++------------+----------+ +| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR || TWR/period | TWR/year | ++===++============+============++===============+==========+=============+=====++=========++============+==========+ +| 1 || 2020-12-02 | 2021-01-02 || 0 | $131 | $149 | $18 || 321.99% || 13.45% | 323.47% | ++---++------------+------------++---------------+----------+-------------+-----++---------++------------+----------+ >= 0 @@ -288,11 +290,11 @@ P 2021-01-01 $ 73.88 assets:investment =11000 income:investment $ hledger -f - roi --inv assets:investment --pnl income:investment --value=end,'$' -+---++------------+------------++---------------+----------+-------------+-----++---------+---------+ -| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR | -+===++============+============++===============+==========+=============+=====++=========+=========+ -| 1 || 2020-12-02 | 2021-01-02 || 0 | $135 | $149 | $14 || 196.58% | 196.58% | -+---++------------+------------++---------------+----------+-------------+-----++---------+---------+ ++---++------------+------------++---------------+----------+-------------+-----++---------++------------+----------+ +| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR || TWR/period | TWR/year | ++===++============+============++===============+==========+=============+=====++=========++============+==========+ +| 1 || 2020-12-02 | 2021-01-02 || 0 | $135 | $149 | $14 || 196.58% || 10.00% | 197.46% | ++---++------------+------------++---------------+----------+-------------+-----++---------++------------+----------+ >= 0 @@ -326,11 +328,11 @@ $ hledger -f - roi --inv assets:investment --pnl income:investment --value=end,' saving -100.00 € checking $ hledger -f - roi --inv saving --pnl dividend -+---++------------+------------++---------------+----------+-------------+---------++-------+-------+ -| || 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% | -+---++------------+------------++---------------+----------+-------------+---------++-------+-------+ ++---++------------+------------++---------------+----------+-------------+---------++-------++------------+----------+ +| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR || TWR/period | TWR/year | ++===++============+============++===============+==========+=============+=========++=======++============+==========+ +| 1 || 2010-01-01 | 2012-03-29 || 0 | -16.00 € | 0 | 16.00 € || 3.52% || 8.00% | 3.49% | ++---++------------+------------++---------------+----------+-------------+---------++-------++------------+----------+ >= 0 @@ -346,10 +348,10 @@ P 2022-07-31 A € 1 P 2022-08-02 A € 2 $ hledger -f - roi --inv stocks --pnl expenses --value=then,€ -Y -+---++------------+------------++---------------+----------+-------------+------++---------+--------+ -| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR | -+===++============+============++===============+==========+=============+======++=========+========+ -| 1 || 2022-01-01 | 2022-12-31 || 0 | € 101 | € 200 | € 99 || 410.31% | 98.02% | -+---++------------+------------++---------------+----------+-------------+------++---------+--------+ ++---++------------+------------++---------------+----------+-------------+------++---------++------------+----------+ +| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR || TWR/period | TWR/year | ++===++============+============++===============+==========+=============+======++=========++============+==========+ +| 1 || 2022-01-01 | 2022-12-31 || 0 | € 101 | € 200 | € 99 || 410.31% || 98.02% | 98.02% | ++---++------------+------------++---------------+----------+-------------+------++---------++------------+----------+ >= 0