DISCLAIMER: I am not a financial professional and cannot give tax advice. This calculator is intended for sample purposes only. Always do your own calculations for your self assessment. I accept no responsibility for any errors this calculator produces.
cgtcalc
is a command line application written in Swift which calculates UK capital gains tax based on a set of transactions. You feed it an input list of transactions and it outputs a summary of each tax year's gain (or loss) and the details for the disposal events that make up the gain (or loss).
I developed this because I needed something that would take my transactions and calculate capitals gains tax. I wanted something which would check my manual working. I developed it in Swift because I wanted to see how building a console app in Swift was.
There are other excellent calculators out there, such as CGTCalculator, however I couldn't find one which did everything that I need. The missing piece seemed to be handling of fund equalisation payments and dividends that need to be accounted for in accumulation funds.
Currently the calculator supports the full range of matches of acquisitions to disposals for the current capital gains tax system, namely supporting matching based on the following rules in this order:
- Same day trades.
- Bed & breakfast trades where you purchase an asset within 30 days of selling the same asset.
- Section 104 holding.
The calculator specifically only deals with shares where the acquisition and disposals are all on or after 6th April 2008 when the latest rules came into effect.
It also supports handling of equalisation payments (capital return) for funds where those amounts should be subtracted from the acquisition proceeds. And it also supports handling of dividends within accumulation share classes of funds where those amounts can be subtracted from the disposal proceeds.
Currently there is no support for:
- Transactions before 6th April 2008.
- Anything I haven't thought of (as I say in the disclaimer - I am not a financial professional).
The library and console app that makes up cgtcalc
both work fully on both macOS and Linux. It's running on a Linux server at https://cgtcalc.galloway.me.uk/. However as of writing this, there's a very serious bug with Decimal
in Swift on Linux that means you should not use it there as you can easily end up in a situation where the calculations are wildly incorrect. The Swift bug can be tracked here: https://bugs.swift.org/browse/SR-13015
Using cgtcalc
is simple. All you need to do is the following:
- Clone the repository.
- Put your transactions into a file, such as
data.txt
. - Run
swift run cgtcalc data.txt
.
That's pretty much it. You'll then see output on your console showing the calculations and a summary for all tax years that have tax events in them. You can see more details about how it's being calculated if you pass the -v
flag.
Full usage can be found by running with -h
:
USAGE: cgtcalc <filename> [--verbose] [--output-file <output-file>]
ARGUMENTS:
<filename> The input data filename
OPTIONS:
-v, --verbose Enable verbose logging
-o, --output-file <output-file>
Output file
--version Show the version.
-h, --help Show help information.
Each row of the input file starts with the kind of data followed by details. For example a buy transaction, for 200 shares of LON:FOOBAR on 01/01/2020 at £1.50 with £20 expenses would be as follows:
BUY 01/01/2020 LON:FOOBAR 200 1.5 20
The full list of kinds of data are as follows:
Kind | Category | Description | Fields |
---|---|---|---|
BUY |
Transaction | Buy transaction | <DATE> <ASSET> <AMOUNT> <PRICE> <EXPENSES> |
SELL |
Transaction | Sell transaction | <DATE> <ASSET> <AMOUNT> <PRICE> <EXPENSES> |
CAPRETURN |
Asset event | Capital return event (usually for a fund on first dividend distribution after purchase) | <DATE> <ASSET> <AMOUNT> <VALUE> |
DIVIDEND |
Asset event | Dividend for which income tax has been taken but shares also retain (usually for fund accumulation share class) | <DATE> <ASSET> <AMOUNT> <VALUE> |
SPLIT |
Asset event | Stock split | <DATE> <ASSET> <MULTIPLIER> |
UNSPLIT |
Asset event | Stock un-split | <DATE> <ASSET> <MULTIPLIER> |
Given the following input in a file called data.txt
:
BUY 05/12/2019 GB00B41YBW71 500 4.7012 2
SELL 28/11/2019 GB00B41YBW71 2000 4.6702 12.5
BUY 28/08/2018 GB00B41YBW71 1000 4.1565 12.5
BUY 01/03/2018 GB00B41YBW71 1000 3.6093 2
The tool can be invoked like so:
swift run cgtcalc data.txt
And will output the following:
# SUMMARY
Tax year Gain Exemption Loss carry Taxable gain Tax (basic) Tax (higher)
======================================================================================
2019/2020 £1140 £12000 £0 £0 £0 £0
# TAX YEAR DETAILS
## TAX YEAR 2019/2020
1) SOLD 2000 of GB00B41YBW71 on 28/11/2019 for GAIN of £1140
Matches with:
- BED & BREAKFAST: 500 bought on 05/12/2019 at £4.7012
- SECTION 104: 2000 at cost basis of £3.89015
Calculation: (2000 * 4.6702 - 12.5) - ( (500 * 4.7012 + 2) + (1500 * 3.89015) ) = 1140
# TRANSACTIONS
05/12/2019 BOUGHT 500 of GB00B41YBW71 at £4.7012 with £2 expenses
28/11/2019 SOLD 2000 of GB00B41YBW71 at £4.6702 with £12.5 expenses
28/08/2018 BOUGHT 1000 of GB00B41YBW71 at £4.1565 with £12.5 expenses
01/03/2018 BOUGHT 1000 of GB00B41YBW71 at £3.6093 with £2 expenses
# ASSET EVENTS
NONE
cgtcalc
is broken into two parts:
- A library called
CGTCalcCore
which contains all of the calculation logic. - A simple console app called
cgtcalc
which usesCGTCalcCore
.
You can extend CGTCalcCore
in two interesting ways:
- Create a custom parser to parse from your own format into what
CGTCalcCore
requires. The default parser that comes with the library is calledDefaultParser
. - Create a custom presenter to process the output from
CGTCalcCore
and display it how you wish. The presenter that outputs in text format is calledTextPresenter
.
It's best to look at main.swift
to see how to use CGTCalcCore
. It's essentially as follows:
import CGTCalcCore
import Foundation
...
// Custom parser could be used here
let parser = DefaultParser()
let data = "... read from file ..."
let input = try parser.calculatorInput(fromData: data)
// Create calculator, feeding it the input created above, and then process it
let calculator = try Calculator(input: input, logger: logger)
let result = try calculator.process()
// Custom presenter could be used here
let presenter = TextPresenter(result: result)
let output = try presenter.process()
cgtcalc
includes a comprehensive test suite. The most interesting ones are in Tests/CGTCalcCoreTests/Examples. These are full end-to-end tests which have input data files and check against equivalent output files. Those are worth looking at to see how the calculator responds to given inputs.
If you like this and you'd like to buy me a coffee or a beer then I would say thank you and ask you to send to my PayPal.