hledger
hledger copied to clipboard
Forecasting should start from the date of the last transaction, by default, not the date today
I have two journal files:
example_transactions.journalthat contains my "actuals"example_forecast.journalthat contains my future forecasted transactions
If I run the following command:
hledger -f $FINANCES/example_transactions.journal -f $FINANCES/example_forecast.journal --forecast --auto bal "^(ass|liab)" --tree -M --debug=2
I see the following output:
journalEndDate: Nothing
forecastspan: DateSpan 2023-06-07..2023-12-03
Balance changes in 2023-05-01..2023-12-31:
|| May Jun Jul Aug Sep Oct Nov Dec
====================++============================================================================
Assets:Wells Fargo || $1,425.00 $-58.00 $542.00 $542.00 $-2458.00 $513.00 $542.00 $600.00
--------------------++----------------------------------------------------------------------------
|| $1,425.00 $-58.00 $542.00 $542.00 $-2458.00 $513.00 $542.00 $600.00
Clearly the forecasting is starting from today (2023-06-07) and not at the date of the last transaction (2023-05-15).
Note: The $58 in June is because Hledger is multiplying the
Expenses:Datingtransaction by two in that period
example_transactions.journal
2023-05-01 Opening Balance
Assets:Wells Fargo $1,000.00
Equity:Opening Balance
2023-05-01 Salary
Income:Salary
Assets:Wells Fargo $3,000.00
2023-05-01 groceries
Expenses:Groceries
Assets:Wells Fargo -$200.00
2023-05-01 mortgage
Expenses:House:Mortgage
Assets:Wells Fargo -$1,800.00
2023-05-15 energy
Expenses:Energy
Assets:Wells Fargo -$500.00
2023-05-15 fuel
Expenses:Fuel
Assets:Wells Fargo -$75.00
example_forecast.journal
~ monthly from 2023-05-01 * Income - Salary, Mortgage, Groceries
Income:Salary -$3,000.00 ; Income - Salary
Expenses:House:Mortgage $1,800.00 ; Mortgage
Expenses:Groceries $600.00 ; Groceries
Assets:Wells Fargo
~ every 2 weeks from 2023-05-15 * Flowers for wife
Expenses:Dating $29.00 ; Flowers for wife
Assets:Wells Fargo
~ yearly from 2023-09-01 * Holidays
Expenses:Holidays $3,000.00 ; Holidays
Assets:Wells Fargo
= Expenses:Groceries date:2024-01-01..2024-12-31
Expenses:Groceries *0.05 ; Food - Inflation
Assets:Wells Fargo *-0.05
Ah, thanks for the example and report @olimorris. https://hledger.org/dev/hledger.html#forecast-period-in-detail is the reference doc:
Here are (with luck) the exact rules ... The forecast period starts on:
- the later of
- the start date in the periodic transaction rule
- the start date in --forecast's argument
- otherwise (if those are not available): the later of
- the report start date specified with -b/-p/date:
- the day after the latest ordinary transaction in the journal
- otherwise (if none of these are available): today.
while Hledger.Read.InputOptions.forecastPeriod 's comment says:
-- ... -- This begins on: -- - the start date supplied to the
--forecastargument, if present -- - otherwise, the later of -- - the report start date if specified with -b/-p/date: -- - the day after the latest normal (non-periodic) transaction in the journal, if any -- - otherwise today. -- ...
and the code is
forecastPeriod :: InputOpts -> Journal -> Maybe DateSpan
forecastPeriod iopts j = do
DateSpan requestedStart requestedEnd <- forecast_ iopts
let forecastStart = fromEFDay <$> requestedStart <|> max mjournalend (fromEFDay <$> reportStart) <|> Just (_ioDay iopts)
forecastEnd = fromEFDay <$> requestedEnd <|> fromEFDay <$> reportEnd <|> (Just $ addDays 180 $ _ioDay iopts)
mjournalend = dbg2 "journalEndDate" $ journalEndDate False j -- ignore secondary dates
DateSpan reportStart reportEnd = reportspan_ iopts
return . dbg2 "forecastspan" $ DateSpan (Exact <$> forecastStart) (Exact <$> forecastEnd)
My own recollection (and apparently the actual behaviour) is that it will not start before today unless you force it to with an explicit forecast period.
So there is some disagreement to clear up. Some very careful contemplation is needed before making any change here as this topic has been/can be hugely confusing.
PRs also welcome!
Thanks @simonmichael, completely understand.
Also worthwhile noting that I can achieve my desired behaviour by adding --forecast="this month"... I'd propose this is actually just a documentation change as there may be users who update their actuals on a daily basis and this change would result in them having to add something like --forecast="tomorrow"...
Seeing as this hasn't been brought up before, it can't be too big a deal for most users.
Doesn't --forecast="this month".. (or equivalently: --forecast=1..) risk duplicating forecast and recorded transactions in the period between first of month and today ? A clunky way to start forecasting after last transaction (roughly) would be: --forecast=$(hledger stats | rg 'Last.*?([-0-9]+)' -or '$1')..
Yep it absolutely does! Thankfully my numbers are quite small so I'd notice the double count 😆. But I did make a comment in my month end notes to watch out for this.