lib: support -X/--exchange (direct/reverse prices only) (#131)
This commit is contained in:
		
							parent
							
								
									50a52dd467
								
							
						
					
					
						commit
						e24c6292d0
					
				| @ -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. | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
| @ -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. | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user