No project description provided
Project description
Fiscal
A simple, systematic tax liability calculator
Fiscal is a simple, systematic tax calculator with soft-coded rate bands. Specifically, Fiscal aims to side-step the commonly-seen behaviour of using 'if' statements in tax calculators, and relying on hard-coded tax bands.
Fiscal, broken down
There are two key elements to Fiscal.
-
Bands - a stream of pairwise tuples (a threshold, a percentage) with an 'allocator'. The allocator dictates the manner in which taxable amounts are allocated between the threshold element of each band - the two predominant forms of allocator are provided:
- 'step', which reflects the most common allocation; and
- 'slab', which represents taxes for which the sole applicable rate is determined by the taxable amount (as in old stamp duty and early SDLT).
-
Liabilities - a calculation of liability stored in a 'breakdown' - a three-element tuple made up of:
- the amount allocated to the band;
- the percentage referable to that band; and
- the product of the amount and the percentage.
Allocators - examples
To draw an example from Stamp Duty Land Tax (SDLT), a land transfer tax in England (and previously throughout the UK).
SDLT - stepped calculation
The applicable bands for a commercial transaction were, after 17 March 2017, as follows:
| Threshold | Percentage |
|---|---|
| £150,000 | 0% |
| £100,000 | 2% |
| Surplus | 5% |
This can be represented by a band as follows:
stepped_bands = SteppedBands((150_000, 0),(100_000, 2),("Infinity", 5))
The bands are allocated on the step basis, so £1m would be allocated as follows:
| Threshold | Percentage | Liability |
|---|---|---|
| £150,000 | 0% | £0 |
| £100,000 | 2% | £2,000 |
| £750,000 | 5% | £37,500 |
allocation = stepped_bands.allocate(1_000_000)
assert allocation == (
(Decimal("150000"), Decimal("0")),
(Decimal("100000"), Decimal("2")),
(Decimal("750000"), Decimal("5")),
) # True
The allocation is intended to be called within an instance of the Liability object.
SDLT - slabbed calculation
Prior to 17 March 2017, the applicable SDLT rates for a commercial transaction were as follows:
| Threshold | Percentage |
|---|---|
| £150,000 | 0% |
| £100,000 | 1% |
| £250,000 | 3% |
| Surplus | 4% |
The bands were allocated on the 'slab' basis. This means that the taxable amount is compared with the cumulative thresholds, which are as follows:
| Cumulative Threshold | Percentage |
|---|---|
| £150,000 | 0% |
| £250,000 | 1% |
| £500,000 | 3% |
| Surplus | 4% |
The first cumulative threshold to equal or exceed the taxable amount determines the applicable percentage. So where the taxable amount was £200,000, the applicable percentage was 1%.
| Cumulative Threshold | Amount | Percentage |
|---|---|---|
| £150,000 | 0% | |
| £250,000 | £200,000 | 1% |
| £500,000 | 3% | |
| Surplus | 4% |
Where the taxable amount was £300,000, the applicable percentage was 3%.
| Cumulative Threshold | Amount | Percentage |
|---|---|---|
| £150,000 | 0% | |
| £250,000 | 1% | |
| £500,000 | £300,000 | 3% |
| Surplus | 4% |
Thresholds were inclusive, so where the taxable amount was £500,000, the applicable percentage was still 3%.
| Cumulative Threshold | Amount | Percentage |
|---|---|---|
| £150,000 | 0% | |
| £250,000 | 1% | |
| £500,000 | £500,000 | 3% |
| Surplus | 4% |
But where the taxable amount was £500,001, the applicable percentage was 4%.
| Cumulative Threshold | Amount | Percentage |
|---|---|---|
| £150,000 | 0% | |
| £250,000 | 1% | |
| £500,000 | 3% | |
| Surplus | £500,001 | 4% |
Liabilities - examples
Liabilities represent the calculation the follows the allocation of a taxable amount into the correct bands.
Those liabilities are then aggregated into a total liability. So by way of example, if calculating the current (9 February 2022) SDLT liability (non-residential property) for a £1m sum, the steps would be as follows.
bands = SteppedBands((150_000, 0),(100_000, 2),("Infinity", 5))
liab = Liability(bands=bands, amount=1_000_000)
The breakdown of liability would look as below:
assert liab.breakdown == (
(Decimal("150000"), Decimal("0"), Decimal("0")),
(Decimal("100000"), Decimal("2"), Decimal("2000")),
(Decimal("750000"), Decimal("5"), Decimal("37500")),
) # True
assert liab.total == Decimal("39500") # True
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fiscal-0.2.0.tar.gz.
File metadata
- Download URL: fiscal-0.2.0.tar.gz
- Upload date:
- Size: 5.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.3.1 CPython/3.11.1 Linux/5.15.0-58-generic
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f1c44b47d8400b3ceed780090001811e220b8697712f302ae4a5ee29c650403d
|
|
| MD5 |
93a5f03e4ea49ed11cdcaa0371db425f
|
|
| BLAKE2b-256 |
0e8f1905366164fa588b0a81570195ce1c703c98131de263020615421b0e3fd9
|
File details
Details for the file fiscal-0.2.0-py3-none-any.whl.
File metadata
- Download URL: fiscal-0.2.0-py3-none-any.whl
- Upload date:
- Size: 5.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.3.1 CPython/3.11.1 Linux/5.15.0-58-generic
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
16496a4fba5d7d51e7e87849a08c60babf3085574a8de7655a4c545afbb52481
|
|
| MD5 |
bad6ca197d3d78197fa42e1bd7f49577
|
|
| BLAKE2b-256 |
59086f1bc2ced0ab1ae1fea6aca06a61bab3e421445562e2f12be3b3662c635a
|