pre-design-doc budgeting notes [long]

Joshua Sled jsled@asynchronous.org
Mon, 22 Jan 2001 22:11:15 -0800


I've been playing around with designing structures to capture
budgeting in GnuCash, and figure out how budgeting integrates with the
rest of the program.

When you get closer to the end, it starts to unravel a bit... it's in
a weird state in my head at the moment... not quite coherent, definitly
not finished.  Hopefully getting this mail out and getting some feedback
will help me to make a somewhat fresh pass at it in the next week...

Cheers...
...jsled

----------

General Notes and Structures

There are maybe a set of budgets which exist in GnuCash at any one
time [maybe one real, and one hypothetical, and one for the coming
quarter/after job change... whatever].  This necessatitaes a budget
manager, or group of budgets, and some interface to creating,
destroying and selecting a budget for manipulation.

But, in order for GnuCash to interact the user [warning them they're
over budget when they make a register entry, for instance [and should
the user desire this, of course!]], only one budget can really be
considered.  Therefore we have the idea of a single "active" budget.

struct BudgetManager {
  GList /* <Budget*> */	*budgets;

  GUID		activeBudget; // or GUID-equiv of NULL.
};


Budgets have a name and description.  They have a start date, and
maybe an end date.  Since a budget is a mapping of incoming to
outgoing cash flows, we have lists of recurring incomes and
expenses...

We also have a list of Savings Goals... they generally have an
explicit "end" [when the goal is reached, no more contributions are
necessary], and are a bit more fungible than something like rent,
especially if they're low-priority [saving for a new stereo].  They
might also just be a more general form of recurring expenses: one
which has a limit...

struct Budget {
	char *name;
	char *description;

	time_t startDate;
	time_t endDate; // or 0, if indefinite

	GList /* <BudgetCategory*> */ 	*recurringIncomes;
	GList /* <BudgetCategory*> */ 	*recurringExpenses;
	GList /* <SavingsGoal*>    */ 	*savingsGoals;

};


BudgetCategories [BCats] are the categorical entries of the budget,
used for both income and expense.  They have a name, and probably a
description.  A recurring income or expense, at least, has a frequency
of recurrence:

enum RecurrenceEnum {
	DAILY,
	WEEKLY,
	BI_WEEKLY,
	MONTHLY,
	QUARTERLY,
	YEARLY,
};

BudgetCategories can be arranged in a tree; bcats themselves contain
their children, if any.

The _aount_ of the bcat may be fixed or variable... Currently, we will
only support simple and seasonal variable expenses.  Simple variable
expenses are those which have a base value, and some plus/minus range
in which they will be.  Seasonal variable expenses are defined over
the course of a year, one amount per month [useful for utilities
bills].  Eventually, there will need to be a more complex
representation here to do thorough analyses, and really help the user
make personal financial decisions via analysis.

There will be some accessor function which gets the correct amount for
a given specific date from the bcat, insulating the weirdness of any
recurrnce or variable amount specification [this becomes even more
important when the types of variable expenses increases].

Bcats contain a template transaction, which allows for scheduled
transactions and their instantiation [a seperate scheduled-transaction
thing is not part of this plan, but might be, time-permitting [see
below for updated thoughts on this -- jsled]].  Specification of the
date of the template transaction depends on the frequency of the bcat.
The amount[s] of the template transaction is probably symbolic for
whatever the "right" amount at the time of instantiation is.
Hopefully the general ledger/register can be forced into editing
things in the right way.

A seperate list of expense categories which relate to the bcat are
also stored, which allow for more transient cash outflow events to be
correctly ascribed to the correct bcat as well.  These add to the list
of expense categories involved in template/schedule transactions to
create the set of expense categories which the bcat 'covers'.
Ideally, all expenses categories will be covered by the budget.

Note that this only allows one or multiple expense accounts to be
combined into a single bcat; it does not allow multiple bcats to cover
a single expense account... don't know if this is the right thing, but
it's fine for now.

struct BudgetCategory {
	char	*name;
	char	*description;

	RecurrenceEnum	freq;

	Transaction	*templateTransaction;

	GList /* <Account*> */	*expenseAccounts;
};

Savings goals are special beasts, as they have some limit [both in
time and total amount, usually], and maybe some priority.  The latter
is useful WRT determining what portion of available funds to allocate
to a savings goal.  Savings Goals also have multiple accounts in which
the funds allocated to that acount may be stored.

The budgeting system is responsible for keeping track of the total
amount saved toward a goal, and will store some amount of data
relating to contributions towards a given savings goal, and the total
amount in each storage account for that goal.  There may be no
transaction associated with a contribution [paycheck direct-deposited
into checking account, and savings for goal held in same account], or
transactions into one or more accounts [savings toward goal is
distributed, for whatever reason].  Another example of split savings
is emergency funds, of which most is in an interest-bearing savings
account, but some is in a checking account so that the checking
account is always above the minimum [read: fee-incuring] balance.

This obviously then affects the real notion of "available funds" in
account[s]; some integration with the register should occur, here.

struct SavingsGoal {
	char	*name;
	char	*description;
	time_t	dueDate;

	gfloat	totalAmt;
	
	guint	priority;

	// restricted to type bank, cash, stock, mutual [?]
	GList /* <Account*> */	*savingsAccounts;

	GList /* <Contributions*> */	*contributions;
};

