main
  1<!DOCTYPE html>
  2<html lang="en">
  3
  4  <head>
  5    <meta charset="utf-8">
  6    <meta http-equiv="X-UA-Compatible" content="IE=edge">
  7    <meta name="viewport" content="width=device-width, initial-scale=1">
  8
  9    <title>Using Ledger for YNAB-like envelope budgeting</title>
 10    <meta name="description" content="Bye bye Elbank">
 11
 12    <link rel="shortcut icon" type="image/png" href="/favicon.png"/>
 13    <link href="https://fonts.googleapis.com/css?family=Fira+Mono|Gentium+Book+Basic|Lato" rel="stylesheet">
 14    <link rel="stylesheet" href="/assets/main.css">
 15    <link rel="stylesheet" href="/css/cafe.css">
 16    <link rel="canonical" href="https://emacs.cafe/ledger/emacs/ynab/budgeting/2018/06/12/elbank-ynab.html">
 17    <link rel="alternate" type="application/rss+xml" title="Emacs café" href="/feed.xml">
 18    
 19    
 20</head>
 21
 22
 23  <body>
 24
 25    <header class="site-header" role="banner">
 26
 27    <div class="wrapper">
 28        
 29        
 30        <a class="site-title" href="/"><img src="/img/emacscafe.png"/>Emacs café</a>
 31        
 32        
 33        <nav class="site-nav">
 34            <input type="checkbox" id="nav-trigger" class="nav-trigger" />
 35            <label for="nav-trigger">
 36                <span class="menu-icon">
 37                    <svg viewBox="0 0 18 15" width="18px" height="15px">
 38                        <path fill="#424242" d="M18,1.484c0,0.82-0.665,1.484-1.484,1.484H1.484C0.665,2.969,0,2.304,0,1.484l0,0C0,0.665,0.665,0,1.484,0 h15.031C17.335,0,18,0.665,18,1.484L18,1.484z"/>
 39                        <path fill="#424242" d="M18,7.516C18,8.335,17.335,9,16.516,9H1.484C0.665,9,0,8.335,0,7.516l0,0c0-0.82,0.665-1.484,1.484-1.484 h15.031C17.335,6.031,18,6.696,18,7.516L18,7.516z"/>
 40                        <path fill="#424242" d="M18,13.516C18,14.335,17.335,15,16.516,15H1.484C0.665,15,0,14.335,0,13.516l0,0 c0-0.82,0.665-1.484,1.484-1.484h15.031C17.335,12.031,18,12.696,18,13.516L18,13.516z"/>
 41                    </svg>
 42                </span>
 43            </label>
 44
 45            <div class="trigger">
 46                
 47                
 48                
 49                <a class="page-link" href="/about/">About Emacs café</a>
 50                
 51                
 52                
 53                
 54                
 55                
 56                
 57                
 58                
 59                
 60                
 61            </div>
 62        </nav>
 63        
 64    </div>
 65</header>
 66
 67
 68    <main class="page-content" aria-label="Content">
 69      <div class="wrapper">
 70        <article class="post" itemscope itemtype="http://schema.org/BlogPosting">
 71
 72  <header class="post-header">
 73    <h1 class="post-title" itemprop="name headline">Using Ledger for YNAB-like envelope budgeting</h1>
 74    <p class="post-meta">
 75      <time datetime="2018-06-12T21:20:00+02:00" itemprop="datePublished">
 76        
 77        Jun 12, 2018
 78      </time>
 79      
 80<span itemprop="author" itemscope itemtype="http://schema.org/Person"><span itemprop="name">Nicolas Petton</span></span>
 81      </p>
 82  </header>
 83
 84  <div class="post-content" itemprop="articleBody">
 85    <h1 id="bye-bye-elbank">Bye bye Elbank</h1>
 86
 87<p>I have to start this post with this: I will not be actively maintaining
 88<a href="https://github.com/NicolasPetton/elbank">Elbank</a> anymore, simply because I
 89switched back to <a href="https://www.ledger-cli.org/">Ledger</a>.  If someone wants to
 90take over, please contact me!</p>
 91
 92<p>The main reason for switching is budgeting.  While Elbank was a cool experiment,
 93it is not an accounting software, and inherently lacks support for powerful
 94budgeting.</p>
 95
 96<p>When I started working on Elbank as a replacement for Ledger, I was looking for
 97a reporting tool within Emacs that would fetch bank transactions automatically,
 98so I wouldn’t have to enter transactions by hand (this is a seriously tedious
 99task, and I grew tired of doing it after roughly two years, and finally gave up).</p>
