Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Managing Personal Finances using Python

Managing Personal Finances using Python

Siddhant Goel

May 15, 2019
Tweet

More Decks by Siddhant Goel

Other Decks in Technology

Transcript

  1. Managing Personal Finances using Python
    Siddhant Goel
     /  @siddhantgoel
    PyMunich May 2019

    View Slide

  2. Let's start with money.

    View Slide

  3. 1. What is my net worth?

    View Slide

  4. 2. What am I spending on?

    View Slide

  5. 3. How much do I owe others?

    View Slide

  6. How to debug this?

    View Slide

  7. duckduckgo.com/?q=personal+ nance+apps
    Mint.com, YNAB, Outbank, Quickbooks, Zuper, GNUCash, ...

    View Slide

  8. Proprietary
    ... mayyyyybe

    View Slide

  9. -based
    ... sorry, that's not happening

    View Slide

  10. Requirements
    Simple
    No cloud
    Ideally free
    Open source
    Hopefully Python

    View Slide

  11. #plaintextaccounting

    View Slide

  12. Double Entry Bookkeeping

    View Slide

  13. beans
    ledger
    hledger
    beancount
    monescript

    View Slide

  14. $ pip install beancount

    View Slide

  15. Disclaimers
    I'm not a nancial advisor.
    Aim is to show you what's possible.
    Following slides may or may not contain some maths.

    View Slide

  16. Accounts

    View Slide

  17. View Slide

  18. Postings & Transactions

    View Slide

  19. 2019-10-25 "*" "Überweisung BigCorp"
    Assets:DKB 3000.00 EUR
    Income:BigCorp -3000.00 EUR

    View Slide

  20. ∑(postings) = 0

    View Slide

  21. View Slide

  22. mkdir -p /home/morty/finances

    View Slide

  23. siddhant@localhost ~/finances % tree .
    .
    ├── config.py
    ├── main.beancount
    ├── originals
    │ └── dkb
    │ └── 2019
    │ ├── credit
    │ │ │── 01-jan.csv
    │ │ └── 02-feb.csv
    │ └── ec
    │ │── 01-jan.csv
    │ └── 02-feb.csv
    ├── poetry.lock
    └── pyproject.toml

    View Slide

  24. Step 1: Download bank data (CSV)

    View Slide

  25. Step 2: Convert .csv to .beancount

    View Slide

  26. Step 3: Append everything to
    main.beancount

    View Slide

  27. Step 4: Reports!

    View Slide

  28. bean-check main.beancount

    View Slide

  29. bean-report main.beancount balances
    siddhant@localhost ~/finances % bean-report main.beancount balances
    Assets:DKB 1450.00 EUR
    Income:BigCorp 3000.00 EUR
    Expenses:Rent -1500.00 EUR
    Expenses:Food 50.00 EUR

    View Slide

  30. bean-query main.beancount
    SELECT
    month, SUM(position)
    FROM
    year = 2019
    WHERE
    account ~ 'Expenses:Supermarket'
    GROUP BY month

    View Slide

  31. $ pip install fava

    View Slide

  32. View Slide

  33. View Slide

  34. main.beancount
    ; Date format - YYYY-MM-DD
    option "title" "Mustermann"
    option "operating_currency" "EUR"
    2019-10-01 open Assets:DKB
    2019-10-01 open Income:BigCorp
    2019-10-01 open Expenses:Food
    2019-10-01 open Expenses:Rent
    2019-10-25 "*" "Überweisung BigCorp"
    Assets:DKB 3000.00 EUR
    Income:BigCorp -3000.00 EUR
    2019-11-01 "*" "Miete"
    Assets:DKB -1500.00 EUR
    Expenses:Rent 1500.00 EUR
    2019-11-02 "*" "Essen"
    Assets:DKB -50.00 EUR
    Expenses:Food 50.00 EUR
    2019-10-26 balance Assets:DKB 3000.00 EUR
    2019-11-03 balance Expenses:Food 50.00 EUR

    View Slide

  35. config.py
    from beancount_dkb import ECImporter, CreditImporter
    CONFIG = (
    ECImporter(
    'DE99 9999 9999 9999 9999 99',
    'Assets:DKB',
    'EUR',
    file_encoding='ISO-8859-1',
    ),
    CreditImporter(
    '1234********5678',
    'Assets:DKB',
    'EUR',
    file_encoding='ISO-8859-1',
    ),
    )

    View Slide

  36. Importers for German banks
    pypi.org/project/beancount-dkb
    pypi.org/project/beancount-ing-diba
    pypi.org/project/beancount-commerzbank

    View Slide

  37. Sample Importer
    from beancount.core.amount import Amount
    from beancount.core.number import Number
    from beancount.ingest.importer import ImporterProtocol
    class SampleImporter(ImporterProtocol):
    # ...
    def identify(self, file_):
    """Check if file_ is from the bank we're supposed to work with
    """
    # ...
    def extract(self, file_):
    """Read file_, and emit a list of beancount data structures
    """

    View Slide

  38. Budgeting
    2012-01-01 custom "budget" Expenses:Coffee "daily" 4.00 EUR
    2013-01-01 custom "budget" Expenses:Books "weekly" 20.00 EUR
    2014-02-10 custom "budget" Expenses:Groceries "monthly" 40.00 EUR
    2015-05-01 custom "budget" Expenses:Electricity "quarterly" 85.00 EUR
    2016-06-01 custom "budget" Expenses:Holiday "yearly" 2500.00 EUR

    View Slide

  39. Resources
    https://plaintextaccounting.org
    https://www.reddit.com/r/plaintextaccounting
    https://awesome-beancount.com/
    https://aumayr.github.io/beancount-docs-static/
    https://beancount.github.io/fava/
    Slides
    https://bit.ly/sg-pymunich-2019

    View Slide

  40. Thanks for your time!
    bit.ly/sg-pymunich-2019
     /  @siddhantgoel
     sgoel.org

    View Slide