Giter Club home page Giter Club logo

lotter's Introduction

Notes

Forked from https://src.d10.dev/lotter

Original author also wrote a nice tutorial which can be found here: https://www.d10.dev/blog/ledger-cli-trade

Readme

Lotter is a command-line tool that works with trade data in ledger-cli format. While ledger-cli is a fantastic calculator for double-entry accounting, its support for lots, cost basis, and gains is rather limited. This tool is meant to provide a handful of features which (to the best of my knowledge) ledger-cli does not provide on its own.

To best understand lotter, it is recommended to first be familiar with ledger-cli. Also, read background articles "Multiple Currencies with Currency Trading Accounts", and Peter Selinger's "Tutorial on Multiple Currency Accounting".

Use lotter by first entering trade information into ledger-cli. Run lotter to add "lot" information, which enables ledger-cli to calculate cost basis and gains.

Simple Example

Let's say you purchased a cryptocurrency (we'll call it ABC), when it cost 2 cents. A ledger-cli entry could look like:

2016-01-01 Bought ABC
    Assets:Crypto          100 ABC @ 0.02 USD
    Equity:Cash

Later, ABC trades at $1, and you sell some. In ledger-cli:

2017-01-01 Sell some ABC
    Assets:Crypto          -1 ABC @ 1 USD
    Assets:Exchange

The idea of lotter is to add "splits" to these ledger entries. The added information captures the cost basis when a "lot" is created, and gains (losses) when inventory from a lot is sold. After lotter, the ledger entris look roughly like:

2016-01-01 Bought ABC
    Assets:Crypto                                100 ABC ; @ 0.02 USD
    Equity:Cash
    [Lot::2016/01/01:[email protected]]            -100 ABC
    [Lot::2016/01/01:[email protected]]            2 USD

2017-01-01 Sell some ABC
    Assets:Crypto                                 -1 ABC ; @ 1 USD
    Assets:Exchange
    [Lot::2016/01/01:[email protected]]            1 ABC
    [Lot::2016/01/01:[email protected]]            -0.02 USD
    [Lot:Income:long term gain]                  -0.98 USD

If your wondering why the last line ("long term gain") shows a negative number, when the actual gain is a positive 98 cents, recall that in ledger-cli's double-entry method, income is expressed in negative numbers while expenses are positive. Similarly in lotter, lot inventory and gain are negative numbers, cost basis is positive. This follows ledger-cli's rules, and makes lotter's splits net zero.

The transactions described above are in testdata/simple.ledger. To see the effects of lotter on these transactions, compare the normal use of ledger-cli,

ledger -f testdata/simple.ledger bal

with the effects of lotter,

lotter -f testdata/simple.ledger lot | ledger -f - bal

Operation: Lot

usage: lotter -f <filename> lot

The lot operation adds "splits" to transactions, representing lot inventory, cost basis, and gains.

Each lot is a ledger-cli "account", named by convention with prefix "Lot", followed by the date the lot was created, and inventory and cost information. This naming convention is intended to provide unique lot names. (It could fail to do so, if multiple purchases occur on the same day, for the same amount and cost.)

lotter considers a transaction to be a purchase when it finds a split for a positive amount, with cost information associated with it. When constructing your ledger entries, use for example "100 ABC @ 0.02 USD" or "100 ABC @@ 2 USD".

Similarly, lotter considers a transaction to be a sale when the amount is negative and has a cost associated. To these transactions, lotter adds splits that "consume" inventory (and basis) acquired earlier.

To see options available, run lotter help lot.

lotter's People

Contributors

div0man avatar

Watchers

 avatar  avatar

Forkers

jefdaj

lotter's Issues

Carrying date(s) when deferring gains

I tried to account for some stock splits and noticed that the date doesn't carry correctly. Here's an example:

2020-01-01 Equity
    Equity:Cash           -100.00 EUR
    Assets:Cash            100.00 EUR

2020-01-01 Buy AAA
    Assets:Cash           -100.00 EUR
    Assets:Stocks            1.00 AAA @@ 100 EUR

2020-02-01 Temporary commodity to hold the value
    Assets:Stocks           -1.00 AAA
    Assets:Stocks:Splits     1.00 TEMP @@ 1 AAA

2020-02-01 Stock split
    Assets:Stocks:Splits    -1.00 TEMP
    Assets:Stocks           10.00 AAA @@ 1 TEMP

P 2020-03-01 00:00:00 AAA 20 EUR
2020-03-01 Sell AAA
    Assets:Stocks           -5.00 AAA @@ 100 EUR
    Assets:Cash            100.00 EUR

Running lotter -f test.txt -base EUR lot | ledger -f - bal -X EUR -E I get:

          200.00 EUR  Assets
          100.00 EUR    Cash
          100.00 EUR    Stocks
                   0      Splits
         -100.00 EUR  Equity:Cash
         -100.00 EUR  Lot
          -50.00 EUR    
                   0      2020/01/01
                   0        1AAA@100EUR
                   0        1TEMP@1AAA@100EUR
          -50.00 EUR      2020/02/01:[email protected]@100EUR
          -50.00 EUR    Income:short term gain
--------------------
                   0

While it demonstrates the convenience of using lotter as a pre-processor, it produces wrong output for my use-case. Too bad :(

It correctly shows that I started with 100 EUR, then bought 1 AAA, which got split 10-for-1 into 10 AAA, later appreciated +100% at which point I took some gains, and am still holding 5 AAA worth 100 EUR with unrealized gains shown under that lot's account.

Judging by the original author's comments in the code here below

lotter/op_lot.go

Lines 697 to 700 in d99fcb7

// for purposes of long-term vs short term, use the
// latest date of the consumed inventory.
lotDate = l[j].date
// TODO(dnc): should deferred gains show date of this transaction, or date of earlier consumed lot?

I understand that the intent was to carry the date of the latest consumed inventory, but that's not what happens because the newly created lot is actually taking the date of the preceding transaction and not of the actual lot.

I think it should either preserve the oldest date(s) or set the date of newly created lot to the transaction date, so 2 modes of operation.

If old dates are to be carried forward, then lotter should create a new lot for each different input date, and can't merge them into a single one as it does now.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.