Approach to track Capital investments

269 views
Skip to first unread message

Chary Chary

unread,
Feb 10, 2023, 8:32:28 AM2/10/23
to Beancount
Dear all,

I don't think there was a discussion like this.

I want to figure out how to track capital investments I can't treat this like just expenses, as if I have today purchased a car for 20000 EURO my net worth is immediately lower tomorrow by 20000 EURO, which is totally different from say going for vacation for 20000 EUR

This is how I plan to track capital investments:



I plan to track by creating a commodity MYCAR and placing 1 item of it the Assets:Capital account

 2020-01-01 commodity MYCAR
  name: "Ford Focus XXXXXXX"
  assets-class: "car"

 2020-01-01 *  "Buying car"
   Assets:Bank:Payment         -20000 EUR
   Assets:Capital                         1 MYCAR  @@  -20000 EUR

And then in prices table I will show the depreciation of the value of the car

 2020-01-01 price  MYCAR  20000 EUR
 2021-01-01 price  MYCAR  18000 EUR
 2022-01-01 price  MYCAR  16000 EUR

Later I can use the unrealized gains plugin (which I still need to figure out how to use) to show depreciation of the value of the car as an unrealized cost

Any feedback?


Robert S

unread,
Feb 10, 2023, 7:48:15 PM2/10/23
to Beancount
I don't use price to track depreciation of fixed assets. At the end of an accounting period (e.g. annually), I insert an adjusting entry to recognize the depreciation as an expense. There are several methods for figuring out the depreciation amount for a period, but straight-line depreciation is (Purchase Cost - Salvage Value) / Useful Life. Salvage value is the amount you expect to recoup when you dispose of the asset, which can be 0 if you plan to use the asset until it's worthless, or an estimate of a fair value to get for selling it. For a business, the accounting principles for your locale will dictate rules on salvage value and useful life. But for personal accounting (where, at least in the U.S., you cannot use depreciation for personal assets), you can use whatever you want for those values. The transactions would look like:

2020-01-01 * "Car" "Purchase"
  Assets:Bank:MyBank -20,000 EUR
  Assets:Equipment:Vehicles 1 CAR.MAKEMODEL {20,000 EUR}
2020-12-31 * "Car" "Depreciation Expense"
  Assets:Equipment:Vehicles
  Expenses:AccumulatedDepreciation 2,000 EUR
2021-12-31 * "Car" "Depreciation Expense"
  Assets:Equipment:Vehicles
  Expenses:AccumulatedDepreciation 2,000 EUR

Note that this will store multiple commodities in the Assets:Equipment:Vehicles – you still have 1 CAR.MAKEMODEL, in addition to a contra-asset in EUR representing the depreciated value. Upon the sale (or other disposition) of the asset, you would debit the fixed asset (CAR.MAKEMODEL) and credit the entire amount of accumulated depreciation. That balances against the profit/loss of the sale of the car. E.g., sell the car 2 years later at 18,000 EUR for a profit of 2,000 EUR:

2022-01-01 * "Car" "Sale"
  Assets:Equipment:Vehicles -1 CAR.MAKEMODEL {20,000 EUR} @ 18,000 EUR
  Assets:Equipment:Vehicles 4,000 EUR
  Assets:Bank:MyBank 18,000 EUR
  Income:Equipment:Vehicles:PnL -2,000 EUR

I think this is preferable to using price directives, because the price of the car is actually the fair-market value for what you could get if you were to sell it at a point in time. The price could be less or greater than current depreciated value based on your useful life estimate.

- Robert

Ben Blount

unread,
Feb 10, 2023, 8:10:09 PM2/10/23
to bean...@googlegroups.com
Chary if you write Python the easiest way is definitely a quick simple plugin that adds the price and adds depreciation transactions to account for this however you want it to be. You can use custom directives to input the data for your plugin, or since it's just for you it can be quick and hacky and just hardcode the details about your car directly in the plugin.

--
You received this message because you are subscribed to the Google Groups "Beancount" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beancount+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/beancount/d8aba3c4-bef3-4bb3-8bea-749b0282755bn%40googlegroups.com.

Red S

unread,
Feb 10, 2023, 9:44:26 PM2/10/23
to Beancount
On Friday, February 10, 2023 at 4:48:15 PM UTC-8 Robert S wrote:
The transactions would look like:

2020-01-01 * "Car" "Purchase"
  Assets:Bank:MyBank -20,000 EUR
  Assets:Equipment:Vehicles 1 CAR.MAKEMODEL {20,000 EUR}
2020-12-31 * "Car" "Depreciation Expense"
  Assets:Equipment:Vehicles
  Expenses:AccumulatedDepreciation 2,000 EUR
2021-12-31 * "Car" "Depreciation Expense"
  Assets:Equipment:Vehicles
  Expenses:AccumulatedDepreciation 2,000 EUR

Above is how I do it as well. I use the effective_date plugin to automate the above.

Chary Chary

unread,
Feb 11, 2023, 4:26:05 AM2/11/23
to Beancount
Ok,

thank you very much for all your comments!

But what about for instance buying a house?

House can go up in price and it does depend on the market.

How would you track buying the house?

Robert S

unread,
Feb 11, 2023, 12:18:28 PM2/11/23
to Beancount
You would track a house the same way. Except most people do not depreciate their homes, but instead spend money on capital improvements:

