Skip to content

aranair/pulse

Repository files navigation

pulse

A local-first, keyboard-driven Rust TUI for portfolio tracking.

pulse is an in-progress finance and investment tracker focused on:

  • stocks / ETFs
  • crypto spot
  • cash / FX balances
  • custom manual assets
  • SQLite-backed local persistence
  • ledger-first transaction tracking
  • projection-based positions, cash, and P&L

Current status

This project is under active development. The current build already supports:

  • SQLite migrations and local database bootstrap
  • entities, accounts, and currency pockets
  • manual assets
  • deposits, withdrawals, fees, interest, dividends
  • buys and sells
  • transaction void / soft delete / revisions
  • cash transfers between accounts
  • FX conversion inside an account
  • manual quote entry
  • manual FX rate entry
  • projection-backed dashboard, positions, cash/FX, transactions, reports, and activity log screens

Tech stack

  • Rust
  • ratatui
  • crossterm
  • rusqlite
  • rust_decimal

Getting started

1. Clone and enter the repo

git clone <your-repo-url>
cd pulse

2. Optional: create a local config

You can run without a config file, but the easiest setup is:

cp pulse.example.toml pulse.toml
mkdir -p data backups

The example config stores the SQLite database at:

  • ./data/pulse.db

pulse looks for config in this order:

  1. ./pulse.toml
  2. your default OS config directory
  3. built-in defaults

3. Run the app

cargo run

4. Run tests

cargo test

Optional:

cargo check

Basic usage

When the TUI opens:

  • ? toggle help
  • : enter command mode
  • q quit
  • r rebuild projections + reload

Command mode supports both direct commands and bare-command forms:

  • type a full command like :buy 1 AAPL 2 185.50 CAD 0 "starter position"
  • or type a bare command like :buy, :sell, or :deposit to open a modal form
  • inside forms, use Tab or arrow keys to move, type to edit, Enter to submit, and Esc to cancel
  • use :help <command> or :<command> help for command-specific usage

Navigation:

  • gd dashboard
  • ge entities
  • ga accounts
  • gp positions
  • gt transactions
  • gx cash / FX
  • gr reports
  • gs settings
  • gl activity log

Quick smoke test

Paste these commands one by one in command mode:

:entity new "Personal" person CAD
:account new 1 "Brokerage" Taxable CAD "Manual"
:pocket new 1 CAD "Main CAD" default
:pocket new 1 USD "USD Pocket"
:asset new AAPL USD equity "Apple Inc"
:deposit 1 CAD 1000 "initial funding"
:fx 1 CAD 200 USD 150 2 "convert cash"
:buy 1 AAPL 2 185 CAD 0 "starter position"
:price AAPL USD 210.50 "manual mark"
:fxrate USD CAD 1.35

Then inspect:

  • gp for positions
  • gx for cash / FX balances
  • gr for valuation-backed report totals

Supported commands

You can either enter the full command directly, or type a bare command keyword to open a form for many workflows.

Examples:

  • :buy opens a buy form
  • :sell opens a sell form
  • :deposit opens a deposit form
  • :account opens an account-creation form
  • :help buy or :buy help shows command-specific help

Setup

:entity new <name> [person|household|corporation|trust|custom] [reporting_currency]
:account new <entity_id> <name> [AccountType] [reporting_currency] [Institution]
:pocket new <account_id> <currency> [Label] [default]
:asset new <ticker> [quote_currency] [asset_type] [Name]

Market data

:price <ticker> <currency> <price> [note]
:fxrate <base_currency> <quote_currency> <rate>

Cash flows

:deposit <account_id> <currency> <amount> [note]
:withdraw <account_id> <currency> <amount> [note]
:fee <account_id> <currency> <amount> [note]
:interest <account_id> <currency> <amount> [note]
:dividend <account_id> <ticker> <currency> <amount> [note]
:transfer <from_account_id> <to_account_id> <currency> <amount> [note]
:fx <account_id> <from_currency> <from_amount> <to_currency> <to_amount> [fee] [note]

Trading

:buy <account_id> <ticker> <qty> <unit_price> <settlement_currency> [fee] [note]
:sell <account_id> <ticker> <qty> <unit_price> <settlement_currency> [fee] [note]

Transaction lifecycle

:void <transaction_id> [reason]
:delete <transaction_id> [reason]
:revisions <transaction_id>
:help

Project principles

  • local-first
  • ledger-first
  • transactions are the source of truth
  • projection tables are derived and rebuildable
  • weighted average cost basis for v1
  • offline-friendly behavior with cached/manual market data

Roadmap highlights

Planned or incomplete areas include:

  • provider-backed quote / FX refresh
  • richer revision inspection UI
  • benchmark tracking
  • broader reporting
  • transaction edit flows
  • import/export improvements

Development notes

Project notes and planning artifacts live in:

  • notes/

Example config:

  • pulse.example.toml

License

See LICENSE.

About

Vim-like Finance and Portfolio Tracker

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages