aboutsummaryrefslogtreecommitdiffstats
path: root/leddy.5.scd
blob: d7bed19acd07640a930825b952fb5db5ce2fa9ee (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
leddy(5)

# NAME

*leddy* - file format and syntax reference

# DESCRIPTION

*leddy* uses a general ledger format similar to, but distinct from, other
common plain text accounting tools. This document assumes a general knowledge
of accounting principles, but no specific knowledge of other plain text
accounting tools.

*leddy* expects plain text files with a particular syntax in valid UTF-8. If
any aspect of the file is unexpected, *leddy* will report this to the user with
a line number and exit.

Lines beginning with '#' are interpreted as comments and ignored. Blank lines
and lines containing only whitespace are also ignored.

# ENTRIES AND DETAILS

An entry in a *leddy* ledger file is comprised of one _header_ line and two or
more _detail_ lines. The header line contains the date in ISO-8601 (YYYY-MM-DD)
format, followed by one space, followed by the name or description of the entry
in question. For example, to write a _header_ representing a fast food purchase:

	2023-01-02 Taco Bell

*leddy* is unopinionated about the content of the line after the date and one
space character that should follow it.

A _detail_ line contains four elements, each separated by one or more spaces:

1. leading whitespace, typically one tab character++
2. a valid account string++
3. the amount to debit or credit the account++
4. the currency or commodity that the amount is denominated in

Here is one possible complete fast food purchase entry, to finish our example:

	2023-01-02 Taco Bell++
		Expenses:Food:Restaurants  5.00 USD++
		Liabilities:Cards:Chase   -5.00 USD

There is no limit to the number of detail lines you can include in an entry. It
is typically ideal to keep them as specific as possible, but complex events,
especially those involving taxes, equities, and debts can validly involve many.
Here is an example of how you may handle the monthly payment on a loan that
accrues interest:

	2023-10-28 Navient++
		Assets:Checking:Chase     -402.00 USD++
		Expenses:Fees:Interest      68.00 USD++
		Liabilities:Loans:Student  334.00 USD

Here, we represent a payment of 402.00 USD, of which 68.00 went toward interest
and the remaining toward the principal balance. When summed up, all details on
an entry must balance, i.e. they must sum to zero. *leddy* will always verify
this and refuse to report anything if any entries in the ledger do not balance.

Other plain text accounting tools typically allow you to optionally omit the
amount and currency of exactly one detail line, and the parser will infer that
the entry is intended to balance and insert the necessary debit or credit to
make the entry balance. *leddy* does not allow this; all detail amounts and
currencies must be explicit.

There is one exception to the typical *leddy* balancing behavior related to
multi-currency entries. See *MULTI-CURRENCY*.

## ACCOUNTS

Accounts are strings that represent the location, application, or context of a
balance of money. They should contain at least two segments. The first segment
is always one of _Assets_, _Liabilities_, _Equity_, _Income_ or _Expenses_.
*leddy* enforces this. Subsequent segments can be organized however the user
wishes. Users are encouraged to consult educational accounting resources as
needed when considering how to best structure accounts.

As shown in the examples throughout this document, segments are colon-delimited.
Segments cannot contain spaces.

## AMOUNTS AND CURRENCIES

A currency must always follow every amount, and be separated from that amount
by exactly one space.

*leddy* handles amounts as integers internally, with precision determined by
the number of integers past the decimal point, if any. This ensures that no
floating point errors occur in processing.

Each account-currency combination must have a consistent number of integers past
the decimal point every time it appears. In other words, the below combination
of entries is invalid even though, in concept, they both make sense:

	2023-01-01 Entry One++
		Expenses:Fees:Interest      50 USD++
		Liabilities:Loans:Personal -50.00 USD

	2023-01-02 Entry Two++
		Expenses:Fees:Interest      50.00 USD++
		Liabilities:Loans:Student  -50.00 USD

In parsing this, *leddy* would complain that the precision between entries on
the Expenses:Fees:Interest account differs from the first time it saw it. This
check is designed to prevent common data entry mistakes, and simplifies the
internal handling of balances.

Currencies here are fiat currencies, but *leddy* is unopinionated about this.
Holdings of stocks, precious metals, crypto assets, or anything else with value 
can and should be represented as a currency in this model.

# MULTI-CURRENCY

*leddy* has no knowledge of the outside world and therefore no way of knowing
the exchange rates between different declared currencies. Therefore, it trusts
the user to input valid, balanced entries when multiple currencies are
involved.

When two currencies are used in one entry, *leddy* assumes the entry is balanced
and calculates an implied exchange rate between the two currencies that makes
the entry balance. These exchange rates can be observed in the *fx* report;
see *leddy*(1).

Lastly, *leddy* must make each currency balance. To achieve this, *leddy*
inserts two new details into the entry that net each currency to zero, into a
special _Equity:Conversions_ account. This account does not need to be declared
and is automatically created when needed. This is the only time *leddy* will
implicitly alter the representation of an entry. (Of course, it doesn't edit
the ledger file.) The effect is that the _Equity:Conversions_ account will
tabulate the net gain or loss of each currency from conversions into other
currencies.

Note the _Equity:Conversions_ account is not otherwise special, can be manually
declared and interacted with, etc. just like any other account.

Entries are allowed to contain up to two currencies in total. Three or more is
not supported. This is because it would be impossible to implicitly calculate
exchange rates if three or more currencies were in the same entry, because
infinitely many valid solutions would exist.