Axiomatic

Cost Basis & Tax Lots

Track asset acquisitions as tax lots, select lots on disposal, and compute realized gains and losses.

Overview

When an entity acquires lot-tracked assets (equities, crypto, commodities), each acquisition is recorded as a tax lot — a record of the quantity, cost basis, and acquisition date. When those assets are later disposed of (sold, exchanged, or transferred out), the system selects which lots to consume and computes the realized gain or loss based on the difference between proceeds and cost basis.

Axiomatic supports three modes of lot creation and multiple lot selection methods, so it adapts to both broker-managed environments (traditional equities) and self-custody environments (crypto).

Lot Creation Modes

ModeSourceMethodWhen used
NativeNATIVEONCHAINLots created automatically by the posting engine when it processes acquisition events (e.g. crypto_received, investment_made)
ImportedIMPORTEDBROKER_REPORTEDLots imported from broker data (1099-B, CSV exports). Supports both open and already-disposed lots
ManualMANUALUSER_ENTEREDLots created by the user through the Tax Lots UI for assets not covered by automation

Native lots

When the posting engine processes an event that is classified as a lot acquisition event (e.g. crypto_received, investment_made, token_purchase), it automatically calls createLot() after the journal entry is created. The lot's cost basis is derived from the event payload's amount and quantity fields.

Imported lots

Broker-reported lots are imported via the API:

POST /api/tax-lots
{
  "action": "import",
  "entityId": "...",
  "bookId": "...",
  "brokerName": "Robinhood",
  "lots": [
    {
      "asset": "AAPL",
      "assetType": "EQUITY",
      "quantity": "100",
      "costBasis": "15000.00",
      "acquiredDate": "2024-03-15"
    },
    {
      "asset": "AAPL",
      "assetType": "EQUITY",
      "quantity": "50",
      "costBasis": "8500.00",
      "acquiredDate": "2024-01-10",
      "disposedDate": "2024-11-20",
      "proceeds": "9200.00"
    }
  ]
}

When disposedDate and proceeds are provided, the lot is created as FULLY_DISPOSED and a corresponding disposal record is inserted with the realized gain/loss already computed.

This is the recommended path for traditional brokerage accounts where the broker determines lot selection and reports results on tax forms.

Manual lots

Users can create lots manually through the Tax Lots inventory page for edge cases not covered by automation or imports.

Lot Selection Methods

When assets are disposed of, the system must decide which lots to consume. The method is configured per book via the costBasisMethod field:

MethodBehavior
FIFOFirst In, First Out — oldest lots are consumed first
LIFOLast In, First Out — newest lots are consumed first
HIFOHighest In, First Out — lots with the highest cost basis per unit are consumed first (tax-optimizing)
SPECIFICUser selects exactly which lots to consume via the lot picker UI
WEIGHTED_AVERAGEAll open lots for the asset are averaged into a single effective cost basis per unit

The default method for new books is FIFO.

Disposal flow

When the posting engine processes a lot disposal event (e.g. crypto_sent, investment_sold), it:

  1. Finds all open lots for the asset in the book
  2. Sorts them according to the book's costBasisMethod
  3. Consumes lots in order until the disposal quantity is fulfilled
  4. Creates lot_disposals records for each consumed lot (or portion)
  5. Computes realizedGainLoss = totalProceeds - costBasisDisposed for each disposal
  6. Determines holding period (short-term if held < 1 year, long-term otherwise)
  7. Appends realized gain/loss journal lines to the journal entry

Partial lot consumption

A single lot can be partially consumed across multiple disposals. The remainingQuantity field tracks how much is left. A lot's status transitions from OPENPARTIALLY_DISPOSEDFULLY_DISPOSED as its remaining quantity decreases.

Holding Period

The holding period is determined automatically based on the time between acquisition and disposal:

  • Short-term: held for less than one year (≤ 365 days)
  • Long-term: held for one year or more (> 365 days)

This classification affects tax treatment — long-term gains are typically taxed at lower rates.

Tax Lots UI

The Tax Lots page (/tax-lots) provides:

  • Summary cards — total realized gain/loss, short-term vs. long-term breakdown, and total disposals count
  • By Asset tab — per-asset summary showing total quantity, remaining quantity, cost basis, and open/disposed lot counts
  • All Lots tab — full inventory of every tax lot with status, quantities, and cost basis details
  • Disposals tab — history of all disposals with proceeds, gain/loss, and holding period
  • Record Disposal — modal form for manually recording a disposal, with lot picker for SPECIFIC identification method

Data Model

tax_lots

ColumnTypeDescription
iduuidPrimary key
entity_iduuidOwning entity
book_iduuidOwning book
assettextAsset symbol (e.g. ETH, AAPL)
asset_typeenumEQUITY, CRYPTO, FIXED_INCOME, COMMODITY, DERIVATIVE, REAL_ESTATE, OTHER
quantitydecimalOriginal acquisition quantity
remaining_quantitydecimalQuantity not yet disposed
cost_basis_per_unitdecimalPer-unit acquisition cost
total_cost_basisdecimalTotal cost (quantity × per-unit cost)
acquired_datedateAcquisition date
sourceenumNATIVE, IMPORTED, MANUAL
methodenumONCHAIN, BROKER_REPORTED, USER_ENTERED
statusenumOPEN, PARTIALLY_DISPOSED, FULLY_DISPOSED
event_iduuidOriginating event (nullable)
external_reftextBroker lot reference (nullable)

lot_disposals

ColumnTypeDescription
iduuidPrimary key
lot_iduuidFK to tax_lots
entity_iduuidOwning entity
book_iduuidOwning book
quantity_disposeddecimalQuantity consumed from the lot
proceeds_per_unitdecimalSale price per unit
total_proceedsdecimalTotal sale proceeds
cost_basis_disposeddecimalCost basis of the consumed quantity
realized_gain_lossdecimalProceeds minus cost basis
holding_periodenumSHORT_TERM or LONG_TERM
disposal_datedateDate of disposal
methodenumSelection method used (FIFO, LIFO, etc.)
event_iduuidOriginating event (nullable)

books.cost_basis_method

The cost_basis_method column on the books table sets the default lot selection method for the book. Values: FIFO, LIFO, HIFO, SPECIFIC, WEIGHTED_AVERAGE. Defaults to FIFO.

Tax Reporting

Axiomatic generates IRS-format capital gains reports from lot disposal data.

Schedule D

The Schedule D report (/api/tax-reports?report=schedule_d) summarizes capital gains and losses for a tax year, split into:

  • Part I — Short-term capital gains and losses (assets held one year or less)
  • Part II — Long-term capital gains and losses (assets held more than one year)

Each part shows total proceeds, total cost basis, and net gain/loss. A summary section shows the combined net capital gain or loss.

Form 8949

The Form 8949 report (/api/tax-reports?report=form_8949) provides per-disposal detail rows with:

  • Description (quantity and asset symbol)
  • Date acquired
  • Date sold or disposed
  • Proceeds (sale price)
  • Cost or other basis
  • Gain or loss

Rows are grouped by holding period (short-term vs. long-term).

PDF Export

The Schedule D report supports PDF export via format=pdf. The generated PDF includes headers with entity name, tax year, and book type, and is formatted for print or filing.

API

GET /api/tax-reports?entityId=...&bookId=...&report=schedule_d&taxYear=2025
GET /api/tax-reports?entityId=...&bookId=...&report=schedule_d&taxYear=2025&format=pdf
GET /api/tax-reports?entityId=...&bookId=...&report=form_8949&taxYear=2025

On this page