[
{
"name": "HMRC CG51590 example: 30-day match gains 60, then the pool costs 2,200 of 2,500 shares at 3,256",
"args": [
[
{
"date": "2006-04-15",
"kind": "buy",
"quantity": 1000,
"amount": {
"minor": 130000,
"currency": "GBP"
}
},
{
"date": "2006-08-04",
"kind": "buy",
"quantity": 1000,
"amount": {
"minor": 145000,
"currency": "GBP"
}
},
{
"date": "2007-01-19",
"kind": "buy",
"quantity": 500,
"amount": {
"minor": 95000,
"currency": "GBP"
}
},
{
"date": "2010-03-16",
"kind": "sell",
"quantity": 2000,
"amount": {
"minor": 685000,
"currency": "GBP"
}
},
{
"date": "2010-04-07",
"kind": "buy",
"quantity": 2000,
"amount": {
"minor": 679000,
"currency": "GBP"
}
},
{
"date": "2010-12-10",
"kind": "sell",
"quantity": 2200,
"amount": {
"minor": 770000,
"currency": "GBP"
}
}
]
],
"expect": {
"disposals": [
{
"date": "2010-03-16",
"quantity": 2000,
"proceeds": {
"minor": 685000,
"currency": "GBP"
},
"allowableCost": {
"minor": 679000,
"currency": "GBP"
},
"gain": {
"minor": 6000,
"currency": "GBP"
},
"matches": [
{
"rule": "bed-and-breakfast",
"acquisitionDate": "2010-04-07",
"quantity": 2000,
"proceeds": {
"minor": 685000,
"currency": "GBP"
},
"cost": {
"minor": 679000,
"currency": "GBP"
},
"gain": {
"minor": 6000,
"currency": "GBP"
}
}
]
},
{
"date": "2010-12-10",
"quantity": 2200,
"proceeds": {
"minor": 770000,
"currency": "GBP"
},
"allowableCost": {
"minor": 325600,
"currency": "GBP"
},
"gain": {
"minor": 444400,
"currency": "GBP"
},
"matches": [
{
"rule": "section-104",
"acquisitionDate": null,
"quantity": 2200,
"proceeds": {
"minor": 770000,
"currency": "GBP"
},
"cost": {
"minor": 325600,
"currency": "GBP"
},
"gain": {
"minor": 444400,
"currency": "GBP"
}
}
]
}
],
"poolQuantity": 300,
"poolCost": {
"minor": 44400,
"currency": "GBP"
}
}
},
{
"name": "HMRC HS284 example 2: 500 matched with shares bought 12 days later at a 100 loss, 3,500 from the pool",
"args": [
[
{
"date": "2020-01-10",
"kind": "buy",
"quantity": 9500,
"amount": {
"minor": 950000,
"currency": "GBP"
}
},
{
"date": "2024-08-30",
"kind": "sell",
"quantity": 4000,
"amount": {
"minor": 600000,
"currency": "GBP"
}
},
{
"date": "2024-09-11",
"kind": "buy",
"quantity": 500,
"amount": {
"minor": 85000,
"currency": "GBP"
}
}
]
],
"expect": {
"disposals": [
{
"date": "2024-08-30",
"quantity": 4000,
"proceeds": {
"minor": 600000,
"currency": "GBP"
},
"allowableCost": {
"minor": 435000,
"currency": "GBP"
},
"gain": {
"minor": 165000,
"currency": "GBP"
},
"matches": [
{
"rule": "bed-and-breakfast",
"acquisitionDate": "2024-09-11",
"quantity": 500,
"proceeds": {
"minor": 75000,
"currency": "GBP"
},
"cost": {
"minor": 85000,
"currency": "GBP"
},
"gain": {
"minor": -10000,
"currency": "GBP"
}
},
{
"rule": "section-104",
"acquisitionDate": null,
"quantity": 3500,
"proceeds": {
"minor": 525000,
"currency": "GBP"
},
"cost": {
"minor": 350000,
"currency": "GBP"
},
"gain": {
"minor": 175000,
"currency": "GBP"
}
}
]
}
],
"poolQuantity": 6000,
"poolCost": {
"minor": 600000,
"currency": "GBP"
}
}
},
{
"name": "same-day purchase is matched before the pool, and the day's sales are one disposal",
"args": [
[
{
"date": "2020-01-01",
"kind": "buy",
"quantity": 1000,
"amount": {
"minor": 100000,
"currency": "GBP"
}
},
{
"date": "2021-05-10",
"kind": "sell",
"quantity": 200,
"amount": {
"minor": 40000,
"currency": "GBP"
}
},
{
"date": "2021-05-10",
"kind": "buy",
"quantity": 200,
"amount": {
"minor": 30000,
"currency": "GBP"
}
},
{
"date": "2021-05-10",
"kind": "sell",
"quantity": 300,
"amount": {
"minor": 60000,
"currency": "GBP"
}
}
]
],
"expect": {
"disposals": [
{
"date": "2021-05-10",
"quantity": 500,
"proceeds": {
"minor": 100000,
"currency": "GBP"
},
"allowableCost": {
"minor": 60000,
"currency": "GBP"
},
"gain": {
"minor": 40000,
"currency": "GBP"
},
"matches": [
{
"rule": "same-day",
"acquisitionDate": "2021-05-10",
"quantity": 200,
"proceeds": {
"minor": 40000,
"currency": "GBP"
},
"cost": {
"minor": 30000,
"currency": "GBP"
},
"gain": {
"minor": 10000,
"currency": "GBP"
}
},
{
"rule": "section-104",
"acquisitionDate": null,
"quantity": 300,
"proceeds": {
"minor": 60000,
"currency": "GBP"
},
"cost": {
"minor": 30000,
"currency": "GBP"
},
"gain": {
"minor": 30000,
"currency": "GBP"
}
}
]
}
],
"poolQuantity": 700,
"poolCost": {
"minor": 70000,
"currency": "GBP"
}
}
},
{
"name": "a purchase on day 30 after the sale is matched",
"args": [
[
{
"date": "2021-01-01",
"kind": "buy",
"quantity": 100,
"amount": {
"minor": 10000,
"currency": "GBP"
}
},
{
"date": "2022-06-01",
"kind": "sell",
"quantity": 100,
"amount": {
"minor": 20000,
"currency": "GBP"
}
},
{
"date": "2022-07-01",
"kind": "buy",
"quantity": 100,
"amount": {
"minor": 15000,
"currency": "GBP"
}
}
]
],
"expect": {
"disposals": [
{
"date": "2022-06-01",
"quantity": 100,
"proceeds": {
"minor": 20000,
"currency": "GBP"
},
"allowableCost": {
"minor": 15000,
"currency": "GBP"
},
"gain": {
"minor": 5000,
"currency": "GBP"
},
"matches": [
{
"rule": "bed-and-breakfast",
"acquisitionDate": "2022-07-01",
"quantity": 100,
"proceeds": {
"minor": 20000,
"currency": "GBP"
},
"cost": {
"minor": 15000,
"currency": "GBP"
},
"gain": {
"minor": 5000,
"currency": "GBP"
}
}
]
}
],
"poolQuantity": 100,
"poolCost": {
"minor": 10000,
"currency": "GBP"
}
}
},
{
"name": "a purchase on day 31 after the sale goes to the pool instead",
"args": [
[
{
"date": "2021-01-01",
"kind": "buy",
"quantity": 100,
"amount": {
"minor": 10000,
"currency": "GBP"
}
},
{
"date": "2022-06-01",
"kind": "sell",
"quantity": 100,
"amount": {
"minor": 20000,
"currency": "GBP"
}
},
{
"date": "2022-07-02",
"kind": "buy",
"quantity": 100,
"amount": {
"minor": 15000,
"currency": "GBP"
}
}
]
],
"expect": {
"disposals": [
{
"date": "2022-06-01",
"quantity": 100,
"proceeds": {
"minor": 20000,
"currency": "GBP"
},
"allowableCost": {
"minor": 10000,
"currency": "GBP"
},
"gain": {
"minor": 10000,
"currency": "GBP"
},
"matches": [
{
"rule": "section-104",
"acquisitionDate": null,
"quantity": 100,
"proceeds": {
"minor": 20000,
"currency": "GBP"
},
"cost": {
"minor": 10000,
"currency": "GBP"
},
"gain": {
"minor": 10000,
"currency": "GBP"
}
}
]
}
],
"poolQuantity": 100,
"poolCost": {
"minor": 15000,
"currency": "GBP"
}
}
},
{
"name": "a purchase before the sale is never bed-and-breakfast: it joins the pool at average cost",
"args": [
[
{
"date": "2021-01-01",
"kind": "buy",
"quantity": 100,
"amount": {
"minor": 10000,
"currency": "GBP"
}
},
{
"date": "2022-05-20",
"kind": "buy",
"quantity": 100,
"amount": {
"minor": 30000,
"currency": "GBP"
}
},
{
"date": "2022-06-01",
"kind": "sell",
"quantity": 100,
"amount": {
"minor": 25000,
"currency": "GBP"
}
}
]
],
"expect": {
"disposals": [
{
"date": "2022-06-01",
"quantity": 100,
"proceeds": {
"minor": 25000,
"currency": "GBP"
},
"allowableCost": {
"minor": 20000,
"currency": "GBP"
},
"gain": {
"minor": 5000,
"currency": "GBP"
},
"matches": [
{
"rule": "section-104",
"acquisitionDate": null,
"quantity": 100,
"proceeds": {
"minor": 25000,
"currency": "GBP"
},
"cost": {
"minor": 20000,
"currency": "GBP"
},
"gain": {
"minor": 5000,
"currency": "GBP"
}
}
]
}
],
"poolQuantity": 100,
"poolCost": {
"minor": 20000,
"currency": "GBP"
}
}
},
{
"name": "the earlier disposal takes the later purchase first (s106A(5)); a pool-first reading gets both wrong",
"args": [
[
{
"date": "2019-01-01",
"kind": "buy",
"quantity": 1000,
"amount": {
"minor": 100000,
"currency": "GBP"
}
},
{
"date": "2023-03-01",
"kind": "sell",
"quantity": 300,
"amount": {
"minor": 60000,
"currency": "GBP"
}
},
{
"date": "2023-03-10",
"kind": "sell",
"quantity": 300,
"amount": {
"minor": 60000,
"currency": "GBP"
}
},
{
"date": "2023-03-20",
"kind": "buy",
"quantity": 400,
"amount": {
"minor": 100000,
"currency": "GBP"
}
}
]
],
"expect": {
"disposals": [
{
"date": "2023-03-01",
"quantity": 300,
"proceeds": {
"minor": 60000,
"currency": "GBP"
},
"allowableCost": {
"minor": 75000,
"currency": "GBP"
},
"gain": {
"minor": -15000,
"currency": "GBP"
},
"matches": [
{
"rule": "bed-and-breakfast",
"acquisitionDate": "2023-03-20",
"quantity": 300,
"proceeds": {
"minor": 60000,
"currency": "GBP"
},
"cost": {
"minor": 75000,
"currency": "GBP"
},
"gain": {
"minor": -15000,
"currency": "GBP"
}
}
]
},
{
"date": "2023-03-10",
"quantity": 300,
"proceeds": {
"minor": 60000,
"currency": "GBP"
},
"allowableCost": {
"minor": 45000,
"currency": "GBP"
},
"gain": {
"minor": 15000,
"currency": "GBP"
},
"matches": [
{
"rule": "bed-and-breakfast",
"acquisitionDate": "2023-03-20",
"quantity": 100,
"proceeds": {
"minor": 20000,
"currency": "GBP"
},
"cost": {
"minor": 25000,
"currency": "GBP"
},
"gain": {
"minor": -5000,
"currency": "GBP"
}
},
{
"rule": "section-104",
"acquisitionDate": null,
"quantity": 200,
"proceeds": {
"minor": 40000,
"currency": "GBP"
},
"cost": {
"minor": 20000,
"currency": "GBP"
},
"gain": {
"minor": 20000,
"currency": "GBP"
}
}
]
}
],
"poolQuantity": 800,
"poolCost": {
"minor": 80000,
"currency": "GBP"
}
}
},
{
"name": "a same-day match outranks a 30-day match for an earlier sale",
"args": [
[
{
"date": "2018-01-01",
"kind": "buy",
"quantity": 500,
"amount": {
"minor": 50000,
"currency": "GBP"
}
},
{
"date": "2023-05-01",
"kind": "sell",
"quantity": 100,
"amount": {
"minor": 20000,
"currency": "GBP"
}
},
{
"date": "2023-05-10",
"kind": "buy",
"quantity": 100,
"amount": {
"minor": 15000,
"currency": "GBP"
}
},
{
"date": "2023-05-10",
"kind": "sell",
"quantity": 100,
"amount": {
"minor": 18000,
"currency": "GBP"
}
}
]
],
"expect": {
"disposals": [
{
"date": "2023-05-01",
"quantity": 100,
"proceeds": {
"minor": 20000,
"currency": "GBP"
},
"allowableCost": {
"minor": 10000,
"currency": "GBP"
},
"gain": {
"minor": 10000,
"currency": "GBP"
},
"matches": [
{
"rule": "section-104",
"acquisitionDate": null,
"quantity": 100,
"proceeds": {
"minor": 20000,
"currency": "GBP"
},
"cost": {
"minor": 10000,
"currency": "GBP"
},
"gain": {
"minor": 10000,
"currency": "GBP"
}
}
]
},
{
"date": "2023-05-10",
"quantity": 100,
"proceeds": {
"minor": 18000,
"currency": "GBP"
},
"allowableCost": {
"minor": 15000,
"currency": "GBP"
},
"gain": {
"minor": 3000,
"currency": "GBP"
},
"matches": [
{
"rule": "same-day",
"acquisitionDate": "2023-05-10",
"quantity": 100,
"proceeds": {
"minor": 18000,
"currency": "GBP"
},
"cost": {
"minor": 15000,
"currency": "GBP"
},
"gain": {
"minor": 3000,
"currency": "GBP"
}
}
]
}
],
"poolQuantity": 400,
"poolCost": {
"minor": 40000,
"currency": "GBP"
}
}
},
{
"name": "pool cost is apportioned to the penny, half-up, and the pool keeps the remainder",
"args": [
[
{
"date": "2019-01-01",
"kind": "buy",
"quantity": 3,
"amount": {
"minor": 1000,
"currency": "GBP"
}
},
{
"date": "2020-01-01",
"kind": "sell",
"quantity": 1,
"amount": {
"minor": 500,
"currency": "GBP"
}
},
{
"date": "2020-02-01",
"kind": "sell",
"quantity": 1,
"amount": {
"minor": 500,
"currency": "GBP"
}
}
]
],
"expect": {
"disposals": [
{
"date": "2020-01-01",
"quantity": 1,
"proceeds": {
"minor": 500,
"currency": "GBP"
},
"allowableCost": {
"minor": 333,
"currency": "GBP"
},
"gain": {
"minor": 167,
"currency": "GBP"
},
"matches": [
{
"rule": "section-104",
"acquisitionDate": null,
"quantity": 1,
"proceeds": {
"minor": 500,
"currency": "GBP"
},
"cost": {
"minor": 333,
"currency": "GBP"
},
"gain": {
"minor": 167,
"currency": "GBP"
}
}
]
},
{
"date": "2020-02-01",
"quantity": 1,
"proceeds": {
"minor": 500,
"currency": "GBP"
},
"allowableCost": {
"minor": 334,
"currency": "GBP"
},
"gain": {
"minor": 166,
"currency": "GBP"
},
"matches": [
{
"rule": "section-104",
"acquisitionDate": null,
"quantity": 1,
"proceeds": {
"minor": 500,
"currency": "GBP"
},
"cost": {
"minor": 334,
"currency": "GBP"
},
"gain": {
"minor": 166,
"currency": "GBP"
}
}
]
}
],
"poolQuantity": 1,
"poolCost": {
"minor": 333,
"currency": "GBP"
}
}
},
{
"name": "proceeds are apportioned across matches by shares, the last match taking the remainder",
"args": [
[
{
"date": "2019-01-01",
"kind": "buy",
"quantity": 2,
"amount": {
"minor": 900,
"currency": "GBP"
}
},
{
"date": "2020-03-03",
"kind": "buy",
"quantity": 1,
"amount": {
"minor": 400,
"currency": "GBP"
}
},
{
"date": "2020-03-03",
"kind": "sell",
"quantity": 3,
"amount": {
"minor": 1000,
"currency": "GBP"
}
}
]
],
"expect": {
"disposals": [
{
"date": "2020-03-03",
"quantity": 3,
"proceeds": {
"minor": 1000,
"currency": "GBP"
},
"allowableCost": {
"minor": 1300,
"currency": "GBP"
},
"gain": {
"minor": -300,
"currency": "GBP"
},
"matches": [
{
"rule": "same-day",
"acquisitionDate": "2020-03-03",
"quantity": 1,
"proceeds": {
"minor": 333,
"currency": "GBP"
},
"cost": {
"minor": 400,
"currency": "GBP"
},
"gain": {
"minor": -67,
"currency": "GBP"
}
},
{
"rule": "section-104",
"acquisitionDate": null,
"quantity": 2,
"proceeds": {
"minor": 667,
"currency": "GBP"
},
"cost": {
"minor": 900,
"currency": "GBP"
},
"gain": {
"minor": -233,
"currency": "GBP"
}
}
]
}
],
"poolQuantity": 0,
"poolCost": {
"minor": 0,
"currency": "GBP"
}
}
},
{
"name": "selling the whole holding at a loss empties the pool",
"args": [
[
{
"date": "2015-06-01",
"kind": "buy",
"quantity": 250,
"amount": {
"minor": 500000,
"currency": "GBP"
}
},
{
"date": "2016-06-01",
"kind": "buy",
"quantity": 250,
"amount": {
"minor": 300000,
"currency": "GBP"
}
},
{
"date": "2024-11-01",
"kind": "sell",
"quantity": 500,
"amount": {
"minor": 650000,
"currency": "GBP"
}
}
]
],
"expect": {
"disposals": [
{
"date": "2024-11-01",
"quantity": 500,
"proceeds": {
"minor": 650000,
"currency": "GBP"
},
"allowableCost": {
"minor": 800000,
"currency": "GBP"
},
"gain": {
"minor": -150000,
"currency": "GBP"
},
"matches": [
{
"rule": "section-104",
"acquisitionDate": null,
"quantity": 500,
"proceeds": {
"minor": 650000,
"currency": "GBP"
},
"cost": {
"minor": 800000,
"currency": "GBP"
},
"gain": {
"minor": -150000,
"currency": "GBP"
}
}
]
}
],
"poolQuantity": 0,
"poolCost": {
"minor": 0,
"currency": "GBP"
}
}
},
{
"name": "no transactions: no disposals and an empty pool",
"args": [
[]
],
"expect": {
"disposals": [],
"poolQuantity": 0,
"poolCost": {
"minor": 0,
"currency": "GBP"
}
}
},
{
"name": "purchases only build the pool, whenever they were made",
"args": [
[
{
"date": "1990-01-01",
"kind": "buy",
"quantity": 10,
"amount": {
"minor": 1234,
"currency": "GBP"
}
},
{
"date": "2025-01-01",
"kind": "buy",
"quantity": 5,
"amount": {
"minor": 5000,
"currency": "GBP"
}
}
]
],
"expect": {
"disposals": [],
"poolQuantity": 15,
"poolCost": {
"minor": 6234,
"currency": "GBP"
}
}
},
{
"name": "a purchase partly matched by bed-and-breakfast puts only its remainder into the pool",
"args": [
[
{
"date": "2021-01-01",
"kind": "buy",
"quantity": 100,
"amount": {
"minor": 10000,
"currency": "GBP"
}
},
{
"date": "2022-06-01",
"kind": "sell",
"quantity": 40,
"amount": {
"minor": 8000,
"currency": "GBP"
}
},
{
"date": "2022-06-15",
"kind": "buy",
"quantity": 100,
"amount": {
"minor": 30000,
"currency": "GBP"
}
},
{
"date": "2022-09-01",
"kind": "sell",
"quantity": 100,
"amount": {
"minor": 25000,
"currency": "GBP"
}
}
]
],
"expect": {
"disposals": [
{
"date": "2022-06-01",
"quantity": 40,
"proceeds": {
"minor": 8000,
"currency": "GBP"
},
"allowableCost": {
"minor": 12000,
"currency": "GBP"
},
"gain": {
"minor": -4000,
"currency": "GBP"
},
"matches": [
{
"rule": "bed-and-breakfast",
"acquisitionDate": "2022-06-15",
"quantity": 40,
"proceeds": {
"minor": 8000,
"currency": "GBP"
},
"cost": {
"minor": 12000,
"currency": "GBP"
},
"gain": {
"minor": -4000,
"currency": "GBP"
}
}
]
},
{
"date": "2022-09-01",
"quantity": 100,
"proceeds": {
"minor": 25000,
"currency": "GBP"
},
"allowableCost": {
"minor": 17500,
"currency": "GBP"
},
"gain": {
"minor": 7500,
"currency": "GBP"
},
"matches": [
{
"rule": "section-104",
"acquisitionDate": null,
"quantity": 100,
"proceeds": {
"minor": 25000,
"currency": "GBP"
},
"cost": {
"minor": 17500,
"currency": "GBP"
},
"gain": {
"minor": 7500,
"currency": "GBP"
}
}
]
}
],
"poolQuantity": 60,
"poolCost": {
"minor": 10500,
"currency": "GBP"
}
}
},
{
"name": "selling more than is held is refused",
"args": [
[
{
"date": "2021-01-01",
"kind": "buy",
"quantity": 100,
"amount": {
"minor": 10000,
"currency": "GBP"
}
},
{
"date": "2022-01-01",
"kind": "sell",
"quantity": 101,
"amount": {
"minor": 20000,
"currency": "GBP"
}
}
]
],
"expectError": "cannot sell more shares than are held"
},
{
"name": "a sale covered only by a later purchase (a short sale) is refused",
"args": [
[
{
"date": "2022-01-01",
"kind": "sell",
"quantity": 10,
"amount": {
"minor": 2000,
"currency": "GBP"
}
},
{
"date": "2022-01-05",
"kind": "buy",
"quantity": 10,
"amount": {
"minor": 1500,
"currency": "GBP"
}
}
]
],
"expectError": "cannot sell more shares than are held"
},
{
"name": "disposals before 6 April 2008 are refused",
"args": [
[
{
"date": "2007-01-01",
"kind": "buy",
"quantity": 10,
"amount": {
"minor": 1000,
"currency": "GBP"
}
},
{
"date": "2008-04-05",
"kind": "sell",
"quantity": 10,
"amount": {
"minor": 2000,
"currency": "GBP"
}
}
]
],
"expectError": "disposals before 2008-04-06 follow earlier identification rules"
},
{
"name": "transactions out of date order are refused",
"args": [
[
{
"date": "2021-02-01",
"kind": "buy",
"quantity": 10,
"amount": {
"minor": 1000,
"currency": "GBP"
}
},
{
"date": "2021-01-01",
"kind": "buy",
"quantity": 10,
"amount": {
"minor": 1000,
"currency": "GBP"
}
}
]
],
"expectError": "transactions must be in date order"
},
{
"name": "amounts must be in sterling",
"args": [
[
{
"date": "2021-01-01",
"kind": "buy",
"quantity": 10,
"amount": {
"minor": 1000,
"currency": "USD"
}
}
]
],
"expectError": "amounts must be in GBP"
},
{
"name": "a fractional quantity is refused",
"args": [
[
{
"date": "2021-01-01",
"kind": "buy",
"quantity": 2.5,
"amount": {
"minor": 1000,
"currency": "GBP"
}
}
]
],
"expectError": "quantity must be a whole number greater than zero"
},
{
"name": "a zero quantity is refused",
"args": [
[
{
"date": "2021-01-01",
"kind": "buy",
"quantity": 0,
"amount": {
"minor": 1000,
"currency": "GBP"
}
}
]
],
"expectError": "quantity must be a whole number greater than zero"
},
{
"name": "a negative amount is refused",
"args": [
[
{
"date": "2021-01-01",
"kind": "buy",
"quantity": 10,
"amount": {
"minor": -1,
"currency": "GBP"
}
}
]
],
"expectError": "amount must be a whole number of pence, not negative"
},
{
"name": "an unknown kind is refused",
"args": [
[
{
"date": "2021-01-01",
"kind": "gift",
"quantity": 10,
"amount": {
"minor": 1000,
"currency": "GBP"
}
}
]
],
"expectError": "kind must be buy or sell"
}
]