- Rust 99%
- Nix 1%
Bumps [toml](https://github.com/toml-rs/toml) from 0.8.23 to 1.1.2+spec-1.1.0. - [Commits](https://github.com/toml-rs/toml/compare/toml-v0.8.23...toml-v1.1.2) --- updated-dependencies: - dependency-name: toml dependency-version: 1.1.2+spec-1.1.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> |
||
|---|---|---|
| .github | ||
| img | ||
| src | ||
| templates | ||
| tests | ||
| .envrc | ||
| .gitignore | ||
| AGENTS.md | ||
| Cargo.lock | ||
| Cargo.toml | ||
| example_data.json | ||
| flake.lock | ||
| flake.nix | ||
| LICENSE | ||
| README.md | ||
| rustfmt.toml | ||

Local-first portfolio management for humans and AI agents — written in Rust.
portfolio_rs is a CLI + interactive TUI for tracking financial investment
portfolios, and a toolkit for the AI era: machine-readable investment
policies, policy-aware reviews, rebalancing simulations, durable financial
memory (diary, decisions, reports), a portable agent skill, and a local HTTP
API. It is also a Rust library that GUIs (e.g. a desktop app) can embed.
This project is the modern successor of finance.
Installation
Available in nixpkgs: nix-shell -p portfolio_rs or nix run nixpkgs#portfolio_rs
Install via pkgx: pkgx portfolio_rs
Install from cargo: cargo install portfolio_rs
Quick Start
Simple mode: a single positions file
Create a JSON file with your portfolio positions (see example data for the schema), then launch the TUI:
portfolio_rs my_positions.json
Workspace mode: a durable finance workspace
For the full experience — policies, diary, decisions, and reports — create a workspace:
portfolio_rs init-workspace my-portfolio
portfolio_rs policy init --strategy balanced-growth my-portfolio
portfolio_rs context my-portfolio/positions.json
This creates a directory with an INVESTMENT_POLICY.md (your financial
constitution), a machine-readable portfolio/policy.toml, folders for diary
entries, decision records, theses, and reports, agent instruction files
(AGENTS.md, CLAUDE.md), and a .gitignore that protects your private
data.
Commands
| Command | Description |
|---|---|
portfolio_rs [FILE] |
Interactive TUI (default) |
balances [FILE] |
Balances table with PnL |
allocation [FILE] |
Allocation pie chart and breakdown |
performance [FILE] |
Performance metrics (YTD, total return) |
sort [FILE] |
Positions sorted by value (display only) |
context [FILE] |
Agent-friendly portfolio briefing (Markdown/JSON) |
review [FILE] |
Policy-aware review: drift, violations, actions |
simulate [FILE] |
Rebalancing what-if scenarios (never trades) |
validate [FILE] |
Validate a portfolio JSON file |
policy init/validate |
Create/check a machine-readable policy.toml |
decision draft |
Draft a structured decision record |
report weekly |
Generate a weekly Markdown report |
doctor [DIR] |
Workspace health check |
init-workspace [DIR] |
Create a new finance workspace |
agent init/skill |
Agent instructions + portable skill management |
api |
Local HTTP API server |
mcp |
MCP server for agents (experimental preview) |
config |
Show config file location |
components |
List TUI components for --disable |
If no file is specified, commands use the portfolio file (or workspace) from
your config. Run portfolio_rs <COMMAND> --help for details.
AI & Agent Integration
portfolio_rs is designed to be operated by coding agents and LLMs, locally:
-
Structured output:
context,review, andsimulatesupport--format json(camelCase) for scripts and agents, and Markdown for humans and LLM prompts.portfolio_rs context positions.json --format json portfolio_rs review positions.json --policy portfolio/policy.toml --format json -
Machine-readable policy:
portfolio/policy.tomlencodes your goals, risk profile, target allocations, and constraints. Strategy templates:balanced-growth,capital-preservation,aggressive-growth,custom. -
Portable agent skill: install the built-in
portfolio-rsskill into any agent harness that supports skill files (opencode, Claude Code, Cursor, ...):portfolio_rs agent skill export ~/.config/opencode/skills -
Workspace instructions:
portfolio_rs agent initcreatesAGENTS.mdandCLAUDE.mdwith local paths and safety rules (no trades, no broker interaction, private data stays local). -
Durable memory: decisions and reports are plain Markdown files in your workspace — reviewable in six months, greppable forever. Use
--dry-runto preview any file mutation. -
MCP server (experimental):
portfolio_rs mcpstarts a JSON-RPC-over- stdio preview. Tools are advertised viatools/listbut currently return pointers to the equivalent CLI commands; a protocol-complete implementation is planned.
HTTP API
Serve your portfolio to local scripts, agents, and GUIs:
portfolio_rs api positions.json [--policy portfolio/policy.toml] [--host 127.0.0.1] [--port 3000]
| Endpoint | Description |
|---|---|
GET /health |
Liveness check |
GET /api/portfolio |
Full portfolio summary |
GET/POST /api/positions |
List / create positions |
GET/PUT/DELETE /api/positions/:id |
Read / update / delete a position |
GET /api/allocation |
Allocation breakdown |
GET /api/performance |
Performance metrics |
GET /api/context |
Agent briefing (JSON) |
GET /api/review |
Policy review (requires --policy) |
GET /api/simulate |
Rebalance simulation (requires --policy) |
GET /api/validate |
Portfolio file validation |
GET /api/doctor?dir=DIR |
Workspace health check |
POST /api/refresh |
Force a live quote refresh |
Notes:
- The API has no authentication and is intended for local use only; binding to a non-loopback host prints a loud warning.
- Position mutations are persisted back to the portfolio file — except for
.gpgfiles, which are never rewritten. - Live quotes are cached for a short TTL;
POST /api/refreshbypasses the cache.
Library Usage
The crate is also a library: state::AppState is an embedding-friendly
facade used by the HTTP API and external GUIs (e.g. a Tauri desktop app).
It loads portfolios/workspaces/policies, does position CRUD, and runs every
analysis (context, review, simulate, doctor, validate, reports) with
camelCase-serializable DTOs.
use portfolio_rs::AppState;
async fn total_value() -> eyre::Result<f64> {
let state = AppState::new("EUR".to_string());
state.load_file("positions.json").await?;
let summary = state.get_portfolio_summary().await;
Ok(summary.total_value)
}
TUI Features
The interactive Terminal User Interface (default mode) provides:
- Overview & Allocation Tab: Large display of total portfolio value, visual bar chart, and detailed allocation breakdown
- Balances Tab: Detailed table of all positions with amounts, current values, and edit functionality
TUI Customization
You may optionally specify which tab to open at start-up:
portfolio_rs [JSON_FILE] --tab overview # Start on Overview & Allocation tab (default)
portfolio_rs [JSON_FILE] --tab balances # Start on Balances tab
You can disable specific UI components using the --disable flag with comma-separated component names:
Overview Tab Components:
tab_bar- Top navigation tabstotal_value- Large portfolio value displayasset_allocation- Visual bar chartdetailed_allocation- Allocation percentage listhelp- Help text at bottom
Balances Tab Components:
tab_bar- Top navigation tabsname- Position name columnasset_class- Asset class columnamount- Amount/quantity columnbalance- Balance/value column
Examples:
# Hide tab bar and help text
portfolio_rs --disable tab_bar,help example_data.json
# Show only the allocation chart (hide detailed list)
portfolio_rs --disable detailed_allocation example_data.json
# Minimal balances view (name and balance only)
portfolio_rs --disable asset_class,amount example_data.json
TUI Navigation
h/l: Switch tabs left/right (vim-style)j/k: Navigate up/down (select positions in Balances tab)e: Edit selected position amount (in Balances tab)Tab/←→: Switch between tabs1-2: Jump directly to specific tabsq/Esc: Quit the application
Edit Functionality
- Select any position with
j/kand presseto edit - Real-time balance preview and input validation
- Changes are saved automatically to your data file
- Supports decimal precision for crypto and fractional shares
Screenshots
Overview & Allocation Tab
Balances Tab with Edit Functionality
Demo
Configuration
Upon first run, portfolio_rs will create a default config file.
Use portfolio_rs config to show the config file location.
The most useful config entry is portfolio_file where you can set the
absolute path to your data file. This will be used when no file is
specified as an argument. Workspace users can point workspace_dir at their
workspace instead; the workspace's positions.json then takes precedence.
Bonus: GPG Encryption
This tool supports (gpg) encrypted json files. Decrypted values are never written to disk.
# you will need a valid gpg key in ~/.gnupg/
portfolio_rs [COMMAND] data.json.gpg
Pro Tip: Use a plugin like vim-gnupg for editing your data file.


