derive_events
Distil ledger transactions into the taxable event stream (SPEC §9).
Per entry: Direction.IN yields an AcquisitionEvent with
cost=None, Direction.OUT a DisposalEvent with
proceeds=None. This module carries totals only when a caller
supplies them, so pricing stays out of the accounting layer.
Three things produce NO event at all:
Direction.SELFentries, moving your own coins is not income;- every entry of a transaction whose
idis ininternal_transfer_ids, the whole transaction is skipped, both legs, which is whatis_internal_transferis for; - every entry of a
removed=Truetransaction, a reorged-away transaction never happened.
at_ms is confirmed_at when it is not None, else
initiated_at (DECISIONS "Accounting event time"). The result is
sorted by at_ms STABLY, so entries sharing a timestamp keep the
order they arrived in. Replay is deterministic.
Parameters
transactionsrequired, Sequence[LedgerTransaction]none
internal_transfer_idsoptional, frozenset[str], default frozenset()none
Returns
tuple[AccountingEvent, ...]