Skip to main content

Instrument Registry

Resolve and maintain canonical financial instrument records. instrument-reg maps ISINs, provider symbols, names, and other identifiers to a consistent local registry for Beancount and other financial workflows.

Why Use It

  • resolve an instrument from a flexible query like an ISIN, symbol, name, conid, or FX pair
  • keep a local instrument registry with explicit, predictable write paths
  • validate bundled and user-defined instrument data
  • fetch provider-backed details without giving up local registry precedence

Concepts

  • Canonical Name: The unique identifier used in Beancount ledgers (e.g., AAPL, CSPX).
  • ISIN: International Securities Identification Number (e.g., US0378331005). Primary identifier for many instruments.
  • FIGI: Financial Instrument Global Identifier.
  • Query: User input to resolve or add, such as an ISIN, provider symbol, name, conid, or FX pair.
  • Provider Symbol: Provider-specific market symbol (e.g., AAPL on Yahoo, CSPX.L on Yahoo).

Installation

Requires Python 3.14 or newer.

uv tool install instrument-registry

Install optional live-data providers when you want external resolution and verification:

uv tool install 'instrument-registry[providers]'

Configuration

The registry loads data from two sources:

  1. Bundled Data: Built-in instruments (ETFs, Stocks).
  2. User Data: Custom YAML files located at INSTRUMENT_REGISTRY_PATH.

Set the environment variable to point to your custom registry:

export INSTRUMENT_REGISTRY_PATH=~/path/to/my/registry

The registry recursively scans this directory for .yaml and .yml files.

Read precedence for CLI commands is:

  • user-defined registry paths first
  • bundled registry second

Write behavior for add is strict:

  • instrument-reg add writes only when INSTRUMENT_REGISTRY_PATH is set or --registry-path is passed
  • --registry-path is a command option, so pass it after the subcommand, for example instrument-reg add --registry-path ~/registry ...
  • if neither is set, the command fails instead of guessing a write location

Network lookup caching uses the platform cache directory by default. For sandboxed development or CI runs, you can override it with INSTRUMENT_REGISTRY_CACHE_DIR:

export INSTRUMENT_REGISTRY_CACHE_DIR=.cache/instrument-registry

Usage

Resolve a Query

Resolve a query from local registries first, then external providers if needed. Queries can be ISINs, provider symbols, names, IBKR conids, or common FX pairs.

instrument-reg resolve US0378331005

A new discovery is saved to the write target (see Configuration); --dry-run resolves without saving.

Automatic Currency Resolution

The resolver can derive common FX provider symbols when they are not already in your registry:

  • resolve EUR -> EURUSD=X
  • resolve EUR/JPY -> EURJPY=X
  • resolve USD/JPY -> JPY=X

This eliminates the need to manually define standard Forex pairs in your registry files.

With price verification (checks if price matches historical data):

instrument-reg resolve US0378331005 --date 2024-01-01 --price 185.00

Resolve Many Queries

resolve-batch reads query records from stdin (or --input-file): JSON objects, one per line or in an array, or another command's JSON envelope. Each record has isin, symbol, figi, currency, asset_class, and optionally target_price with target_date or price_on. The result has one entry per record, so failed records can be retried alone; any failed record exits 3.

ibkr-converter securities statement.xml | instrument-reg resolve-batch

Add an Instrument

Add a new instrument to your local registry.

add requires an explicit write target. Set INSTRUMENT_REGISTRY_PATH or pass --registry-path.

# Auto-fetch metadata — instrument type and asset class are inferred from the provider
instrument-reg add --registry-path ~/registry US0378331005 --fetch

# Manually specify all details (instrument-type and asset-class are required without --fetch)
INSTRUMENT_REGISTRY_PATH=~/registry instrument-reg add \
  --isin US0378331005 \
  --symbol AAPL \
  --instrument-type Stock \
  --asset-class Stock \
  --currency USD

Linting

Validate registry files and check for duplicates.

instrument-reg lint

Verify against live market data (checks if tickers are valid):

instrument-reg lint --verify

A registry error exits 80 (LINT_FAILED) with the full report still in data.

