|
|
@ -0,0 +1,330 @@ |
|
|
|
<!DOCTYPE html> |
|
|
|
<html lang="en"> |
|
|
|
|
|
|
|
<head> |
|
|
|
<meta charset="utf-8"> |
|
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge"> |
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1"> |
|
|
|
|
|
|
|
<title>Using Ledger for YNAB-like envelope budgeting</title> |
|
|
|
<meta name="description" content="Bye bye Elbank"> |
|
|
|
|
|
|
|
<link rel="shortcut icon" type="image/png" href="/favicon.png"/> |
|
|
|
<link href="https://fonts.googleapis.com/css?family=Fira+Mono|Gentium+Book+Basic|Lato" rel="stylesheet"> |
|
|
|
<link rel="stylesheet" href="/assets/main.css"> |
|
|
|
<link rel="stylesheet" href="/css/cafe.css"> |
|
|
|
<link rel="canonical" href="https://emacs.cafe/ledger/emacs/ynab/budgeting/2018/06/12/elbank-ynab.html"> |
|
|
|
<link rel="alternate" type="application/rss+xml" title="Emacs café" href="/feed.xml"> |
|
|
|
|
|
|
|
|
|
|
|
</head> |
|
|
|
|
|
|
|
|
|
|
|
<body> |
|
|
|
|
|
|
|
<header class="site-header" role="banner"> |
|
|
|
|
|
|
|
<div class="wrapper"> |
|
|
|
|
|
|
|
|
|
|
|
<a class="site-title" href="/"><img src="/img/emacscafe.png"/>Emacs café</a> |
|
|
|
|
|
|
|
|
|
|
|
<nav class="site-nav"> |
|
|
|
<input type="checkbox" id="nav-trigger" class="nav-trigger" /> |
|
|
|
<label for="nav-trigger"> |
|
|
|
<span class="menu-icon"> |
|
|
|
<svg viewBox="0 0 18 15" width="18px" height="15px"> |
|
|
|
<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"/> |
|
|
|
<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"/> |
|
|
|
<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"/> |
|
|
|
</svg> |
|
|
|
</span> |
|
|
|
</label> |
|
|
|
|
|
|
|
<div class="trigger"> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<a class="page-link" href="/about/">About Emacs café</a> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</div> |
|
|
|
</nav> |
|
|
|
|
|
|
|
</div> |
|
|
|
</header> |
|
|
|
|
|
|
|
|
|
|
|
<main class="page-content" aria-label="Content"> |
|
|
|
<div class="wrapper"> |
|
|
|
<article class="post" itemscope itemtype="http://schema.org/BlogPosting"> |
|
|
|
|
|
|
|
<header class="post-header"> |
|
|
|
<h1 class="post-title" itemprop="name headline">Using Ledger for YNAB-like envelope budgeting</h1> |
|
|
|
<p class="post-meta"> |
|
|
|
<time datetime="2018-06-12T21:20:00+02:00" itemprop="datePublished"> |
|
|
|
|
|
|
|
Jun 12, 2018 |
|
|
|
</time> |
|
|
|
|
|
|
|
• <span itemprop="author" itemscope itemtype="http://schema.org/Person"><span itemprop="name">Nicolas Petton</span></span> |
|
|
|
</p> |
|
|
|
</header> |
|
|
|
|
|
|
|
<div class="post-content" itemprop="articleBody"> |
|
|
|
<h1 id="bye-bye-elbank">Bye bye Elbank</h1> |
|
|
|
|
|
|
|
<p>I have to start this post with this: I will not be actively maintaining |
|
|
|
<a href="https://github.com/NicolasPetton/elbank">Elbank</a> anymore, simply because I |
|
|
|
switched back to <a href="https://www.ledger-cli.org/">Ledger</a>. If someone wants to |
|
|
|
take over, please contact me!</p> |
|
|
|
|
|
|
|
<p>The main reason for switching is budgeting. While Elbank was a cool experiment, |
|
|
|
it is not an accounting software, and inherently lacks support for powerful |
|
|
|
budgeting.</p> |
|
|
|
|
|
|
|
<p>When I started working on Elbank as a replacement for Ledger, I was looking for |
|
|
|
a reporting tool within Emacs that would fetch bank transactions automatically, |
|
|
|
so I wouldn’t have to enter transactions by hand (this is a seriously tedious |
|
|
|
task, and I grew tired of doing it after roughly two years, and finally gave up).</p> |
|
|
|
|
|
|
|
<p>Since then, I learned about ledger-autosync and boobank, which I use to sync my |
|
|
|
bank statements with Ledger (more about that in another post).</p> |
|
|
|
|
|
|
|
<h1 id="ynabs-way-of-budgeting">YNAB’s way of budgeting</h1> |
|
|
|
|
|
|
|
<p>I only came across <a href="https://ynab.com">YNAB</a> recently. While I won’t use their |
|
|
|
software (being a non-free web application, and, you know… there’s no <code class="highlighter-rouge">M-x |
|
|
|
ynab</code>), I think that the principles behind it are really appealing for personal |
|
|
|
budgeting. I encourage you to <a href="https://www.youneedabudget.com/method/">read more about |
|
|
|
it</a> (or grab a <a href="https://www.youneedabudget.com/book-order-now/">copy of the |
|
|
|
book</a>, it’s great), but here’s |
|
|
|
the idea.</p> |
|
|
|
|
|
|
|
<ol> |
|
|
|
<li> |
|
|
|
<p><strong>Budget every euro</strong>: Quite simple once you get it. Every single Euro you have |
|
|
|
should be in a budget envelope. You should assign a job to every Euro you |
|
|
|
earn (that’s called |
|
|
|
<a href="https://en.wikipedia.org/wiki/Zero-based_budgeting">zero-based</a>, <a href="https://en.wikipedia.org/wiki/Envelope_system">envelope |
|
|
|
system</a>).</p> |
|
|
|
</li> |
|
|
|
<li> |
|
|
|
<p><strong>Embrace your true expenses</strong>: Plan for larger and less frequent expenses, so |
|
|
|
when a yearly bill arrives, or your car breaks down, you’ll be covered.</p> |
|
|
|
</li> |
|
|
|
<li> |
|
|
|
<p><strong>Roll with the punches</strong>: Address overspending as it happens by taking money |
|
|
|
overspent from another envelope. As long as you keep budgeting, you’re |
|
|
|
succeeding.</p> |
|
|
|
</li> |
|
|
|
<li> |
|
|
|
<p><strong>Age your money</strong>: Spend less than you earn, so your money stays in the bank |
|
|
|
account longer. As you do that, the age of your money will grow, and once |
|
|
|
you reach the goal of spending money that is at least one month old, you |
|
|
|
won’t worry about that next bill.</p> |
|
|
|
</li> |
|
|
|
</ol> |
|
|
|
|
|
|
|
<h1 id="implementation-in-ledger">Implementation in Ledger</h1> |
|
|
|
|
|
|
|
<p>I assume that you are familiar with Ledger, but if not I recommend reading its |
|
|
|
great |
|
|
|
<a href="https://www.ledger-cli.org/3.0/doc/ledger3.html#Introduction-to-Ledger">introduction</a> |
|
|
|
and <a href="https://www.ledger-cli.org/3.0/doc/ledger3.html#Ledger-Tutorial">tutorial</a>.</p> |
|
|
|
|
|
|
|
<p>The implementation in Ledger uses plain double-entry accounting. I took most of |
|
|
|
it from |
|
|
|
<a href="http://sachachua.com/blog/2014/11/keeping-financial-score-ledger/">Sacha</a>, with |
|
|
|
some minor differences.</p> |
|
|
|
|
|
|
|
<h2 id="budgeting-new-money">Budgeting new money</h2> |
|
|
|
|
|
|
|
<p>After each income transaction, I budget the new money:</p> |
|
|
|
|
|
|
|
<div class="highlighter-rouge"><pre class="highlight"><code>2018-06-12 Employer |
|
|
|
Assets:Bank:Checking 1600.00 EUR |
|
|
|
Income:Salary -1600.00 EUR |
|
|
|
|
|
|
|
2018-06-12 Budget |
|
|
|
[Assets:Budget:Food] 400.00 EUR |
|
|
|
[Assets:Budget:Rent] 600.00 EUR |
|
|
|
[Assets:Budget:Utilities] 600.00 EUR |
|
|
|
[Equity:Budget] -1600.00 EUR |
|
|
|
</code></pre> |
|
|
|
</div> |
|
|
|
|
|
|
|
<p>Did you notice the square brackets around the accounts of the budget |
|
|
|
transaction? It’s a feature Ledger calls <a href="https://www.ledger-cli.org/3.0/doc/ledger3.html#Virtual-postings">virtual |
|
|
|
postings</a>. These |
|
|
|
postings are not considered real, and won’t be present in any report that uses |
|
|
|
the <code class="highlighter-rouge">--real</code> flag. This is exactly what we want, since it’s a budget allocation |
|
|
|
and not a “real” transaction. Therefore we’ll use the <code class="highlighter-rouge">--real</code> flag for all |
|
|
|
reports except for our budget report.</p> |
|
|
|
|
|
|
|
<h2 id="automatically-crediting-budget-accounts-when-spending-money">Automatically crediting budget accounts when spending money</h2> |
|
|
|
|
|
|
|
<p>Next, we need to credit the budget accounts each time we spend money. Ledger |
|
|
|
has another neat feature called <a href="https://www.ledger-cli.org/3.0/doc/ledger3.html#Automated-Transactions">automated |
|
|
|
transactions</a> |
|
|
|
for this:</p> |
|
|
|
|
|
|
|
<div class="highlighter-rouge"><pre class="highlight"><code>= /Expenses/ |
|
|
|
[Assets:Budget:Unbudgeted] -1.0 |
|
|
|
[Equity:Budget] 1.0 |
|
|
|
|
|
|
|
= /Expenses:Food/ |
|
|
|
[Assets:Budget:Food] -1.0 |
|
|
|
[Assets:Budget:Unbudgeted] 1.0 |
|
|
|
|
|
|
|
= /Expenses:Rent/ |
|
|
|
[Assets:Budget:Rent] -1.0 |
|
|
|
[Assets:Budget:Unbudgeted] 1.0 |
|
|
|
|
|
|
|
= /Expenses:Utilities/ |
|
|
|
[Assets:Budget:Utilities] -1.0 |
|
|
|
[Assets:Budget:Unbudgeted] 1.0 |
|
|
|
</code></pre> |
|
|
|
</div> |
|
|
|
|
|
|
|
<p>Every expense is taken out of the <code class="highlighter-rouge">Assets:Budget:Unbudgeted</code> account by default.</p> |
|
|
|
|
|
|
|
<p>This forces me to budget properly, as <code class="highlighter-rouge">Assets:Budget:Unbudgeted</code> should always |
|
|
|
be 0 (if it is not the case I immediately know that there is something wrong |
|
|
|
going on).</p> |
|
|
|
|
|
|
|
<p>All other automatic transactions take money out of the |
|
|
|
<code class="highlighter-rouge">Assets:Budget:Unbudgeted</code> account instead of <code class="highlighter-rouge">Equity:Budget</code> account.</p> |
|
|
|
|
|
|
|
<h2 id="a-budget-report">A Budget report</h2> |
|
|
|
|
|
|
|
<p>This is the final piece of the puzzle. Here’s the budget report command:</p> |
|
|
|
|
|
|
|
<div class="highlighter-rouge"><pre class="highlight"><code>ledger --empty -S -T -f ledger.dat bal ^assets:budget |
|
|
|
</code></pre> |
|
|
|
</div> |
|
|
|
|
|
|
|
<p>If we have the following transactions:</p> |
|
|
|
|
|
|
|
<div class="highlighter-rouge"><pre class="highlight"><code>2018/06/12 Groceries store |
|
|
|
Expenses:Food 123.00 EUR |
|
|
|
Assets:Bank:Checking |
|
|
|
|
|
|
|
2018/06/12 Landlord |
|
|
|
Expenses:Rent 600.00 EUR |
|
|
|
Assets:Bank:Checking |
|
|
|
|
|
|
|
2018/06/12 Internet provider |
|
|
|
Expenses:Utilities:Internet 40.00 EUR |
|
|
|
Assets:Bank:Checking |
|
|
|
</code></pre> |
|
|
|
</div> |
|
|
|
|
|
|
|
<p>Here’s what the report looks like:</p> |
|
|
|
|
|
|
|
<div class="highlighter-rouge"><pre class="highlight"><code> 837.00 EUR Assets:Budget |
|
|
|
560.00 EUR Utilities |
|
|
|
277.00 EUR Food |
|
|
|
0 Rent |
|
|
|
0 Unbudgeted |
|
|
|
-------------------- |
|
|
|
837.00 EUR |
|
|
|
</code></pre> |
|
|
|
</div> |
|
|
|
|
|
|
|
<h1 id="conclusion">Conclusion</h1> |
|
|
|
|
|
|
|
<p>Ledger is amazingly powerful, and provides a great framework for YNAB-like |
|
|
|
budgeting. In a future post I’ll explain how I automatically import my bank |
|
|
|
transactions using a mix of <code class="highlighter-rouge">ledger-autosync</code> and <code class="highlighter-rouge">weboob</code>.</p> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div id="disqus_thread"></div> |
|
|
|
<script> |
|
|
|
/* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */ |
|
|
|
var disqus_shortname = 'emacs-cafe'; |
|
|
|
|
|
|
|
/* * * DON'T EDIT BELOW THIS LINE * * */ |
|
|
|
(function() { |
|
|
|
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true; |
|
|
|
dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js'; |
|
|
|
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq); |
|
|
|
})(); |
|
|
|
</script> |
|
|
|
<noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript" rel="nofollow">comments powered by Disqus.</a></noscript> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</article> |
|
|
|
|
|
|
|
</div> |
|
|
|
</main> |
|
|
|
|
|
|
|
<footer class="site-footer"> |
|
|
|
|
|
|
|
<div class="wrapper"> |
|
|
|
|
|
|
|
<h2 class="footer-heading">Emacs café</h2> |
|
|
|
|
|
|
|
<div class="footer-col-wrapper"> |
|
|
|
<div class="footer-col footer-col-1"> |
|
|
|
<ul class="contact-list"> |
|
|
|
<li> |
|
|
|
|
|
|
|
Emacs café |
|
|
|
|
|
|
|
</li> |
|
|
|
|
|
|
|
<li><a href="mailto:nicolas@petton.fr">nicolas@petton.fr</a></li> |
|
|
|
|
|
|
|
</ul> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="footer-col footer-col-2"> |
|
|
|
<ul class="social-media-list"> |
|
|
|
|
|
|
|
<li> |
|
|
|
<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> |
|
|
|
</span><span class="username">NicolasPetton</span></a> |
|
|
|
|
|
|
|
</li> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li> |
|
|
|
<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> |
|
|
|
</span><span class="username">NicolasPetton</span></a> |
|
|
|
|
|
|
|
</li> |
|
|
|
|
|
|
|
</ul> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="footer-col footer-col-3"> |
|
|
|
<p>A blog about Emacs, mostly focused on JavaScript development, by Nicolas Petton. |
|
|
|
</p> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
</footer> |
|
|
|
|
|
|
|
|
|
|
|
</body> |
|
|
|
|
|
|
|
</html> |