100
101<p>Since then, I learned about ledger-autosync and boobank, which I use to sync my
102bank statements with Ledger (more about that in another post).</p>
103
104<h1 id="ynabs-way-of-budgeting">YNAB’s way of budgeting</h1>
105
106<p>I only came across <a href="https://ynab.com">YNAB</a> recently.  While I won’t use their
107software (being a non-free web application, and, you know… there’s no <code class="highlighter-rouge">M-x
108ynab</code>), I think that the principles behind it are really appealing for personal
109budgeting. I encourage you to <a href="https://www.youneedabudget.com/method/">read more about
110it</a> (or grab a <a href="https://www.youneedabudget.com/book-order-now/">copy of the
111book</a>, it’s great), but here’s
112the idea.</p>
113
114<ol>
115  <li>
116    <p><strong>Budget every euro</strong>: Quite simple once you get it. Every single Euro you have
117should be in a budget envelope. You should assign a job to every Euro you
118earn (that’s called
119<a href="https://en.wikipedia.org/wiki/Zero-based_budgeting">zero-based</a>, <a href="https://en.wikipedia.org/wiki/Envelope_system">envelope
120system</a>).</p>
121  </li>
122  <li>
123    <p><strong>Embrace your true expenses</strong>: Plan for larger and less frequent expenses, so
124when a yearly bill arrives, or your car breaks down, you’ll be covered.</p>
125  </li>
126  <li>
127    <p><strong>Roll with the punches</strong>: Address overspending as it happens by taking money
128overspent from another envelope.  As long as you keep budgeting, you’re
129succeeding.</p>
130  </li>
131  <li>
132    <p><strong>Age your money</strong>: Spend less than you earn, so your money stays in the bank
133account longer.  As you do that, the age of your money will grow, and once
134you reach the goal of spending money that is at least one month old, you
135won’t worry about that next bill.</p>
136  </li>
137</ol>
138
139<h1 id="implementation-in-ledger">Implementation in Ledger</h1>
140
141<p>I assume that you are familiar with Ledger, but if not I recommend reading its
142great
143<a href="https://www.ledger-cli.org/3.0/doc/ledger3.html#Introduction-to-Ledger">introduction</a>
144and <a href="https://www.ledger-cli.org/3.0/doc/ledger3.html#Ledger-Tutorial">tutorial</a>.</p>
145
146<p>The implementation in Ledger uses plain double-entry accounting.  I took most of
147it from
148<a href="http://sachachua.com/blog/2014/11/keeping-financial-score-ledger/">Sacha</a>, with
149some minor differences.</p>
150
151<h2 id="budgeting-new-money">Budgeting new money</h2>
152
153<p>After each income transaction, I budget the new money:</p>
154
155<div class="highlighter-rouge"><pre class="highlight"><code>2018-06-12 Employer
156    Assets:Bank:Checking                        1600.00 EUR
157    Income:Salary                              -1600.00 EUR
158
1592018-06-12 Budget
160    [Assets:Budget:Food]                         400.00 EUR
161    [Assets:Budget:Rent]                         600.00 EUR
162    [Assets:Budget:Utilities]                    600.00 EUR
163    [Equity:Budget]                            -1600.00 EUR
164</code></pre>
165</div>
166
167<p>Did you notice the square brackets around the accounts of the budget
168transaction? It’s a feature Ledger calls <a href="https://www.ledger-cli.org/3.0/doc/ledger3.html#Virtual-postings">virtual
169postings</a>. These
170postings are not considered real, and won’t be present in any report that uses
171the <code class="highlighter-rouge">--real</code> flag.  This is exactly what we want, since it’s a budget allocation
172and not a “real” transaction.  Therefore we’ll use the <code class="highlighter-rouge">--real</code> flag for all
173reports except for our budget report.</p>
174
175<h2 id="automatically-crediting-budget-accounts-when-spending-money">Automatically crediting budget accounts when spending money</h2>
176
177<p>Next, we need to credit the budget accounts each time we spend money.  Ledger
178has another neat feature called <a href="https://www.ledger-cli.org/3.0/doc/ledger3.html#Automated-Transactions">automated
179transactions</a>
180for this:</p>
181
182<div class="highlighter-rouge"><pre class="highlight"><code>= /Expenses/
183    [Assets:Budget:Unbudgeted]                    -1.0
184    [Equity:Budget]                                1.0
185
186= /Expenses:Food/
187    [Assets:Budget:Food]                          -1.0
188    [Assets:Budget:Unbudgeted]                     1.0
189	
190= /Expenses:Rent/
191    [Assets:Budget:Rent]                          -1.0
192    [Assets:Budget:Unbudgeted]                     1.0
193	
194= /Expenses:Utilities/
195    [Assets:Budget:Utilities]                     -1.0
196    [Assets:Budget:Unbudgeted]                     1.0
197</code></pre>
198</div>
199
200<p>Every expense is taken out of the <code class="highlighter-rouge">Assets:Budget:Unbudgeted</code> account by default.</p>
201
202<p>This forces me to budget properly, as <code class="highlighter-rouge">Assets:Budget:Unbudgeted</code> should always
203be 0 (if it is not the case I immediately know that there is something wrong
204going on).</p>
205
206<p>All other automatic transactions take money out of the
207<code class="highlighter-rouge">Assets:Budget:Unbudgeted</code> account instead of <code class="highlighter-rouge">Equity:Budget</code> account.</p>
208
209<h2 id="a-budget-report">A Budget report</h2>
210
211<p>This is the final piece of the puzzle.  Here’s the budget report command:</p>
212
213<div class="highlighter-rouge"><pre class="highlight"><code>ledger --empty -S -T -f ledger.dat bal ^assets:budget
214</code></pre>
215</div>
216
217<p>If we have the following transactions:</p>
218
219<div class="highlighter-rouge"><pre class="highlight"><code>2018/06/12 Groceries store
220    Expenses:Food                                123.00 EUR
221    Assets:Bank:Checking
222
2232018/06/12 Landlord
224    Expenses:Rent                                600.00 EUR
225    Assets:Bank:Checking
226
2272018/06/12 Internet provider
228    Expenses:Utilities:Internet                   40.00 EUR
229    Assets:Bank:Checking
230</code></pre>
231</div>
232
233<p>Here’s what the report looks like:</p>
234
235<div class="highlighter-rouge"><pre class="highlight"><code>          837.00 EUR  Assets:Budget
236          560.00 EUR    Utilities
237          277.00 EUR    Food
238                   0    Rent
239                   0    Unbudgeted
240--------------------
241          837.00 EUR
242</code></pre>
243</div>
244
245<h1 id="conclusion">Conclusion</h1>
246
247<p>Ledger is amazingly powerful, and provides a great framework for YNAB-like
248budgeting.  In a future post I’ll explain how I automatically import my bank
249transactions using a mix of <code class="highlighter-rouge">ledger-autosync</code> and <code class="highlighter-rouge">weboob</code>.</p>
250
251  </div>
252
253  
254    
255
256<div id="disqus_thread"></div>
257<script>
258 /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
259 var disqus_shortname = 'emacs-cafe';
260
261 /* * * DON'T EDIT BELOW THIS LINE * * */
262 (function() {
263     var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
264     dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
265     (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
266 })();
267</script>
268<noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript" rel="nofollow">comments powered by Disqus.</a></noscript>
269
270
271  
272</article>
273
274      </div>
275    </main>
276
277    <footer class="site-footer">
278
279  <div class="wrapper">
280
281    <h2 class="footer-heading">Emacs café</h2>
282
283    <div class="footer-col-wrapper">
284      <div class="footer-col footer-col-1">
285        <ul class="contact-list">
286          <li>
287            
288              Emacs café
289            
290            </li>
291            
292            <li><a href="mailto:nicolas@petton.fr">nicolas@petton.fr</a></li>
293            
294        </ul>
295      </div>
296
297      <div class="footer-col footer-col-2">
298        <ul class="social-media-list">
299          
300          <li>
301            <a href="https://github.com/NicolasPetton"><span class="icon icon--github"><svg viewBox="0 0 16 16" width="16px" height="16px"><path fill="#828282" d="M7.999,0.431c-4.285,0-7.76,3.474-7.76,7.761 c0,3.428,2.223,6.337,5.307,7.363c0.388,0.071,0.53-0.168,0.53-0.374c0-0.184-0.007-0.672-0.01-1.32 c-2.159,0.469-2.614-1.04-2.614-1.04c-0.353-0.896-0.862-1.135-0.862-1.135c-0.705-0.481,0.053-0.472,0.053-0.472 c0.779,0.055,1.189,0.8,1.189,0.8c0.692,1.186,1.816,0.843,2.258,0.645c0.071-0.502,0.271-0.843,0.493-1.037 C4.86,11.425,3.049,10.76,3.049,7.786c0-0.847,0.302-1.54,0.799-2.082C3.768,5.507,3.501,4.718,3.924,3.65 c0,0,0.652-0.209,2.134,0.796C6.677,4.273,7.34,4.187,8,4.184c0.659,0.003,1.323,0.089,1.943,0.261 c1.482-1.004,2.132-0.796,2.132-0.796c0.423,1.068,0.157,1.857,0.077,2.054c0.497,0.542,0.798,1.235,0.798,2.082 c0,2.981-1.814,3.637-3.543,3.829c0.279,0.24,0.527,0.713,0.527,1.437c0,1.037-0.01,1.874-0.01,2.129 c0,0.208,0.14,0.449,0.534,0.373c3.081-1.028,5.302-3.935,5.302-7.362C15.76,3.906,12.285,0.431,7.999,0.431z"/></svg>
302</span><span class="username">NicolasPetton</span></a>
303
304          </li>
305          
306
307          
308          <li>
309            <a href="https://twitter.com/NicolasPetton"><span class="icon icon--twitter"><svg viewBox="0 0 16 16" width="16px" height="16px"><path fill="#828282" d="M15.969,3.058c-0.586,0.26-1.217,0.436-1.878,0.515c0.675-0.405,1.194-1.045,1.438-1.809c-0.632,0.375-1.332,0.647-2.076,0.793c-0.596-0.636-1.446-1.033-2.387-1.033c-1.806,0-3.27,1.464-3.27,3.27 c0,0.256,0.029,0.506,0.085,0.745C5.163,5.404,2.753,4.102,1.14,2.124C0.859,2.607,0.698,3.168,0.698,3.767 c0,1.134,0.577,2.135,1.455,2.722C1.616,6.472,1.112,6.325,0.671,6.08c0,0.014,0,0.027,0,0.041c0,1.584,1.127,2.906,2.623,3.206 C3.02,9.402,2.731,9.442,2.433,9.442c-0.211,0-0.416-0.021-0.615-0.059c0.416,1.299,1.624,2.245,3.055,2.271 c-1.119,0.877-2.529,1.4-4.061,1.4c-0.264,0-0.524-0.015-0.78-0.046c1.447,0.928,3.166,1.469,5.013,1.469 c6.015,0,9.304-4.983,9.304-9.304c0-0.142-0.003-0.283-0.009-0.423C14.976,4.29,15.531,3.714,15.969,3.058z"/></svg>
310</span><span class="username">NicolasPetton</span></a>
311
312          </li>
313          
314        </ul>
315      </div>
316
317      <div class="footer-col footer-col-3">
318        <p>A blog about Emacs, mostly focused on JavaScript development, by Nicolas Petton.
319</p>
320      </div>
321    </div>
322
323  </div>
324
325</footer>
326
327
328  </body>
329
330</html>