Fetch Metadata

Fetch details using local registries first, then provider lookup when needed.

instrument-reg fetch --isin US0378331005
instrument-reg fetch --symbol AAPL --price

Output and Exit Codes

The CLI runs on treaty: piped output is a JSON envelope ({"ok", "data", "error", "warnings", "meta"}) with the result under data, and a terminal gets plain text. add, resolve, and resolve-batch report an effect (created, updated, noop, or would_* on a dry run). Failures have their own exit codes: 2 bad arguments, 3 some batch records failed, 4 no write target configured, 5 no match, 6 symbol collision, 79 a live-data provider is not installed, 80 lint found registry errors. instrument-reg manifest and instrument-reg <command> --schema describe the commands for agents, and -v/-vv go after the command.

Command Summary

  • resolve: resolve a query from local registries first, then external providers
  • resolve-batch: resolve every query record read from stdin
  • add: add or update an instrument in an explicit user registry path
  • fetch: inspect provider details using local registry precedence first
  • lint: validate registry files and optionally verify live provider data

Programmatic Usage

You can use the registry in your Python scripts:

from pydantic_market_data.models import SecurityCriteria

from instrument_registry.registry import get_registry

# Initialize registry (loads bundled data + user data from env var)
reg = get_registry()

# 1. Resolve by ISIN
instrument = reg.find_by_isin("US0378331005")
if instrument:
    print(f"Name: {instrument.name}, Currency: {instrument.currency}")

# 2. Search by identifier fields
criteria = SecurityCriteria(symbol="AAPL")
candidates = reg.find_candidates(criteria)
for c in candidates:
    print(f"Found: {c.name} ({c.isin})")

# 3. Look up by provider symbol
# Note: Provider-symbol lookup requires the provider name
instrument = reg.find_by_ticker("yahoo", "AAPL")

Data Format (YAML)

instruments:
  - name: AAPL
    isin: US0378331005
    instrument_type: Stock
    asset_class: Stock
    currency: USD
    tickers:
      yahoo: AAPL
    validation_points:
      - date: "2024-01-01"
        price: 185.64

Contributing

  • Bundled Data: Submit a PR to add common instruments to src/instrument_registry/data/instruments/.
  • Providers: Implement new data sources in src/instrument_registry/finder.py by adding a class that implements the DataProvider protocol.

Metadata

Release files for instrument-registry 0.4.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for instrument-registry 0.4.1
File Size Uploaded
instrument_registry-0.4.1.tar.gz 30.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for instrument-registry 0.4.1
File Interpreter ABI Platform
instrument_registry-0.4.1-py3-none-any.whl Python 3 none any Details

Total release size: 67.7 kB

Release files / instrument_registry-0.4.1.tar.gz

Download URL instrument_registry-0.4.1.tar.gz
Size 30.2 kB
Tags Source
SHA-256 checksum
How to use checksums
3f81d7dcfa95042e60f33b16792155c71c8655ec248881ef970cd18ec2d46a46
BLAKE2b-256 checksum
How to use checksums
a58df6072e5259180f9d8ab1e5ffcb538d44774bf7f9b1a8e320cf425d1c47db
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.22 {"installer":{"name":"uv","version":"0.12.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / instrument_registry-0.4.1-py3-none-any.whl

Download URL instrument_registry-0.4.1-py3-none-any.whl
Size 37.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ca9b7f7b86176dec52a6162eb299fffee41b8aaf5e92937d0721a37c88644146
BLAKE2b-256 checksum
How to use checksums
ca661ee0e7d121b2fc824b2eee92442359be3a5e18e89e5959434a936ccb5b28
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.22 {"installer":{"name":"uv","version":"0.12.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

0.4.3

2 release files

0.4.2

2 release files

This release

0.4.1 This release

2 release files

0.3.0

2 release files

0.2.14

2 release files

0.2.13

2 release files

0.2.12

2 release files

0.2.9

2 release files

0.2.8

2 release files

0.2.7

2 release files

0.2.6

2 release files

0.2.5

2 release files

0.2.4

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page