With valuation now preserving more decimal digits, roi could show
excessively precise decimals if there was no known display precision
for the valuation commodity. Now in that situation it limits the
precision to a maximum of 8 digits.
This and the preceding commits were "work in progress" that got out of control.
There's more to do, but this one brings these precision-related improvements
(at least):
When "infinite decimals" arise, they are now generally shown with
8 decimal digits rather than 255.
print and prices no longer add trailing decimal zeros unnecessarily.
Some code has been refactored or given more debug output.
All tests have been updated to match the recent changes.
- The prices comand now more accurately lists the prices that hledger
uses when calculating value reports (similar to what you'd see with
eg `hledger bal -V --debug=2`).
- The prices command's --infer-reverse-prices flag was confusing since
we always infer and use reverse prices; it has been renamed to --show-reverse.
- --infer-market-prices and --show-reverse combine properly.
- --show-reverse now ignores all zero prices rather than giving an error.
- Reverse prices (which can be infinite decimals) are now displayed
with at most 8 decimal digits (rather than the internal precision of
255 digits).
- Filtering prices by cur: or amt: now works properly.
- Price amounts are styled, but all decimal digits are shown.
Cost/value conversion now applies the standard display style, and
sets the display precision equal to the internal decimal precision
(or 8 if the decimal appears to be infinite).
This means value reports and especially `print -V` now show amounts
with more accurate and standard style and precision.
New tests have been added describing and explaining various
style/precision behaviours in print cost/value reports.
Changes to enable more control of "rounding" behaviour
(ie, choosing display precisions for amounts).
This reverts 1.31's change of asprecision, making it a non-Maybe
again, and adds a new asrounding field providing more control over how
a target display precision is applied to existing amounts (two options
for now, more later). Functionality is in an interim state (reports do
no rounding).
Eg "1,000" (with , as a thousands separator and no decimal digits) is
now displayed with a decimal mark: "1,000.".
"1 000" (where space is a thousands separator) is less ambiguous,
but we do the same thing (eg "1 000.") for consistency, and also to
help disambiguate when forgetting to quote a numeric commodity symbol
(eg "1234 0" where 1234 is a symbol that should have been in double quotes).
This simplifies the code for styling amounts with or without precision.
But it complicates the semantics (Nothing is useful only when setting style).
Not sure if it's the best way.
print now shows zero posting amounts with their original commodity
symbol and the corresponding style (instead of stripping the symbol).
If an inferred amount has multiple zeroes in different commodities,
a posting is displayed for each of these.
Possible breaking changes:
showMixedAmountLinesB, showAmountB, showAmountPrice now preserve
commodityful zeroes when rendering. This is intended to improve print output,
but it seems possible it might also affect balance and register reports,
though our tests show no change in those.
Hledger.Utils.Debug's "trace or log" functions are now controlled as
follows: to enable logging, append ",logging" to the program name at
startup (using withProgName). This also works when running in GHCI.
And they log to PROGNAME.log, not debug.log.
All (hopefully) debug logging in the hledger packages is now "trace or
log" capable.
This means that hledger-ui should now log all debug output to
./hledger-ui.log, with none of it appearing on the console.
total prices. (#1813)
Also reduce duplication for inferring market prices (previously it was
done separately in both Hledger.Data.Journal and
Hledger.Cli.Commands.Prices), and remove *TotalPriceToUnitPrice
functions, since unit prices cannot represent all total prices.
Add a helper function numDigitsInt to get the number of digits in an
integer, which has a surprising number of ways to get it wrong.
Introduce --infer-equity option which will generate conversion postings.
--cost will override --infer-equity.
This means there will no longer be unbalanced transactions, but will be
offsetting conversion postings to balance things out. For example.
2000-01-01
a 1 AAA @@ 2 BBB
b -2 BBB
When converting to cost, this is treated the same as before.
When used with --infer-equity, this is now treated as:
2000-01-01
a 1 AAA
equity:conversion:AAA-BBB:AAA -1 AAA
equity:conversion:AAA-BBB:BBB 2 BBB
b -2 BBB
There is a new account type, Conversion/V, which is a subtype of Equity/E.
The first account declared with this type, if any, is used as the base account
for inferred equity postings in conversion transactions, overriding the default
"equity:conversion".
API changes:
Costing has been changed to ConversionOp with three options:
NoConversionOp, ToCost, and InferEquity.
The first correspond to the previous NoCost and Cost options, while the
third corresponds to the --infer-equity flag. This converts transactions with costs
(one or more transaction prices) to transactions with equity:conversion postings.
It is in ConversionOp because converting to cost with -B/--cost and inferring conversion
equity postings with --infer-equity are mutually exclusive.
Correspondingly, the cost_ record of ReportOpts has been changed to
conversionop_.
This also removes show_costs_ option in ReportOpts, as its functionality
has been replaced by the richer cost_ option.
This allows more control over how multicommodity amounts are displayed.
In addition to the default single-line display, and the recent commodity
column display, we now have multi-line display. This is controlled by
the --layout option, which has possible values "wide", "tall", and
"bare". The --commodity-column option has been hidden, but is equivalent
to --layout=bare.
squash
mixedAmount(Looks|Is)Zero now operate directly on the MixedAmount,
rather than converting them to a list of amounts first.
mixedAmountCost no longer reconstructs the entire MixedAmount when there
are amounts with no cost.
transactionCheckBalanced only checks if signs are okay if sums are not
okay. It also only traverses the list of postings once when picking real
and balanced virtual postings.
There are no modules which depend on Hledger.Data.Commodity which don't
also depend on Hledger.Data.Amount. Though Hledger.Data.Amount is a very
large module and might be broken up, Hledger.Data.Commodity only defines
three very small functions which are used, and so can be combined with
little cost.
We can't filter out empty commodity strings since that is a legitimate
group. Simultaneously, we should only include the empty commodity if it
is explicitly used (part of a posting) and not generated as part of
`Amounts.amounts`
This adds the `--commodity-column` option that displays each commodity
on a separate line and the commodities themselves as a separate column.
The initial design considerations are at
simonmichael.hledger.issues.1559
The single-period balance report with `--commodity-column` does not
interoperate with custom formats.
In Amount, aismultiplier is a boolean flag that will always be False,
except for in TMPostingRules, where it indicates whether the posting
rule is a multiplier. It is therefore unnecessary in the vast majority
of cases. This posting pulls this flag out of Amount and puts it into
TMPostingRule, so it is only kept around when necessary.
This changes the parsing of journals somewhat. Previously you could
include an * before an amount anywhere in a Journal, and it would
happily parse and set the aismultiplier flag true. This will now fail
with a parse error: * is now only acceptable before an amount within an
auto posting rule.
Any usage of the library in which the aismultiplier field is read or set
should be removed. If you truly need its functionality, you should
switch to using TMPostingRule.
This changes the JSON output of Amount, as it will no longer include
aismultiplier.
This change provides more predictable and intuitive behaviour when
using -S/--sort-amount with multiple commodities.
It implements a custom Ord (and Eq) instance for MixedAmount
which substitutes zero for any missing commodities.
As a consequence, all the ways of representing zero with a MixedAmount ([],
[A 0], [A 0, B 0, ...]) are now Eq-ual (==), whereas before they were
not. We have not been able to find anything broken by this change.
* imp: lib: Compare MixedAmounts by substituting zero for any missing commodities. (#1563)
* ;doc: Update docs for new multicommodity sort by amount rules.
instead of a list of Amounts. No longer export Mixed constructor, to
keep API clean (if you really need it, you can import it directly from
Hledger.Data.Types). We also ensure the JSON representation of
MixedAmount doesn't change: it is stored as a normalised list of
Amounts.
This commit improves performance. Here are some indicative results.
hledger reg -f examples/10000x1000x10.journal
- Maximum residency decreases from 65MB to 60MB (8% decrease)
- Total memory in use decreases from 178MiB to 157MiB (12% decrease)
hledger reg -f examples/10000x10000x10.journal
- Maximum residency decreases from 69MB to 60MB (13% decrease)
- Total memory in use decreases from 198MiB to 153MiB (23% decrease)
hledger bal -f examples/10000x1000x10.journal
- Total heap usage decreases from 6.4GB to 6.0GB (6% decrease)
- Total memory in use decreases from 178MiB to 153MiB (14% decrease)
hledger bal -f examples/10000x10000x10.journal
- Total heap usage decreases from 7.3GB to 6.9GB (5% decrease)
- Total memory in use decreases from 196MiB to 185MiB (5% decrease)
hledger bal -M -f examples/10000x1000x10.journal
- Total heap usage decreases from 16.8GB to 10.6GB (47% decrease)
- Total time decreases from 14.3s to 12.0s (16% decrease)
hledger bal -M -f examples/10000x10000x10.journal
- Total heap usage decreases from 108GB to 48GB (56% decrease)
- Total time decreases from 62s to 41s (33% decrease)
If you never directly use the constructor Mixed or pattern match against
it then you don't need to make any changes. If you do, then do the
following:
- If you really care about the individual Amounts and never normalise
your MixedAmount (for example, just storing `Mixed amts` and then
extracting `amts` as a pattern match, then use should switch to using
[Amount]. This should just involve removing the `Mixed` constructor.
- If you ever call `mixed`, `normaliseMixedAmount`, or do any sort of
amount arithmetic (+), (-), then you should replace the constructor
`Mixed` with the function `mixed`. To extract the list of Amounts, use
the function `amounts`.
- If you ever call `normaliseMixedAmountSquashPricesForDisplay`, you can
replace that with `mixedAmountStripPrices`. (N.B. this does something
slightly different from `normaliseMixedAmountSquashPricesForDisplay`,
but I don't think there's any use case for squashing prices and then
keeping the first of the squashed prices around. If you disagree let
me know.)
- Any remaining calls to `normaliseMixedAmount` can be removed, as that
is now the identity function.