Skip to content

Cost Basis Methods

Supported methods

MethodIDCountryNotes
First In, First OutFIFO🌍Oldest lots sold first (IRS default)
Last In, First OutLIFO🌍Must elect Specific ID (IRS)
Highest In, First OutHIFO🌍Must elect Specific ID (IRS)
Specific IDSPECIFIC_ID🌍Manual lot selection
Germany FIFOGERMANY_FIFO🇩🇪§23 EStG, 1-year holding exemption
PMPAPMPA🇫🇷Plus-value mobilière, weighted average
Total AverageTOTAL_AVERAGE🌍Average cost basis
UK Share PoolingUK_SHARE_POOLING🇬🇧Section 104 pool + 30-day rule
AU CGT DiscountAU_CGT_DISCOUNT🇦🇺FIFO + 50% discount on long-term gains (ATO s.115)
CA ACBCA_ACB🇨🇦Weighted average Adjusted Cost Base (CRA IT-387R2)
KR Virtual AssetKR_VIRTUAL_ASSET🇰🇷FIFO; 22% flat rate + KRW 2.5M exemption at report layer
IN VDAIN_VDA🇮🇳FIFO; losses not deductible (s.115BBH)
ES CGTES_CGT🇪🇸FIFO; tiered 19–27% rates at report layer

IRS note

The IRS allows FIFO and Specific Identification for crypto (Rev. Rul. 2023-14). LIFO and HIFO are technically Specific ID strategies — you must maintain lot-level records and consistently apply your method.

Usage

import { computeGains, compareAllMethods } from '@dtax/tax-engine';
// Single method
const result = computeGains(transactions, {
method: 'FIFO',
taxYear: 2024,
});
// Compare all comparable methods (excludes SPECIFIC_ID)
const comparison = compareAllMethods(transactions, 2024);
comparison.forEach(({ method, totalGain, recommendation }) => {
console.log(`${method}: $${totalGain} ${recommendation ? '← recommended' : ''}`);
});

Result shape

interface GainResult {
shortTermGain: number;
longTermGain: number;
totalGain: number;
disposals: Disposal[];
unrealizedGain?: number;
}