lib: support -X/--exchange (direct/reverse prices only) (#131)

This commit is contained in:
Simon Michael 2019-06-01 16:12:20 -07:00
parent 50a52dd467
commit e24c6292d0
3 changed files with 71 additions and 62 deletions

View File

@ -334,14 +334,15 @@ reportOptsToggleStatus s ropts@ReportOpts{statuses_=ss}
| otherwise = ropts{statuses_=simplifyStatuses (s:ss)} | otherwise = ropts{statuses_=simplifyStatuses (s:ss)}
-- | Parse the type of valuation to be performed, if any, specified by -- | Parse the type of valuation to be performed, if any, specified by
-- -B/--cost/-V/--value flags. If there's more than one of these, the -- -B/--cost, -V, -X/--exchange, or --value flags. If there's more
-- rightmost flag wins. -- than one of these, the rightmost flag wins.
valuationTypeFromRawOpts :: RawOpts -> Maybe ValuationType valuationTypeFromRawOpts :: RawOpts -> Maybe ValuationType
valuationTypeFromRawOpts = lastDef Nothing . filter isJust . map valuationfromrawopt valuationTypeFromRawOpts = lastDef Nothing . filter isJust . map valuationfromrawopt
where where
valuationfromrawopt (n,v) -- option name, value valuationfromrawopt (n,v) -- option name, value
| n == "B" = Just $ AtCost Nothing | n == "B" = Just $ AtCost Nothing
| n == "V" = Just $ AtDefault Nothing | n == "V" = Just $ AtDefault Nothing
| n == "X" = Just $ AtDefault (Just $ T.pack v)
| n == "value" = Just $ valuation v | n == "value" = Just $ valuation v
| otherwise = Nothing | otherwise = Nothing
valuation v valuation v
@ -353,12 +354,18 @@ valuationTypeFromRawOpts = lastDef Nothing . filter isJust . map valuationfromra
Just d -> AtDate d mc Just d -> AtDate d mc
Nothing -> usageError $ "could not parse \""++t++"\" as valuation type, should be: cost|end|now|c|e|n|YYYY-MM-DD" Nothing -> usageError $ "could not parse \""++t++"\" as valuation type, should be: cost|end|now|c|e|n|YYYY-MM-DD"
where where
-- parse TYPE[,COMM] -- parse --value's value: TYPE[,COMM]
(t,c') = break (==',') v (t,c') = break (==',') v
mc = case drop 1 c' of mc = case drop 1 c' of
"" -> Nothing "" -> Nothing
c -> Just $ T.pack c c -> Just $ T.pack c
valuationTypeIsCost :: ReportOpts -> Bool
valuationTypeIsCost ropts =
case value_ ropts of
Just (AtCost _) -> True
_ -> False
type DisplayExp = String type DisplayExp = String
maybedisplayopt :: Day -> RawOpts -> Maybe DisplayExp maybedisplayopt :: Day -> RawOpts -> Maybe DisplayExp
@ -390,12 +397,6 @@ flat_ = (==ALFlat) . accountlistmode_
-- depthFromOpts :: ReportOpts -> Int -- depthFromOpts :: ReportOpts -> Int
-- depthFromOpts opts = min (fromMaybe 99999 $ depth_ opts) (queryDepth $ queryFromOpts nulldate opts) -- depthFromOpts opts = min (fromMaybe 99999 $ depth_ opts) (queryDepth $ queryFromOpts nulldate opts)
valuationTypeIsCost :: ReportOpts -> Bool
valuationTypeIsCost ropts =
case value_ ropts of
Just (AtCost _) -> True
_ -> False
-- | Convert this journal's postings' amounts to cost using their -- | Convert this journal's postings' amounts to cost using their
-- transaction prices, if specified by options (-B/--value=cost). -- transaction prices, if specified by options (-B/--value=cost).
-- Maybe soon superseded by newer valuation code. -- Maybe soon superseded by newer valuation code.

View File

@ -154,29 +154,28 @@ reportflags = [
-- valuation -- valuation
,flagNone ["B","cost"] (setboolopt "B") ,flagNone ["B","cost"] (setboolopt "B")
"show amounts converted to cost commodity, same as --value=cost" "show amounts converted to their cost, using the transaction price. Equivalent to --value=cost."
,flagNone ["V","market"] (setboolopt "V") ,flagNone ["V","market"] (setboolopt "V")
(unwords (unwords
["show amounts converted to default valuation commodity," ["show amounts converted to current market value (single period reports)"
,"same as --value=now (single period reports)" ,"or period-end market value (multiperiod reports) in their default valuation commodity."
,"or --value=end (multiperiod reports)" -- TODO ,"Equivalent to --value=now / --value=end."
])
,flagReq ["X","exchange"] (\s opts -> Right $ setopt "X" s opts) "COMM"
(unwords
["show amounts converted to current (single period reports)"
,"or period-end (multiperiod reports) market value in the specified commodity."
,"Equivalent to --value=now,COMM / --value=end,COMM."
]) ])
-- TODO: -X
-- ,flagReq ["X"] (\s opts -> Right $ setopt "X" s opts) "COMM"
-- (unwords
-- ["show amounts converted to this commodity"
-- ,"same as --value=now,COMM (single period reports)"
-- ,"or --value=end,COMM (multiperiod reports)"
-- ])
,flagReq ["value"] (\s opts -> Right $ setopt "value" s opts) "TYPE[,COMM]" ,flagReq ["value"] (\s opts -> Right $ setopt "value" s opts) "TYPE[,COMM]"
(unlines (unlines
["TYPE is cost, end, now or YYYY-MM-DD." ["TYPE is cost, end, now or YYYY-MM-DD."
,"COMM is an optional commodity symbol." ,"COMM is an optional commodity symbol."
,"Shows amounts converted to:" ,"Shows amounts converted to:"
,"- cost commodity using transaction prices (then optionally to COMM using market prices at period end(s))" ,"- cost using transaction prices, then optionally to COMM using period-end market prices"
,"- default valuation commodity (or COMM) using market prices at period end(s)" ,"- period-end market value, in default valuation commodity or COMM"
,"- default valuation commodity (or COMM) using current market prices" ,"- current market value, in default valuation commodity or COMM"
,"- default valuation commodity (or COMM) using market prices at some date" ,"- market value on the given date, in default valuation commodity or COMM"
]) ])
-- generated postings/transactions -- generated postings/transactions

View File

@ -443,22 +443,32 @@ $ hledger balance --pivot member acct:.
-2 EUR -2 EUR
``` ```
## Cost ## Valuation
The `-B/--cost` flag converts amounts to their cost at transaction time, ### -B: Cost
The `-B/--cost` flag converts amounts to their cost (or selling price) at transaction time,
if they have a [transaction price](/journal.html#transaction-prices) specified. if they have a [transaction price](/journal.html#transaction-prices) specified.
This flag is equivalent to `--value=cost`, described below. This flag is equivalent to `--value=cost`, described below.
## Market value ### -V: Market value
The `-V/--market` flag converts reported amounts to their market value in another commodity. The `-V/--market` flag converts reported amounts to their market value in a default valuation commodity,
It uses the default valuation commodity referenced in the latest [market price](journal.html#market-prices) (P directive) using the [historical market prices](journal.html#market-prices) in effect on a default valuation date.
dated on or before the default valuation date, which is:
- today for single period reports (equivalent to `--value=now`) For single period reports, the valuation date is today.
- the end of each subperiod for multiperiod reports, ie reports with a [report interval](#report-intervals) (equivalent to `--value=end`). For [multiperiod reports](#report-intervals), it is the last day of each subperiod.
A quick example of `-V`: The valuation commodity will be the one referenced in the latest
applicable market price dated on or before the valuation date.
If most of your P declarations lead to a single home currency, this will usually be what you want.
`-V/--market` is similar to the same flag in Ledger, except
unlike Ledger it does not infer market prices from [transaction prices](/manual.html#transaction-prices).
(Mnemonic: in hledger, -B uses transaction prices, -V and -X use market prices.)
It is equivalent to `--value=now` or `--value=end`.
Here's a quick example:
```journal ```journal
# one euro is worth this many dollars from nov 1 # one euro is worth this many dollars from nov 1
@ -488,15 +498,18 @@ $ hledger -f t.j bal -N euros -V
$103.00 assets:euros $103.00 assets:euros
``` ```
Ledger users: Ledger's -V also infers market prices from journal entries, ### -X: Market value in specified commodity
but we don't do that. hledger's -V uses only market prices declared explicitly, with P directives.
(Mnemonic: -B/--cost uses transaction prices, -V/--market uses market prices.)
### More control over valuation The `-X/--exchange` option is like `-V/--market` except it takes a
commodity symbol argument, so that you can select a different target commodity.
It is similar to the same option in Ledger, with the same caveat mentioned for `-V`/`--value` above.
It is equivalent to `--value=now,COMM` or `--value=end,COMM`; for more details, read on.
### --value
*(experimental, added 201905)* *(experimental, added 201905)*
You can control valuation more precisely with the `--value` option: `-B`, `-V` and `-X` are special cases of the more general `--value` option:
--value=TYPE[,COMM] TYPE is cost, end, now or YYYY-MM-DD. --value=TYPE[,COMM] TYPE is cost, end, now or YYYY-MM-DD.
COMM is an optional commodity symbol. COMM is an optional commodity symbol.
@ -506,20 +519,21 @@ You can control valuation more precisely with the `--value` option:
- default valuation commodity (or COMM) using current market prices - default valuation commodity (or COMM) using current market prices
- default valuation commodity (or COMM) using market prices at some date - default valuation commodity (or COMM) using market prices at some date
TYPE is one of the keywords shown, or their first letter, or a date #### Valuation type
(which must be 8 digits with `-` or `/` or `.` separators).
Here they are in more detail:
`--value=cost` (or `c`) TYPE is one of these keywords, or their first letter, or a date (which
must be 8 digits with `-` or `/` or `.` separators):
`--value=cost`
: Convert amounts to cost, using the prices recorded in transactions. : Convert amounts to cost, using the prices recorded in transactions.
`-B`/`--cost` is equivalent to this. `-B`/`--cost` is equivalent to this.
`--value=end` (or `e`) `--value=end`
: Convert amounts to their value in default valuation commodity using market prices : Convert amounts to their value in default valuation commodity using market prices
on the last day of the report period (or of each subperiod in a multiperiod report). on the last day of the report period (or of each subperiod in a multiperiod report).
When no report period is specified, uses the journal's last transaction date. When no report period is specified, uses the journal's last transaction date.
`--value=now` (or `n`) `--value=now`
: Convert amounts to their value in default valuation commodity using current market prices : Convert amounts to their value in default valuation commodity using current market prices
(as of when report is generated). `-V`/`--market` is equivalent to this. (as of when report is generated). `-V`/`--market` is equivalent to this.
@ -527,17 +541,20 @@ Here they are in more detail:
: Convert amounts to their value in default valuation commodity using market prices : Convert amounts to their value in default valuation commodity using market prices
on this date. Eg `--value=2019-04-25`. on this date. Eg `--value=2019-04-25`.
#### Valuation commodity
The default valuation commodity is the commodity mentioned in the most The default valuation commodity is the commodity mentioned in the most
recent applicable market price declaration. When all your price recent applicable market price declaration. When all your price
declarations lead to a single home currency, that will be the default declarations lead to a single home currency, this will usually do what
valuation currency, which is generally what you want. you want.
To select a different valuation currency, you can write a comma and To select a different valuation commodity: write the commodity symbol
the commodity symbol after the valuation type above. after the valuation type, separated by a comma (eg: **`--value=now,EUR`**).
<!-- This is like the `-X`/`--exchange` flag. --> Currently this will only use market prices leading directly from A to
Note this does not yet follow chains of market prices; B, or (after inverting them) prices from B to A;
it can only use market prices leading directly from A to B, it does not yet follow chains of market prices.
or prices from B to A (which will be inverted).
#### --value examples
Here are the effects of `--value` as seen with `print`: Here are the effects of `--value` as seen with `print`:
@ -624,7 +641,7 @@ $ hledger -f- print --value=2000-01-15
``` ```
### Effect of --value on reports #### Effect of --value on reports
Below is how `--value` affects each of hledger's reports, currently. Below is how `--value` affects each of hledger's reports, currently.
You're not expected to remember all this, but when troubleshooting a report, look here. You're not expected to remember all this, but when troubleshooting a report, look here.
@ -649,15 +666,7 @@ messages being printed - please report them (with reproducible examples) eg at
| budget amounts with --budget | costs of budget amounts | budget-setting periodic txns are valued at period end | budget-setting periodic txns are valued at DATE | | budget amounts with --budget | costs of budget amounts | budget-setting periodic txns are valued at period end | budget-setting periodic txns are valued at DATE |
| column/row/grand totals/averages | sum/average of the displayed values | market value at period end of sum/average of postings | market value at DATE of sum/average of postings | | column/row/grand totals/averages | sum/average of the displayed values | market value at period end of sum/average of postings | market value at DATE of sum/average of postings |
### Some useful value reports ### Combining -B, -V, -X, --value
Here are some probably useful reports, please send suggestions if you find more:
| Command: | Description of report: | Could answer: |
|---------------------------|----------------------------------------------------|--------------------------------------------------|
| `hledger bs -M --value=e` | Monthly historical value of assets/liabilities | How are my investments performing ? |
### Combining -B, -V, --value
The rightmost of these flags wins. The rightmost of these flags wins.