mirror of
https://github.com/simonmichael/hledger.git
synced 2024-11-09 21:22:26 +03:00
roi: fix insane precision bug, discovered in #1417
This commit is contained in:
parent
db3fe16645
commit
14a3b9833c
@ -131,10 +131,10 @@ roi CliOpts{rawopts_=rawopts, reportspec_=rspec@ReportSpec{rsOpts=ReportOpts{..}
|
||||
let smallIsZero x = if abs x < 0.01 then 0.0 else x
|
||||
return [ showDate spanBegin
|
||||
, showDate (addDays (-1) spanEnd)
|
||||
, T.pack $ show valueBefore
|
||||
, T.pack $ show cashFlowAmt
|
||||
, T.pack $ show valueAfter
|
||||
, T.pack $ show (valueAfter - (valueBefore + cashFlowAmt))
|
||||
, T.pack $ showDecimal valueBefore
|
||||
, T.pack $ showDecimal cashFlowAmt
|
||||
, T.pack $ showDecimal valueAfter
|
||||
, T.pack $ showDecimal (valueAfter - (valueBefore + cashFlowAmt))
|
||||
, T.pack $ printf "%0.2f%%" $ smallIsZero irr
|
||||
, T.pack $ printf "%0.2f%%" $ smallIsZero twr ]
|
||||
|
||||
@ -193,7 +193,6 @@ timeWeightedReturn showCashFlow prettyTables investmentsQuery trans (OneSpan spa
|
||||
years = fromIntegral (diffDays spanEnd spanBegin) / 365 :: Double
|
||||
annualizedTWR = 100*((1+(realToFrac totalTWR/100))**(1/years)-1) :: Double
|
||||
|
||||
let s d = show $ roundTo 2 d
|
||||
when showCashFlow $ do
|
||||
printf "\nTWR cash flow for %s - %s\n" (showDate spanBegin) (showDate (addDays (-1) spanEnd))
|
||||
let (dates', amounts) = unzip changes
|
||||
@ -216,19 +215,19 @@ timeWeightedReturn showCashFlow prettyTables investmentsQuery trans (OneSpan spa
|
||||
, Tbl.Group SingleLine [Header "Pnl", Header "Cashflow", Header "Unit price", Header "Units"]
|
||||
, Tbl.Group SingleLine [Header "New Unit Balance"]])
|
||||
[ [value, oldBalance, pnl, cashflow, prc, udelta, balance]
|
||||
| value <- map s valuesOnDate
|
||||
| oldBalance <- map s (0:unitBalances)
|
||||
| balance <- map s unitBalances
|
||||
| pnl <- map s pnls
|
||||
| cashflow <- map s cashflows
|
||||
| prc <- map s unitPrices
|
||||
| udelta <- map s unitsBoughtOrSold ])
|
||||
| value <- map showDecimal valuesOnDate
|
||||
| oldBalance <- map showDecimal (0:unitBalances)
|
||||
| balance <- map showDecimal unitBalances
|
||||
| pnl <- map showDecimal pnls
|
||||
| cashflow <- map showDecimal cashflows
|
||||
| prc <- map showDecimal unitPrices
|
||||
| udelta <- map showDecimal unitsBoughtOrSold ])
|
||||
|
||||
printf "Final unit price: %s/%s units = %s\nTotal TWR: %s%%.\nPeriod: %.2f years.\nAnnualized TWR: %.2f%%\n\n" (s valueAfter) (s finalUnitBalance) (s finalUnitPrice) (s totalTWR) years annualizedTWR
|
||||
printf "Final unit price: %s/%s units = %s\nTotal TWR: %s%%.\nPeriod: %.2f years.\nAnnualized TWR: %.2f%%\n\n"
|
||||
(showDecimal valueAfter) (showDecimal finalUnitBalance) (showDecimal finalUnitPrice) (showDecimal totalTWR) years annualizedTWR
|
||||
|
||||
return annualizedTWR
|
||||
|
||||
|
||||
internalRateOfReturn showCashFlow prettyTables (OneSpan spanBegin spanEnd valueBefore valueAfter cashFlow _pnl) = do
|
||||
let prefix = (spanBegin, negate valueBefore)
|
||||
|
||||
@ -243,7 +242,7 @@ internalRateOfReturn showCashFlow prettyTables (OneSpan spanBegin spanEnd valueB
|
||||
(Table
|
||||
(Tbl.Group NoLine (map (Header . showDate) dates))
|
||||
(Tbl.Group SingleLine [Header "Amount"])
|
||||
(map ((:[]) . T.pack . show) amounts))
|
||||
(map ((:[]) . T.pack . showDecimal) amounts))
|
||||
|
||||
-- 0% is always a solution, so require at least something here
|
||||
case totalCF of
|
||||
@ -279,3 +278,11 @@ unMix a =
|
||||
Nothing -> error' $ "Amounts could not be converted to a single cost basis: " ++ show (map showAmount $ amounts a) ++
|
||||
"\nConsider using --value to force all costs to be in a single commodity." ++
|
||||
"\nFor example, \"--value cost,<commodity> --infer-value\", where commodity is the one that was used to pay for the investment."
|
||||
|
||||
-- Show Decimal rounded to two decimal places, unless it has less places already. This ensures that "2" won't be shown as "2.00"
|
||||
showDecimal :: Decimal -> String
|
||||
showDecimal d = if d == rounded then show d else show rounded
|
||||
where
|
||||
rounded = roundTo 2 d
|
||||
|
||||
|
||||
|
@ -262,3 +262,25 @@ hledger -f- roi -p 2019-11 --inv Investment --pnl PnL --value cost,A --infer-val
|
||||
+---++------------+------------++---------------+----------+-------------+-----++----------+-------+
|
||||
|
||||
>>>=0
|
||||
|
||||
# 11. Dont use crazy amount of decimal places
|
||||
hledger -f - roi --inv assets:investment --pnl income:investment -X '$'
|
||||
<<<
|
||||
P 2020-12-01 $ 76.20
|
||||
P 2021-01-01 $ 73.88
|
||||
|
||||
2020-12-02 invest
|
||||
assets:investment 10000
|
||||
assets
|
||||
|
||||
2021-01-02 get profit
|
||||
assets:investment =11000
|
||||
income:investment
|
||||
>>>
|
||||
+---++------------+------------++---------------+----------+-------------+-------++---------+---------+
|
||||
| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR |
|
||||
+===++============+============++===============+==========+=============+=======++=========+=========+
|
||||
| 1 || 2020-12-02 | 2021-01-02 || 0 | 135.35 | 148.89 | 13.54 || 196.58% | 196.58% |
|
||||
+---++------------+------------++---------------+----------+-------------+-------++---------+---------+
|
||||
|
||||
>>>=0
|
||||
|
Loading…
Reference in New Issue
Block a user