imp: prices: clarify, fixes, improve semantics (precisiongeddon)
- 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.
This commit is contained in:
parent
50dc7bebb1
commit
c51d883162
@ -67,6 +67,7 @@ module Hledger.Data.Amount (
|
||||
amountLooksZero,
|
||||
divideAmount,
|
||||
multiplyAmount,
|
||||
invertAmount,
|
||||
-- ** styles
|
||||
amountstyle,
|
||||
canonicaliseAmount,
|
||||
@ -89,6 +90,7 @@ module Hledger.Data.Amount (
|
||||
showAmountDebug,
|
||||
showAmountWithoutPrice,
|
||||
amountSetPrecision,
|
||||
amountSetPrecisionMin,
|
||||
withPrecision,
|
||||
amountSetFullPrecision,
|
||||
amountSetFullPrecisionUpTo,
|
||||
@ -335,6 +337,10 @@ divideAmount n = transformAmount (/n)
|
||||
multiplyAmount :: Quantity -> Amount -> Amount
|
||||
multiplyAmount n = transformAmount (*n)
|
||||
|
||||
-- | Invert an amount (replace its quantity q with 1/q).
|
||||
invertAmount :: Amount -> Amount
|
||||
invertAmount a@Amount{aquantity=q} = a{aquantity=1/q}
|
||||
|
||||
-- | Is this amount negative ? The price is ignored.
|
||||
isNegativeAmount :: Amount -> Bool
|
||||
isNegativeAmount Amount{aquantity=q} = q < 0
|
||||
@ -375,6 +381,12 @@ withPrecision = flip amountSetPrecision
|
||||
amountSetPrecision :: AmountPrecision -> Amount -> Amount
|
||||
amountSetPrecision p a@Amount{astyle=s} = a{astyle=s{asprecision=p}}
|
||||
|
||||
-- | Ensure an amount's display precision is at least the given minimum precision.
|
||||
-- Always sets an explicit Precision.
|
||||
amountSetPrecisionMin :: Word8 -> Amount -> Amount
|
||||
amountSetPrecisionMin minp a = amountSetPrecision p a
|
||||
where p = Precision $ max minp (amountDisplayPrecision a)
|
||||
|
||||
-- | Increase an amount's display precision, if needed, to enough decimal places
|
||||
-- to show it exactly (showing all significant decimal digits, without trailing zeros).
|
||||
-- If the amount's display precision is unset, it will be treated as precision 0.
|
||||
@ -784,14 +796,12 @@ isNegativeMixedAmount m =
|
||||
_ -> Nothing -- multiple amounts with different signs
|
||||
|
||||
-- | Does this mixed amount appear to be zero when rendered with its display precision?
|
||||
-- i.e. does it have zero quantity with no price, zero quantity with a total price (which is also zero),
|
||||
-- and zero quantity for each unit price?
|
||||
-- See amountLooksZero.
|
||||
mixedAmountLooksZero :: MixedAmount -> Bool
|
||||
mixedAmountLooksZero (Mixed ma) = all amountLooksZero ma
|
||||
|
||||
-- | Is this mixed amount exactly zero, ignoring its display precision?
|
||||
-- i.e. does it have zero quantity with no price, zero quantity with a total price (which is also zero),
|
||||
-- and zero quantity for each unit price?
|
||||
-- See amountIsZero.
|
||||
mixedAmountIsZero :: MixedAmount -> Bool
|
||||
mixedAmountIsZero (Mixed ma) = all amountIsZero ma
|
||||
|
||||
|
||||
@ -203,8 +203,12 @@ amountValueAtDate priceoracle styles mto d a =
|
||||
-- The display precision will be that of nullamt (0).
|
||||
-- Now apply the standard display style for comm
|
||||
& styleAmounts styles
|
||||
-- and set the display precision to rate's (internal) precision
|
||||
-- and set the display precision to rate's internal precision
|
||||
-- XXX (unnormalised - don't strip trailing zeros) ?
|
||||
-- XXX valuation.test:8 why is it showing precision 1 ?
|
||||
& amountSetPrecision (Precision $ decimalPlaces $ normalizeDecimal rate)
|
||||
-- or at least 1, ensuring we show at least one decimal place.
|
||||
-- & amountSetPrecision (Precision $ max 1 (decimalPlaces $ normalizeDecimal rate))
|
||||
-- see also print-styles.test, valuation2.test
|
||||
|
||||
-- | Calculate the gain of each component amount, that is the difference
|
||||
@ -447,6 +451,8 @@ makePriceGraph alldeclaredprices allinferredprices d =
|
||||
,pgDefaultValuationCommodities=defaultdests
|
||||
}
|
||||
where
|
||||
-- XXX logic duplicated in Hledger.Cli.Commands.Prices.prices, keep synced
|
||||
|
||||
-- prices in effect on date d, either declared or inferred
|
||||
visibledeclaredprices = dbg9 "visibledeclaredprices" $ filter ((<=d).mpdate) alldeclaredprices
|
||||
visibleinferredprices = dbg9 "visibleinferredprices" $ filter ((<=d).mpdate) allinferredprices
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
{-# LANGUAGE TemplateHaskell #-}
|
||||
{-# LANGUAGE NamedFieldPuns #-}
|
||||
|
||||
module Hledger.Cli.Commands.Prices (
|
||||
pricesmode
|
||||
@ -7,78 +8,97 @@ module Hledger.Cli.Commands.Prices (
|
||||
)
|
||||
where
|
||||
|
||||
import qualified Data.Map as M
|
||||
import Data.List
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.IO as T
|
||||
import Hledger
|
||||
import Hledger.Cli.CliOptions
|
||||
import System.Console.CmdArgs.Explicit
|
||||
import Data.Maybe (mapMaybe)
|
||||
|
||||
pricesmode = hledgerCommandMode
|
||||
$(embedFileRelative "Hledger/Cli/Commands/Prices.txt")
|
||||
[flagNone ["infer-reverse-prices"] (setboolopt "infer-reverse-prices") "also show prices obtained by inverting transaction prices"
|
||||
[flagNone ["show-reverse"] (setboolopt "show-reverse")
|
||||
"also show the prices inferred by reversing known prices"
|
||||
]
|
||||
[generalflagsgroup1]
|
||||
(hiddenflags ++
|
||||
[flagNone ["costs"] (setboolopt "infer-market-prices") "deprecated, use --infer-market-prices instead"
|
||||
,flagNone ["inverted-costs"] (setboolopt "infer-reverse-prices") "deprecated, use --infer-reverse-prices instead"
|
||||
[flagNone ["costs"] (setboolopt "infer-market-prices") "deprecated, use --infer-market-prices instead"
|
||||
,flagNone ["inverted-costs"] (setboolopt "show-reverse") "deprecated, use --show-reverse instead"
|
||||
,flagNone ["infer-reverse-prices"] (setboolopt "show-reverse") "deprecated, use --show-reverse instead"
|
||||
])
|
||||
([], Just $ argsFlag "[QUERY]")
|
||||
|
||||
-- XXX the original hledger-prices script always ignored assertions
|
||||
instance HasAmounts PriceDirective where
|
||||
styleAmounts styles pd = pd{pdamount=styleAmounts styles $ pdamount pd}
|
||||
|
||||
-- List market prices.
|
||||
prices opts j = do
|
||||
let
|
||||
styles = journalCommodityStyles j
|
||||
q = _rsQuery $ reportspec_ opts
|
||||
ps = filter (matchesPosting q) $ allPostings j
|
||||
mprices = jpricedirectives j
|
||||
cprices =
|
||||
map (stylePriceDirectiveExceptPrecision styles) $
|
||||
concatMap postingPriceDirectivesFromCost ps
|
||||
rcprices =
|
||||
map (stylePriceDirectiveExceptPrecision styles) $
|
||||
concatMap (postingPriceDirectivesFromCost . postingTransformAmount (mapMixedAmount invertPrice))
|
||||
ps
|
||||
allprices =
|
||||
mprices
|
||||
++ ifBoolOpt "infer-market-prices" cprices
|
||||
++ ifBoolOpt "infer-reverse-prices" rcprices -- TODO: shouldn't this show reversed P prices also ? valuation will use them
|
||||
styles = journalCommodityStyles j
|
||||
q = _rsQuery $ reportspec_ opts
|
||||
|
||||
mapM_ (T.putStrLn . showPriceDirective) $
|
||||
sortOn pddate $
|
||||
filter (matchesPriceDirective q) $
|
||||
allprices
|
||||
-- XXX duplicates logic in Hledger.Data.Valuation.makePriceGraph, keep synced
|
||||
|
||||
declaredprices =
|
||||
-- dbg0 "declaredprices" $
|
||||
jpricedirectives j
|
||||
|
||||
pricesfromcosts =
|
||||
-- dbg0 "pricesfromcosts" $
|
||||
concatMap postingPriceDirectivesFromCost $
|
||||
journalPostings j
|
||||
|
||||
forwardprices =
|
||||
-- dbg0 "forwardprices" $
|
||||
if boolopt "infer-market-prices" (rawopts_ opts)
|
||||
then declaredprices `mergePriceDirectives` pricesfromcosts
|
||||
else declaredprices
|
||||
|
||||
reverseprices =
|
||||
-- dbg0 "reverseprices" $
|
||||
mapMaybe reversePriceDirective forwardprices
|
||||
|
||||
allprices =
|
||||
-- dbg0 "allprices" $
|
||||
if boolopt "show-reverse" (rawopts_ opts)
|
||||
then forwardprices `mergePriceDirectives` reverseprices
|
||||
else forwardprices
|
||||
|
||||
filteredprices =
|
||||
-- dbg0 "filtered unsorted" $
|
||||
filter (matchesPriceDirective q) allprices
|
||||
|
||||
mapM_ (T.putStrLn . showPriceDirective . styleAmounts styles) $
|
||||
sortOn pddate filteredprices
|
||||
|
||||
-- XXX performance
|
||||
-- | Append any new price directives (with different from commodity,
|
||||
-- to commodity, or date) from the second list to the first.
|
||||
-- (Does not remove redundant prices from the first; just avoids adding more.)
|
||||
mergePriceDirectives :: [PriceDirective] -> [PriceDirective] -> [PriceDirective]
|
||||
mergePriceDirectives pds1 pds2 =
|
||||
pds1 ++ [ pd | pd <- pds2 , pdid pd `notElem` pds1ids ]
|
||||
where
|
||||
ifBoolOpt opt | boolopt opt $ rawopts_ opts = id
|
||||
| otherwise = const []
|
||||
pds1ids = map pdid pds1
|
||||
pdid PriceDirective{pddate,pdcommodity,pdamount} = (pddate, pdcommodity, acommodity pdamount)
|
||||
|
||||
showPriceDirective :: PriceDirective -> T.Text
|
||||
showPriceDirective mp = T.unwords ["P", T.pack . show $ pddate mp, quoteCommoditySymbolIfNeeded $ pdcommodity mp, wbToText . showAmountB noColour{displayZeroCommodity=True} $ pdamount mp]
|
||||
showPriceDirective mp = T.unwords [
|
||||
"P",
|
||||
T.pack . show $ pddate mp,
|
||||
quoteCommoditySymbolIfNeeded $ pdcommodity mp,
|
||||
wbToText . showAmountB noColour{displayZeroCommodity=True} $ pdamount mp
|
||||
]
|
||||
|
||||
-- XXX
|
||||
|
||||
-- | Invert an amount's price for --invert-cost, somehow ? Unclear.
|
||||
invertPrice :: Amount -> Amount
|
||||
invertPrice a =
|
||||
case aprice a of
|
||||
Nothing -> a
|
||||
Just (UnitPrice pa) -> invertPrice
|
||||
-- normalize to TotalPrice
|
||||
a { aprice = Just $ TotalPrice pa' } where
|
||||
pa' = ((1 / aquantity a) `divideAmount` pa) { aprice = Nothing }
|
||||
Just (TotalPrice pa) ->
|
||||
a { aquantity = aquantity pa * nonZeroSignum (aquantity a), acommodity = acommodity pa, aprice = Just $ TotalPrice pa' } where
|
||||
pa' = pa { aquantity = abs $ aquantity a, acommodity = acommodity a, aprice = Nothing, astyle = astyle a }
|
||||
where
|
||||
nonZeroSignum x = if x < 0 then -1 else 1
|
||||
|
||||
-- | Given a map of standard amount display styles, apply the
|
||||
-- appropriate one, if any, to this price directive's amount.
|
||||
-- But keep the number of decimal places unchanged.
|
||||
stylePriceDirectiveExceptPrecision :: M.Map CommoditySymbol AmountStyle -> PriceDirective -> PriceDirective
|
||||
stylePriceDirectiveExceptPrecision styles pd@PriceDirective{pdamount=a} =
|
||||
pd{pdamount = styleAmounts styles a}
|
||||
|
||||
allPostings :: Journal -> [Posting]
|
||||
allPostings = concatMap tpostings . jtxns
|
||||
-- | Convert a market price directive to a corresponding one in the
|
||||
-- opposite direction, if possible. (A price directive specifying zero
|
||||
-- as the price can't be reversed.)
|
||||
-- The display precision is set to show all significant decimal digits,
|
||||
-- up to a maximum of 8 (this is visible eg in the prices command's output).
|
||||
reversePriceDirective :: PriceDirective -> Maybe PriceDirective
|
||||
reversePriceDirective pd@PriceDirective{pdcommodity=c, pdamount=a}
|
||||
| amountIsZero a = Nothing
|
||||
| otherwise =
|
||||
Just pd{pdcommodity=acommodity a, pdamount=setprec $ invertAmount a{acommodity=c}}
|
||||
where setprec = amountSetFullPrecisionUpTo 8
|
||||
|
||||
@ -1,9 +1,17 @@
|
||||
## prices
|
||||
|
||||
Print [market price directives](https://hledger.org/hledger.html#market-prices) from the journal.
|
||||
With --infer-market-prices, generate additional market prices from [costs](https://hledger.org/hledger.html#costs).
|
||||
With --infer-reverse-prices, also generate market prices by inverting known prices.
|
||||
Prices can be filtered by a query.
|
||||
Price amounts are displayed with their full precision.
|
||||
Print the [market prices](hledger.md#p-directive) declared with P directives.
|
||||
With --infer-market-prices, also show any additional prices inferred from [costs](hledger.md#costs).
|
||||
With --show-reverse, also show additional prices inferred by reversing known prices.
|
||||
|
||||
Price amounts are always displayed with their full precision,
|
||||
except for reverse prices which are limited to 8 decimal digits.
|
||||
|
||||
Prices can be filtered by a date:, cur: or amt: query.
|
||||
|
||||
Generally if you run this command with --infer-market-prices --show-reverse,
|
||||
it will show the same prices used internally to calculate value reports.
|
||||
But if in doubt, you can inspect those directly by running the value report
|
||||
with --debug=2.
|
||||
|
||||
_FLAGS
|
||||
|
||||
@ -5231,9 +5231,7 @@ the `V` key always resets it to "end".)
|
||||
|
||||
To convert a commodity A to its market value in another commodity B,
|
||||
hledger looks for a suitable market price (exchange rate) as follows,
|
||||
in this order of preference
|
||||
<!-- (-X tries all of these; -V tries only 1) (really ?) -->
|
||||
:
|
||||
in this order of preference:
|
||||
|
||||
1. A *declared market price* or *inferred market price*:
|
||||
A's latest market price in B on or before the valuation date
|
||||
|
||||
@ -1,92 +1,119 @@
|
||||
# * prices command
|
||||
|
||||
# ** 1. by default only market prices are reported
|
||||
# ** 1. By default it lists market prices declared with P directives.
|
||||
# It shows them with their original precisions, ignoring commodity display styles.
|
||||
# Redundant P directives on the same date are shown (though only the last is used in value reports).
|
||||
<
|
||||
P 2016/1/1 EUR $1.06
|
||||
P 2016/2/1 EUR $1.05
|
||||
P 2023-01-01 B A10
|
||||
P 2023-01-01 B A100
|
||||
P 2023-01-01 A B100
|
||||
|
||||
2016/1/1 paycheck
|
||||
income:remuneration $-100
|
||||
income:donations $-15
|
||||
assets:bank
|
||||
2023-01-02
|
||||
(a) A2 @ B1
|
||||
|
||||
2016/1/2 spend
|
||||
expenses 20 EUR @ $1.07
|
||||
assets:bank
|
||||
$ hledger prices -f-
|
||||
P 2016-01-01 EUR $1.06
|
||||
P 2016-02-01 EUR $1.05
|
||||
2023-01-02
|
||||
(a) B1 @ A200
|
||||
|
||||
# ** 2. costs from postings can be included also
|
||||
<
|
||||
P 2016/1/1 EUR $1.06
|
||||
P 2016/2/1 EUR $1.05
|
||||
2023-01-03
|
||||
a B1
|
||||
b A-3
|
||||
|
||||
2016/1/1 paycheck
|
||||
income:remuneration $-100
|
||||
income:donations $-15
|
||||
assets:bank
|
||||
2023-01-04
|
||||
(a) B1 @@ A4
|
||||
|
||||
2016/1/2 spend
|
||||
expenses 20 EUR @ $1.07
|
||||
assets:bank
|
||||
2023-01-05
|
||||
(a) B-1 @@ A5
|
||||
|
||||
2016/1/3 spend
|
||||
expenses 20 EUR @@ $21.45
|
||||
assets:bank
|
||||
2023-01-06
|
||||
a B1
|
||||
b
|
||||
|
||||
2023-01-07
|
||||
(a) B1 @ A7
|
||||
|
||||
2016/1/4 spend
|
||||
expenses -20 EUR @@ $21.45
|
||||
assets:bank
|
||||
P 2023-01-07 B A70
|
||||
|
||||
$ hledger prices -f- -c A1.00
|
||||
P 2023-01-01 B A10
|
||||
P 2023-01-01 B A100
|
||||
P 2023-01-01 A B100
|
||||
P 2023-01-07 B A70
|
||||
|
||||
# ** 2. With --show-reverse it also lists any new prices inferred by inverting known prices.
|
||||
# Reverse prices are shown with all of their decimal digits up to a maximum of 8.
|
||||
# Redundant reverse prices are discarded.
|
||||
$ hledger prices -f- --show-reverse
|
||||
P 2023-01-01 B A10
|
||||
P 2023-01-01 B A100
|
||||
P 2023-01-01 A B100
|
||||
P 2023-01-07 B A70
|
||||
P 2023-01-07 A B0.01428571
|
||||
|
||||
# ** 3. With --infer-market-prices it also lists prices inferred from costs
|
||||
# (explicit or inferred, unit or total, positive or negative amounts).
|
||||
# Redundant prices inferred from costs are discarded.
|
||||
# ** XXX why precision 1 for 3/4/5 ?
|
||||
$ hledger prices -f- --infer-market-prices
|
||||
P 2016-01-01 EUR $1.06
|
||||
P 2016-01-02 EUR $1.07
|
||||
P 2016-01-03 EUR $1.0725
|
||||
P 2016-01-04 EUR $1.0725
|
||||
P 2016-02-01 EUR $1.05
|
||||
P 2023-01-01 B A10
|
||||
P 2023-01-01 B A100
|
||||
P 2023-01-01 A B100
|
||||
P 2023-01-02 A B1
|
||||
P 2023-01-02 B A200
|
||||
P 2023-01-03 B A3.0
|
||||
P 2023-01-04 B A4.0
|
||||
P 2023-01-05 B A5.0
|
||||
P 2023-01-07 B A70
|
||||
|
||||
# ** 3. inverted prices can be calculated
|
||||
# ** 4. --infer-market-prices and --show-reverse combine.
|
||||
$ hledger prices -f- --infer-market-prices --show-reverse
|
||||
P 2023-01-01 B A10
|
||||
P 2023-01-01 B A100
|
||||
P 2023-01-01 A B100
|
||||
P 2023-01-02 A B1
|
||||
P 2023-01-02 B A200
|
||||
P 2023-01-03 B A3.0
|
||||
P 2023-01-03 A B0.33333333
|
||||
P 2023-01-04 B A4.0
|
||||
P 2023-01-04 A B0.25
|
||||
P 2023-01-05 B A5.0
|
||||
P 2023-01-05 A B0.2
|
||||
P 2023-01-07 B A70
|
||||
P 2023-01-07 A B0.01428571
|
||||
|
||||
# ** 5. Prices can be filtered by a date: query.
|
||||
$ hledger prices -f- --infer-market-prices --show-reverse date:2023-01-01
|
||||
P 2023-01-01 B A10
|
||||
P 2023-01-01 B A100
|
||||
P 2023-01-01 A B100
|
||||
|
||||
# ** 6. Prices can be filtered by a cur: query.
|
||||
$ hledger prices -f- --infer-market-prices --show-reverse cur:A
|
||||
P 2023-01-01 A B100
|
||||
P 2023-01-02 A B1
|
||||
P 2023-01-03 A B0.33333333
|
||||
P 2023-01-04 A B0.25
|
||||
P 2023-01-05 A B0.2
|
||||
P 2023-01-07 A B0.01428571
|
||||
|
||||
# ** 7. Prices can be filtered by a amt: query.
|
||||
$ hledger prices -f- --infer-market-prices --show-reverse amt:100
|
||||
P 2023-01-01 B A100
|
||||
P 2023-01-01 A B100
|
||||
|
||||
# ** 8. Zero prices, which can't be reversed, are not reversed.
|
||||
<
|
||||
P 2016/1/1 EUR $1.06
|
||||
P 2016/2/1 EUR $1.05
|
||||
P 2021-10-16 B 0.0 A
|
||||
$ hledger -f- prices --show-reverse
|
||||
P 2021-10-16 B 0.0 A
|
||||
|
||||
2016/1/1 paycheck
|
||||
income:remuneration $-100
|
||||
income:donations $-15
|
||||
assets:bank
|
||||
|
||||
2016/1/3 spend
|
||||
expenses $21.45 @@ 20.00 EUR
|
||||
assets:bank
|
||||
$ hledger prices -f- --infer-reverse-prices
|
||||
P 2016-01-01 EUR $1.06
|
||||
P 2016-01-03 EUR $1.0725
|
||||
P 2016-02-01 EUR $1.05
|
||||
|
||||
#
|
||||
# ** 9. Zero postings, which can't determine a price, are ignored.
|
||||
<
|
||||
commodity 1.000,00 A
|
||||
2021-10-16
|
||||
(b) 0 A @@ 1 B
|
||||
|
||||
P 2019-01-01 X A1000,123
|
||||
P 2019-01-02 X A1000,1
|
||||
|
||||
2019-02-01
|
||||
(a) X1 @ A1000,2345
|
||||
2019-02-02
|
||||
(a) X1 @ A1000,2
|
||||
|
||||
# ** 4. Commodity styles are applied, but precision is left unchanged.
|
||||
$ hledger -f- prices
|
||||
P 2019-01-01 X 1.000,123 A
|
||||
P 2019-01-02 X 1.000,1 A
|
||||
|
||||
# ** 5. Commodity styles aren't yet applied to prices inferred from transaction prices.
|
||||
$ hledger -f- prices --infer-market-prices
|
||||
P 2019-01-01 X 1.000,123 A
|
||||
P 2019-01-02 X 1.000,1 A
|
||||
P 2019-02-01 X 1.000,2345 A
|
||||
P 2019-02-02 X 1.000,2 A
|
||||
|
||||
# ** 10. Inferring prices should play well with balance assertions mixing prices and no prices. (#1736)
|
||||
<
|
||||
;; Total asset value should be 400 USD + 1000 USD = 1400 USD
|
||||
2021-10-15 Broker initial balance (equity ABC)
|
||||
@ -97,22 +124,47 @@ P 2019-02-02 X 1.000,2 A
|
||||
Assets:Broker = 1000 USD
|
||||
Equity:Opening Balances
|
||||
|
||||
# ** 6. Inferring prices should play well with balance assertions involving mixing
|
||||
# of prices and no prices. (#1736)
|
||||
$ hledger -f- prices --infer-market-prices
|
||||
P 2021-10-15 ABC 100.0 USD
|
||||
|
||||
# ** 11. Commodity styles are applied to all price amounts, but their precision is left unchanged.
|
||||
<
|
||||
2021-10-15
|
||||
(a) 1 A @@ 0 B
|
||||
commodity 1.000,00 A
|
||||
|
||||
2021-10-16
|
||||
(b) 0 A @@ 1 B
|
||||
P 2019-01-01 X A1000,123
|
||||
P 2019-01-02 X A1000,1
|
||||
|
||||
# ** 7. Gracefully ignore any postings which would result in an infinite price.
|
||||
$ hledger -f- prices --infer-market-prices
|
||||
P 2021-10-15 A 0.0 B
|
||||
2019-02-01
|
||||
(a) X1 @ A1000,2345
|
||||
|
||||
2019-02-02
|
||||
(a) X1 @ A1000,2
|
||||
|
||||
2019-03-01
|
||||
(a) 20 EUR @ $1.07
|
||||
|
||||
$ hledger -f- prices --infer-market-prices --show-reverse
|
||||
P 2019-01-01 X 1.000,123 A
|
||||
P 2019-01-01 A X0.00099988
|
||||
P 2019-01-02 X 1.000,1 A
|
||||
P 2019-01-02 A X0.00099990
|
||||
P 2019-02-01 X 1.000,2345 A
|
||||
P 2019-02-01 A X0.00099977
|
||||
P 2019-02-02 X 1.000,2 A
|
||||
P 2019-02-02 A X0.00099980
|
||||
P 2019-03-01 EUR $1.07
|
||||
P 2019-03-01 $ 0.93457944 EUR
|
||||
|
||||
# ** 12. Reverse market prices are shown with all decimal digits, up to a maximum of 8.
|
||||
# ** XXX does this prevent displaying more precise prices ?
|
||||
<
|
||||
P 2023-01-01 B 3A
|
||||
|
||||
2023-01-01
|
||||
a 1A
|
||||
b
|
||||
|
||||
$ hledger -f - prices --show-reverse
|
||||
P 2023-01-01 B 3A
|
||||
P 2023-01-01 A 0.33333333B
|
||||
|
||||
# ** 8. Same for reverse prices
|
||||
$ hledger -f- prices --infer-reverse-prices
|
||||
P 2021-10-16 B 0.0 A
|
||||
|
||||
Loading…
Reference in New Issue
Block a user