2022-01-01 * "House" "Purchase"
  Assets:Bank:MyBank -500,000 EUR
  Expenses:Property:AcquisitionFees 50,000 EUR
  Assets:Property:Address 1 HOUSE.ADDRESS {450,000 EUR}
2022-06-01 * "House" "New Roof"
  Assets:Bank:MyBank -30,000 EUR
  Assets:Property:Address 30,000 EUR

The price of the house and the car both depend on the market; that's what I mentioned at the bottom of my previous message. Any time you receive market information about the current price of an asset, you can insert a price directive for it:

2021-06-01 price CAR.MAKEMODEL 17,500 EUR
2022-07-01 price HOUSE.ADDRESS 465,000 EUR

Fava's unrealized gain/loss report will show the PnL from the balance sheet value (i.e. the cost plus accumulated depreciation or capital improvements).

- Robert

P.S. I also use a plugin to automate inserting the adjusting entries for depreciation and amortization. I just wanted to illustrate the manual process in my first reply.

Chary Chary

unread,
Feb 20, 2023, 10:02:05 AM2/20/23
to Beancount
Robert,

RE:  Fava's unrealized gain/loss report will show the PnL from the balance sheet value (i.e. the cost plus accumulated depreciation or capital improvements).

Can you please can you please point me to this Fava's unrealized gain/loss report. I did some looking around, but could not find it.

I can see, that there is a normal unrealized gains plugin, but I understand you meant something else

Regards.

Robert S

unread,
Feb 24, 2023, 12:48:41 PM2/24/23
to Beancount
No plugins are necessary; this is all computed on the Balance Sheet view in Fava. You use the selector in the upper-right to switch between "At Cost", "At Market Value", and "Units". Using the example car transactions above, prior to the sale, the Balance Sheet would show:

- At Cost: 16,000 EUR (the original cost of the car plus -4,000 EUR of accumulated depreciation).
- At Market Value: the same (16,000 EUR) unless you also had price entries for CAR.MAKEMODEL, which would then be the most recent price plus -4,000 EUR of accumulated depreciation. Above the current value, it would show in green or red the gain/loss from the current value (cost plus accumulated depreciation).
- Units: 1 CAR.MAKEMODEL and -4,000 EUR of accumulated depreciation (the mixed commodities).

- Robert

Chary Chary

unread,
Feb 26, 2023, 1:38:52 PM2/26/23
to Beancount
Robert,

OK, thanks, understood. 

Stefano Merlo

unread,
Mar 4, 2023, 2:26:14 PM3/4/23
to Beancount
I personally consider my car as a commodity like my investments. See below a reproducible example:

~~~
option "operating_currency" "EUR"
option "title" "test-depreciation"

2021-07-01 commodity VAN
  name: "Renault Master Van"
  asset-class: "car"
  current_price_origin: "depreciation"
  yearly_rate: 10
  initial_price: 49900.00
  purchase_date: "2021-07-15"

2021-01-01 open Assets:Car:Van
2021-01-01 open Assets:Checking

2021-07-15 * "Ahorn Camp GmbH" "Purchase Renault Master"
  note: "depreciated using the declining balance depreciation at 10% per year [[https://www.investopedia.com/terms/d/decliningbalancemethod.asp]]"
  Assets:Car:Van                                          1 VAN   {49900.00 EUR}
  Assets:Checking                                 -49900.00 EUR

2021-07-15 price VAN                               49900.00 EUR
2021-12-31 price VAN                               47524.13 EUR
2022-07-15 price VAN                               44910.00 EUR
2022-12-31 price VAN                               42771.72 EUR
2023-07-15 price VAN                               40419.00 EUR

~~~

I wrote a script that fetch current prices for all my commodities from either Google Finance (almost all my ETFs and currencies), iShares (some ETFs not in Google Finance), OECD API (inflation rate, for beangrow calculation of real CAGR). I added a function that appends the current price of my car by applying a approx straight line depreciation (see below).

This allows me to look at my current assets and get the price I estimate I can convert my car if I would sell today; lot of assumptions, acknowledged, but good enough for me. If I was using this for official reporting, e.g. taxes declaration, I would likely use your method of a yearly transaction to a 'Expenses:Depreciation' account.Screenshot 2023-03-04 202023.png

I don't own an house, but if I were I would be interested of the present value. I would likely write a webscraper that gets the current price index of the properties in my region and estimate the present value, getting additional parameters such as closure costs, moving costs etc. Beancount is awesomely scalable for these plugins.

*Depreciation function*
~~~
def present_value(initial_value: float,
                  yearly_rate: float,
                  start_date_iso: str,
                  current_date_iso: str = None) -> float:
    """Return present value calculated with straight line depreciation.
    Args:
      initial_value: purchase price
      yearly_rate: rate in % (e.g. for 10% enter 10)
      start_date: in iso format; e.g. for 2021/07/15 enter '2021-07-15'
      current_date: iso of present date. If omitted, will take today
    Return:
      current value, rounded 0.2f.
    """
    start_value = float(initial_value)
    start_date = dt.fromisoformat(start_date_iso).date()
    if current_date_iso:
        current_date = dt.fromisoformat(current_date_iso).date()
    else:
        current_date = dt.today().date()
    delta = current_date - start_date
    years = delta.days / 365  # approx, without considering leap years
    present_value = start_value * pow((1 - yearly_rate / 100), years)
    return round(present_value, 2)

~~~
Reply all
Reply to author
Forward
0 new messages