zfin/docs/reference/config/transaction-log-srf.md
Emil Lerch 74fc219afd
All checks were successful
Generic zig build / build (push) Successful in 5m48s
Generic zig build / publish-macos (push) Successful in 11s
Generic zig build / deploy (push) Successful in 23s
add docs/guides
2026-06-22 14:53:53 -07:00

68 lines
3.1 KiB
Markdown

# `transaction_log.srf` reference
`transaction_log.srf` is an optional sibling of `portfolio.srf` that
declares real-world transactions which change how zfin interprets the
portfolio diff. In v1 it holds exactly one kind of record:
**transfers** -- money you moved between accounts you own.
## Why it exists
[`zfin contributions`](../cli/contributions.md) infers "new money" by
diffing your portfolio over time. A plain diff can't tell an external
contribution apart from an internal transfer, so moving (say) $50k from
one account to another would otherwise be **double-counted**: the
receiving account's new lots look like contributions while the sending
account's removed lots are ignored. Declaring the transfer here cancels
that out.
Missing file -> the matcher is a no-op; nothing changes.
## File format
One record per **destination**. A record pins the money to exactly one
landing spot: either a specific lot (`SYMBOL@open_date`) or the literal
token `cash`. A sweep that lands in several lots becomes several records
sharing the same `(date, from, to)` but differing in `dest_lot`.
```srf
#!srfv1
# Simple cash transfer between two accounts
transfer::2026-05-02,type::cash,amount:num:5000,from::Sample IRA,to::Sample Brokerage,dest_lot::cash
# Transfer that was invested into a single stock lot on arrival
transfer::2026-05-02,type::cash,amount:num:7000,from::Sample IRA,to::Sample Brokerage,dest_lot::VTI@2026-05-03
# Sweep into a basket plus a cash residual (two records, same date/from/to)
transfer::2026-05-02,type::cash,amount:num:145300,from::Sample IRA,to::Sample Brokerage,dest_lot::VTI@2026-05-03
transfer::2026-05-02,type::cash,amount:num:4700,from::Sample IRA,to::Sample Brokerage,dest_lot::cash
```
## Fields
| Field | Type | Required | Description |
|------------|--------|----------|---------------------------------------------------------------------|
| `transfer` | date | Yes | Transfer date (`YYYY-MM-DD`); the record key. |
| `type` | string | Yes | `cash` or `in_kind` (see v1 scope below). |
| `amount` | num | Yes | Dollar amount transferred to this destination. |
| `from` | string | Yes | Source account name (matches an `account::` in your portfolio). |
| `to` | string | Yes | Destination account name. |
| `dest_lot` | string | Yes | Where it landed: `cash`, or `SYMBOL@YYYY-MM-DD` for a specific lot. |
## v1 scope and limits
- Only `transfer::` records. Buys, sells, and dividends stay inferred
from the portfolio diff.
- Only `type::cash` is wired into the contributions classifier.
`type::in_kind` parses (the format is forward-compatible) but the
matcher rejects it with an "in-kind transfers not yet supported"
message.
- Forward-looking only -- there is no historical reconstruction.
## See also
- [Track contributions](../../guides/track-contributions.md) -- the walkthrough.
- [`zfin contributions`](../cli/contributions.md) -- the command that consumes this file.
---
[Documentation home](../../README.md#reference)