// This could use some work, otherwise it gets verbose over time.
// It's unclear we need to store _every_ contribution outside of some
// window... maybe just the total after that point.
struct Contribution {
	time_t	date;
	gfloat	amt;
	SavingsGoal	*toward;
	Account		*from;
};



With bcat's, especially yearly, infrequent things [christmas-time
gifts, random gadget purchases, books] should be dealt with
gracefully.  There should be some strategy contained w/in the bcat
which specifies how it is handled.  For instance, it may be nice to
save when possible to support future sporadic gadget purchases,
instead of drawing from available funds/credit...  This begins to
cross over into savings goals, so it might just be best to have the
bcat be or contain an implicit savings goal for such things.

[see below for more thoughts about this]



	Analysis

There are many kinds of analyses the user would like to perform with
the budgeting tool.

One of these is the initial analysis when creating the budget.

A very obvious help for developers and current users is that the
budgeting system should determine the initial cut at the budget from
existing data... this will also be true of future users who don't
initially use the budgeting system, but read reports of it's awesome
power, and decide to use it.  Budget creation can be based on
historical data, a previous budget, a druid or straight user bcat
creation.

The budgeting tool can also help in fixing the amounts for different
categories in the budget, if we model the problem as a
constraint-satisfaction problem [and include a solver :)].  For
instance: given this set of income and recurring expenses and these
savings goals with these constraints [date due, absolute/relative
priority, minimum-payments, &c], figure everything out...  scheduling
payments such that they are covered by available funds is another
interesting problem.

The more important analysis is the historical one, comparing budgeting
constraints to actual spending.  The results of this are to indicate
to the user where they (over/under)spend, either to improve the
amounts of the budgeting categories or so the use can select an
appropriate punishment for themselves [GnuCash-inflicted pain will not
be part of the first-cut at budgeting. :) ]

The period of this analysis may be:
  . since last run
  . last <<time range>>
In either case, long-term data will need to be pulled in from the
budget [progress toward savings goals, yearly-budgeted periodic
expenses, &c].

Ideally, this analysis will be able to make suggestions so that the
user can adjust their budget or spending appropriately.  For instance,
it would be nice to have the budgeting system recognize that
long-distance spending or food [variable, _controllable_ expenses] is
too large, and if cut back by X percent, then the budget would
balance.  Alternatively, if consulting income Y is a _controllable_
income, then more income could be generated.

Analyses of this nature require more information than is current in
the budgeting model.  The controllable nature of expenses is not
indicated.  More importantly, the long-distance calling example above
is not at all represented in the budgeting model, at present.

I believe that at some point down the road [and perhaps sooner rather
than later], some "expected" expense categories [food, phone, utils,
&c.] will need to allow for a more detailed approach to be taken, such
that this information can be captured, and these recommendations can
be made.  I say "allow" because it is lame to force the user into
entering 5 numbers [or ranges] for their phone bill if a) they don't
want to or b) their bill isn't structured that way; if they want to
say phone bills are "x +/- y" per month, then so be it.  However, lack
of information input doesn't enable the budgeting subsystem to perform
some useful functions.

There is some graphing here: cash-flow based time-series thingy is
what I want.  Some may want a pie chart, so eventually that'll show
up.

==========

After this point are random notes I thought up this recent
weekend... they need to be cleaned up, and some of them invalidate
what was said above...

Scheduled Transactions

. budgeting wants a mechanism for scheduled transaction.
. a scheduled xaction is a set of xactions which can be instantiated
  when due or upon request.
  . a particular xaction may involve multiple budget categories.
  . when used by the budgeting system, some schedule transactions are
    linked to their bcats; changes go both ways.
. fixed xactions have a fixed amt.
. var xactions have a strategy for payment:
  . even-pay
  . user-prompt with expected range
. one interface is visa the register [calendar-like repitition on
  jentries]
. another is a seperate list/dialog.
. in order to seperate scheduled transactions from the engine, we need
  some filter/selector for register entries.
  . defined by the templates in the scheduled xaction editor.
. notion of freq is shared w/the budget editor
. editing facilities are shared

Savings Goals

Types of expenses:
  . fixed/var, recurring: immed come from income, when available
  . sporadic [estimated|limited for period, no fixed schedule]:
save|debt|from available
  . long-term specific goals.

---

. Where do "Christmas Gifts" come in?
  . expected
  . funds needed in November
  . total amount estimated
  . should save over appropriate time period [starting 6 mo before,
    after other expenses are dealt with, &c]
. ...gadgets?
  . superfulous [wrt spending]
  . savings depends on the expectation value
  . wish-list, prioritized/in-active items 
  . medium-term savings goal, debt-repayment
. ... car maint?
  . unexpected... half-expected
  . straight savings goal?
. ...Burning Man?
  . same as Christmas:
    . expected
    . fund needed in August
    . total amount estimated
    . should save over appropriate time period

-----

. these things can be seperated into short- and long-term.
. they are different from straight recurring expenses.
  . new hierarchy:
    . recurring income
    . recurring expenses
    . periodic expenses
      . short-term
      . long-term
    . savings goals
      . short-term
      . long-term

But even this is weird, as the periodic expeneses act as savings goals
at times, and both are seperated into short- and long-term
items... there's obviously some similarity there to be exploited.

I'm also pretty sure that Savings Goals and bcats [at least expense
categories] are pretty much the same thing... maybe the distinction
isn't between income/expense bcats and savings goals, but instead
between income [pretty simple] and all these wacky different kinds of
expenses.