Skip to content

Latest commit

 

History

4 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CashPulse

Privacy-first, local-only personal cash flow forecasting and financial anomaly detection.

CashPulse turns raw bank exports (CSV, OFX, QFX) into auto-categorized transactions, 30-day cash flow forecasts with confidence intervals, and actionable anomaly alerts (subscription creep, spending drift, lifestyle inflation, overdraft risk).

Everything runs locally on your machine. No bank credentials. No cloud uploads. No telemetry.


Status

Feature-complete across all six build phases:

Phase Subsystem Status
1 Ingestion layer (parsers + dedup + DB) Done
2 Hybrid categorization engine Done
3 Feature engineering + recurrence/payday Done
4 Model layer (forecasters + 5 detectors) Done
5 Output layer, dashboard, PDF, CLI polish Done
6 Model training + evaluation + model card Done

533 tests pass / ruff check + mypy --strict clean across both cashpulse/ and tests/. Line coverage is 52 % overall; the Phase 6 training-script package (cashpulse/training/) is intentionally exercised end-to-end via the integration test rather than via unit tests, so excluding it brings runtime-code coverage to ~84 %. See docs/MODEL_CARD.md for trained-model metrics with the actual numbers from each training run.


Why CashPulse?

Most personal-finance tools are rearview mirrors — they tell you what already happened. CashPulse is forward-looking:

  • Predicts the next 30 days of cash flow with confidence intervals
  • Catches subscription creep before you do — including zombie subscriptions you never use
  • Detects spending drift in specific categories ("Dining Out is up 34% over 3 months")
  • Flags lifestyle inflation when discretionary spending scales faster than income
  • Warns of overdraft risk with SHAP-backed feature contributions

Everything stays on your machine. No Plaid. No bank APIs. No cloud.


Quick Start

# Install (dev mode)
pip install -e ".[dev]"

# Step-by-step pipeline
cashpulse scan        --input ./bank_exports/      # ingest
cashpulse categorize                                # label
cashpulse featurize                                 # features + recurrence
cashpulse train                                     # train all 7 models
cashpulse predict                                   # forecasts + alerts

# Or one-shot
cashpulse analyze --input ./bank_exports/ --dashboard

# PDF export
cashpulse report --input ./bank_exports/ --format pdf --output vitals.pdf

What you get

Terminal vital-signs panel

+----------------------------------------------------------------+
|         CashPulse Vital Signs - May 2026                       |
+----------------------------------------------------------------+
| Burn rate          $3,240/mo  (^ 6% vs 3-mo avg)              |
| Savings rate       11.2%      (v from 14.8%)                  |
| Subscription load  $187/mo    (12.4% of income)               |
| Emergency runway   18.3 days  (v from 24.1 days)              |
| Income regularity  0.87       (HIGH - stable)                 |
| Overdraft risk     LOW        (next 30 days)                  |
|                                                                |
| ANOMALIES DETECTED: 3                                          |
|  - Dining Out drift: +$116/mo vs baseline                     |
|  - 2 subscription price increases: +$36/yr                    |
|  - Lifestyle inflation: Shopping elasticity 2.1x              |
|                                                                |
| 30-DAY FORECAST                                                |
|  Balance projection: $1,420 - $2,890 (80% CI)                 |
|  Next cash crunch: June 3 (rent + insurance overlap)          |
+----------------------------------------------------------------+

Streamlit dashboard (6 pages)

  1. Overview — vital signs + forecast envelope chart
  2. Cash Flow — daily balance projection, income/expense bars
  3. Categories — spend breakdown, pie chart, month-over-month trends
  4. Subscriptions — every recurring charge, zombie flags, price history
  5. Anomalies — timeline of detected anomalies + SHAP factor breakdown
  6. Forecast — interactive what-if scenarios ("what if I cancel Netflix?")

PDF report

A self-contained one-page report with the headline metrics table, the forecast-envelope chart, and the top-5 alert table. Includes a privacy footer reminding the reader that nothing left their machine.


Architecture

+----------+   +-------------+   +-------------+   +---------+   +----------+
|  Ingest  |-->| Categorize  |-->|  Features   |-->|  Models |-->|  Output  |
+----------+   +-------------+   +-------------+   +---------+   +----------+
     |               |                  |                |             |
     v               v                  v                v             v
  Parser Zoo    Rule + ML +     Rolling windows     Forecasters    Vital signs
  CSV / OFX     Active learn   Recurrence detect    + 5 detectors  Terminal +
  Dedup + DB    Taxonomy       Payday detect        + SHAP         PDF + dash

Strict one-way dependency flow: a downstream module never imports from an upstream module. Every persistence boundary is SQLite (one local DB at ~/.cashpulse/data.db). Model weights live under ~/.cashpulse/models/.


Phase 1 — Ingestion Layer

Goal: drop any supported bank export onto disk, get a clean, deduplicated, unified transaction ledger.

Parser Zoo

  • CSV parsers with auto-detection: Chase (checking + credit card), Bank of America, Capital One. Each implements BankParser.detect() -> float for confidence scoring and normalize() -> pd.DataFrame for the unified schema.
  • OFX / QFX parser via ofxparse, handles both SGML and XML variants. Timezone-aware timestamps are normalized to UTC before the calendar date is taken (stable across machines).
  • Encoding fallback chain (utf-8 -> utf-8-sig -> cp1252 -> latin-1) to survive banks that mis-declare their export encoding.

Unified schema

UNIFIED_SCHEMA = {
    "date": "datetime64[ns]",
    "description": "str",
    "amount": "float64",           # negative = outflow
    "balance": "float64 | null",
    "account_id": "str",
    "source_file": "str",
    "raw_category": "str | null",
}

Deduplicator

  • Groups by (date ± 1 day, abs(amount), description similarity > 0.85). Rows with blank descriptions are never clustered together.
  • Detects transfer pairs (opposite amounts across accounts within the date window). Both sides must look transfer-related (shared keywords such as transfer, zelle, card payment) or have very similar descriptions — coincidental same-amount payments are not linked.
  • Cross-account aware so combining checking + credit-card + savings works out of the box.

SQLite store

  • Idempotent INSERT OR IGNORE keyed on (date, amount, description, account_id).
  • Schema bootstrapped on first connection; no migrations needed.

CLI

cashpulse scan --input <file_or_directory>

Phase 2 — Categorization Engine

Goal: every transaction gets a (category, subcategory, confidence) label.

Hybrid three-stage classifier per the architecture doc:

Stage 1 — Deterministic rule engine

  • Merchant normalizer strips dates, card-number fragments, location codes, transaction IDs.
  • Curated merchant dictionary with 1,082 entries across 11 top-level categories (see data/merchants/merchants.json). Each entry can carry aliases; rapidfuzz handles fuzzy matching.

Stage 2 — Sentence-transformer classifier

  • Base model: all-MiniLM-L6-v2 (384-dim embeddings, ~80MB).
  • For each category, computes a centroid embedding from the dictionary entries; new descriptions are scored by cosine similarity to every centroid.
  • Returns top-1 label with a confidence score.

Stage 3 — Active learning

  • Transactions below a confidence threshold (default 0.7) are flagged needs_review.
  • User corrections persist to the corrections SQLite table, keyed by normalized merchant, so the same merchant won't get mislabeled twice.
  • Future categorize runs treat corrections as ground truth (overriding both the rule engine and the embedder).

Taxonomy

11 top-level categories, ~50 subcategories total: Income, Housing, Transportation, Food, Subscriptions & Recurring, Health, Financial, Shopping, Education, Travel, Miscellaneous. See cashpulse/categorize/taxonomy.py for the full tree.

CLI

cashpulse categorize --threshold 0.7

Phase 3 — Feature Engineering

Goal: raw labeled transactions become a rich daily feature matrix ready for model consumption.

Per-transaction features

day_of_week, day_of_month, week_of_year, month, is_weekend, is_payday_proximity, is_recurring, merchant_frequency, amount_zscore (z-score within category), and time_since_last_same_merchant.

Multi-account balance

features/balance_utils.py builds a combined end-of-day balance: per-account last balance each day, forward-filled per account, then summed across accounts (or per-account cashflow integration when the bank omits balance). Used by rolling features, overdraft risk, and vital-signs forecast envelopes.

Rolling-window features (per day)

Feature Notes
daily_net_cashflow Signed sum
daily_spend, daily_income Outflow / inflow magnitudes
rolling_spend_{7,14,30}d Outflow sums
rolling_income_{7,14,30}d Inflow sums
balance Combined EOD balance (NaN when unavailable)
rolling_balance_trend_{7,14,30}d Linear-regression slope on EOD balance
spend_velocity First derivative of 7-day rolling spend
burn_rate_acceleration Second derivative of cumulative spend
savings_rate_30d (income - spend) / income over 30d
subscription_burden_ratio Recurring outflows / income
emergency_runway_days balance / avg_daily_spend
income_regularity_score 1 - CV of inter-arrival times between income days
category_spend_ratio_{cat}_30d Per-top-level-category 30-day shares

RecurrenceDetector

  • Mines per-merchant inter-transaction intervals against canonical periods (weekly, biweekly, monthly, quarterly, annual).
  • A stream is flagged recurring when periodicity score > 0.7 AND amount coefficient-of-variation < 0.15.
  • Emits RecurringCharge records carrying merchant, amount, period, full price history, and a stable/increasing/decreasing trend label.

PaydayDetector

  • Classifies inflows as weekly / biweekly / semi-monthly / monthly / irregular per account.
  • Returns the typical day(s) of the month, the median interval, the detection confidence, and the projected next payday.

Feature store

Persists four tables in the same SQLite DB: transaction_features, daily_features (with category-share JSON), recurring_charges, payday_patterns. Every write is idempotent.

CLI

cashpulse featurize

Phase 4 — Model Layer

Goal: trained models that forecast cash flow and detect anomalies. Seven models behind a common CashPulseModel interface (fit, predict, save, load).

Model Module Purpose
LSTM-Transformer forecaster/lstm_transformer.py Primary 30-day cash-flow forecaster (90-day lookback, MSE + pinball loss)
Prophet + XGBoost forecaster/prophet_xgb.py Fallback forecaster, OLS-stacked, residual-driven 80% intervals
Spending drift anomaly/spending_drift.py PyTorch MLP autoencoder, per-category 2σ reconstruction-error threshold
Cash-flow anomaly anomaly/cashflow_anomaly.py Isolation Forest on 6 daily features; detect(as_of=, lookback_days=) scopes alerts to a recent window
Subscription creep anomaly/subscription_creep.py Rule-based: 4 alert kinds — price increase, cumulative creep, new sub, zombie
Lifestyle inflation anomaly/lifestyle_inflation.py Income-elasticity-of-spending regression on discretionary categories
Overdraft risk anomaly/overdraft_risk.py XGBoost classifier + SHAP feature contributions

LSTM-Transformer architecture

Per-day feature vector
   |
   v
Temporal Embedding (day_of_week, day_of_month, week_of_year, payday_proximity)
   |
   v
2-layer LSTM (128 hidden units)
   |
   v
4-head Multi-Head Self-Attention
   |
   v
Mean-pool -> [Point head | Quantile head]

Combined MSE + pinball-quantile loss; 90-day lookback, configurable horizon. Persona training can normalize each lookback window independently; inference uses the same window-local normalization when that mode is active. Falls back to Prophet+XGBoost when history is shorter than 150 days.

Walk-forward validation

models/walk_forward.py implements expanding-window and sliding-window validation with a model-agnostic callable API. Returns per-fold MAE / RMSE / MAPE so callers can pick a forecaster on real held-out folds, not in-sample fit.

Model store + runner

  • models/store.py handles save/load and meta-json versioning (name + version validated on load).
  • models/runner.py is the run_train / run_predict orchestrator. It gracefully degrades when history is short:
    • LSTM-Transformer skipped < 150 days
    • Prophet+XGBoost skipped < 60 days
    • Autoencoder skipped < 60 days
    • Anomaly detectors skipped < 30 days
    • Rule-based detectors always trainable.

CLI

cashpulse train         # trains every model that meets its data threshold
cashpulse predict       # loads + runs every available model

Phase 5 — Output Layer + Dashboard + Polish

Goal: turn structured model output into a usable product.

Vital-signs aggregation

output/vital_signs.py consumes the PredictResult + the daily feature frame and produces a single VitalSigns dataclass: burn rate, savings rate, subscription burden (from transaction_features.is_recurring when available), emergency runway, income regularity, overdraft band, the 30-day forecast envelope (when balance history exists), the projected cash-crunch date, and a severity-sorted top-5 alert list across every detector (including overdraft).

Terminal renderer

output/report_generator.py renders the vital-signs panel via Rich, with coloured trend arrows and a fallback ASCII text mode shared with the PDF exporter.

PDF export

output/pdf_export.py produces a self-contained two-page PDF via matplotlib + reportlab:

  • Page 1: title, headline metrics table, forecast chart (cumulative balance only when daily balance exists; otherwise raw forecast target), top-alerts table, optional cash-crunch warning.
  • Page 2: privacy footer ("CashPulse runs entirely on your local machine; no network calls, no telemetry").

Streamlit dashboard

cashpulse/dashboard/ ships as an importable sub-package. cashpulse dashboard (or cashpulse analyze --dashboard) spawns streamlit run against dashboard/app.py. Six sidebar-navigated pages cover Overview, Cash Flow, Categories, Subscriptions, Anomalies, and Forecast (with interactive cancel-a-sub what-if).

Orchestration runner

output/runner.py implements run_analyze (end-to-end scan -> categorize -> featurize -> train -> predict -> vital signs) and run_report (full pipeline + terminal/PDF render). The analyze runner reuses already-trained models on disk unless --retrain is passed.


Phase 6 — Model Training

Goal: trained, evaluated, serialised weights for every ML model — so the project ships with a working classifier, forecaster, and anomaly detectors instead of architecture-only stubs.

Training data strategy

Training data comes from two complementary sources, both deterministic and local:

  1. PersonaGenerator (cashpulse/training/persona_generator.py) produces 12-month synthetic financial lives for 8 persona archetypes (stable salaried, high-earner, freelancer, paycheck-to-paycheck, subscription zombie, couple, college student, retiree). Clean personas establish baselines; "dirty" personas inject one of five anomalies (drift, creep, inflation, overdraft, cashflow) for labelled evaluation. 780 personas total, regenerable via python -m cashpulse.training.build_datasets.
  2. HuggingFace DoDataThings/us-bank-transaction-categories-v2 — 68K rows of realistic US bank-export descriptions, mapped to the CashPulse 11-category / ~50-subcategory taxonomy by category_mapping.py.

What got trained

Model Source data Headline metric Target Hit?
Sentence-transformer categorizer (fine-tuned MiniLM + multi-task head) 68K HF + 89K synthetic Top-1 cat accuracy = 88.8% (baseline 63.5%) > 92% close
LSTM-Transformer forecaster 160 personas × 12mo 30-day MAE = 1.0% of avg balance < 15% yes
Prophet+XGBoost fallback 160 personas, 120-day slice, 27-point grid Test walk-forward MAE = $896 n/a
Spending-drift autoencoder 130 clean personas (per-user fit) Recall 0.58, precision 0.50 > 0.70 / 0.80 partial
Cash-flow Isolation Forest 130 clean personas (per-user fit) Day-level FP rate 3.48%, persona recall 1.00 < 5% yes
Overdraft XGBoost + SHAP 100 personas × 12-point grid AUC=0.52, SHAP top-2 = balance + days_to_next_payday (as expected) > 0.85 no — data limit
Subscription creep (threshold-tuned) 10 zombie persona pairs × 27 combos F1=0.67, recall=1.00 n/a
Lifestyle inflation (threshold-tuned) 10 high-earner pairs + 10 controls × 24 combos F1=0.48 n/a

End-to-end integration test (Phase 6 Step 7)

10 fresh, unseen personas (5 clean + 5 dirty) exported as Chase CSVs and run through cashpulse analyze --retrain=False against the pre-trained models. Full per-persona metric summary at test_integration/metric_summary.json: 96.25% avg category accuracy, 0.0% uncategorised, 10/10 valid forecast envelopes, 10/10 complete vital signs, all 6 dashboard pages import cleanly.

Honest gap analysis

Several models miss their architecture-spec targets. The gaps trace to synthetic-data realism more than to model architecture — see docs/MODEL_CARD.md for the per-model root-cause analysis (where the metric breaks down: detector code, training data, or integration boundary). The model card distinguishes "detector working as designed" from "detector underperforming" rather than burying the gap.

Training scripts

All Phase 6 training scripts live in cashpulse/training/:

persona_generator.py            # 8 archetypes, 5 anomaly injectors
persona_loader.py               # Shared loader for trainers
build_datasets.py               # Step 1+2 dataset orchestrator
category_mapping.py             # HuggingFace -> CashPulse taxonomy
train_categorizer.py            # Step 3 (sentence-transformer fine-tune)
train_forecaster.py             # Step 4 (LSTM-Transformer)
train_fallback_forecaster.py    # Step 5 (Prophet+XGBoost)
train_spending_drift.py         # Step 6A (autoencoder, per-user)
train_cashflow_anomaly.py       # Step 6B (Isolation Forest, per-user)
train_overdraft.py              # Step 6C (XGBoost + SHAP)
tune_subscription_creep.py      # Step 6D (rule-based thresholds)
tune_lifestyle_inflation.py     # Step 6E (rule-based thresholds)
integration_test.py             # Step 7 (10-persona E2E)

Trained weights are persisted via the existing ModelStore to ~/.cashpulse/models/<model_name>/, each with a sidecar training_metadata.json carrying dataset sizes, hyperparameters, and every reported metric.


CLI Reference

cashpulse scan        --input <path>             # Parse + dedupe + persist
cashpulse categorize  --threshold 0.7            # Rule + transformer classifier
cashpulse featurize                              # Rolling features + recurrence
cashpulse train                                  # Train every Phase 4 model
cashpulse predict                                # Run every detector / forecaster
cashpulse analyze     --input <path>             # Full pipeline end-to-end
                      --dashboard                # Launch Streamlit after
                      --retrain                  # Force fresh training
cashpulse report      --format pdf               # Export PDF vital signs
                      --output vitals.pdf
cashpulse dashboard                              # Streamlit only (no analysis)

Global flags accepted by every subcommand:

--config <path.yaml>                             # Override config
--log-level DEBUG|INFO|WARNING|ERROR             # Verbosity
--strict / --no-strict                           # Fail fast vs. continue

Configuration

A single CashPulseConfig Pydantic model (cashpulse/config.py) holds every tunable knob. Defaults work out of the box; override anything via a YAML file passed with --config:

data_dir: ~/.cashpulse                 # SQLite DB + model artifacts live here
log_level: INFO
strict: false                          # Fail loud on recoverable issues
default_encoding: utf-8
fallback_encodings: [utf-8-sig, cp1252, latin-1]
min_parser_confidence: 0.5
dedup_date_window_days: 1
dedup_description_similarity: 0.85

Nothing in the library hard-codes a file path; everything flows through this object.


Privacy Architecture

+-------------------------------------------+
|           User's Machine                  |
|                                           |
|  CSV files --> CashPulse --> SQLite DB    |
|                    |                      |
|                    v                      |
|              Local Models                 |
|         (no network calls)                |
|                    |                      |
|                    v                      |
|           Reports & Dashboard             |
|                                           |
|  - No cloud uploads                       |
|  - No API keys required                   |
|  - No telemetry                           |
|  - No bank credentials                    |
+-------------------------------------------+

CashPulse downloads no model weights at runtime, makes no outgoing network requests during analysis, and writes nothing outside the user's chosen data_dir. The sentence-transformer is pulled once at install time and cached locally by sentence-transformers itself.


Repository Layout

cashpulse/
  cli.py                       # Click CLI entry point
  config.py                    # CashPulseConfig (Pydantic)
  exceptions.py                # CashPulseError hierarchy
  ingest/                      # Phase 1
    base_parser.py             # BankParser ABC + UnifiedTransaction
    csv_parsers/               # Chase, BoA, Capital One
    ofx_parser.py              # OFX/QFX
    csv_reader.py              # Encoding fallback chain
    deduplicator.py            # Dedup + transfer-pair detection
    scan.py                    # End-to-end scan pipeline
  categorize/                  # Phase 2
    normalizer.py              # Merchant string cleaning
    merchant_db.py             # Curated dictionary loader
    rule_engine.py             # Stage 1
    embedder.py                # Stage 2 (sentence-transformer)
    classifier.py              # 3-stage orchestration
    active_learner.py          # Stage 3 (SQLite-backed corrections)
    taxonomy.py                # 11 categories / ~50 subcategories
    store.py                   # CategorizationStore
    runner.py                  # cashpulse categorize pipeline
  features/                    # Phase 3
    balance_utils.py           # Multi-account combined EOD balance
    transaction_features.py    # Per-row features
    rolling_features.py        # Daily rolling windows
    recurrence_detector.py     # RecurringCharge mining
    payday_detector.py         # PaydayPattern detection
    feature_store.py           # 4 feature tables
    runner.py                  # cashpulse featurize pipeline
  models/                      # Phase 4
    base.py                    # CashPulseModel ABC
    store.py                   # ModelStore (filesystem)
    walk_forward.py            # WalkForwardValidator
    forecaster/
      lstm_transformer.py      # Primary forecaster (PyTorch)
      prophet_xgb.py           # Fallback ensemble
    anomaly/
      spending_drift.py        # Autoencoder (PyTorch)
      cashflow_anomaly.py      # Isolation Forest
      subscription_creep.py    # Rule-based
      lifestyle_inflation.py   # Income elasticity
      overdraft_risk.py        # XGBoost + SHAP
    runner.py                  # cashpulse train / predict
  output/                      # Phase 5
    vital_signs.py             # VitalSigns aggregator
    report_generator.py        # Rich terminal renderer
    pdf_export.py              # matplotlib + reportlab PDF
    runner.py                  # cashpulse analyze / report
  dashboard/                   # Phase 5
    app.py                     # Streamlit entry (6 pages)
    components.py              # Chart + table builders
    state.py                   # Shared data loader + cache
  db/
    schema.py                  # 7-table SQLite DDL
    store.py                   # TransactionStore

data/
  merchants/merchants.json     # 1,082 curated merchants
  sample/                      # 5 realistic sample bank exports

tests/                         # pytest (533 tests; 52% overall, ~84% ex-training)
  helpers.py                   # Shared test fixtures (stub classifier)
  test_parsers/                # CSV / OFX parser tests
  test_categorize/             # Categorization pipeline
  test_features/               # Feature engineering
  test_models/                 # 7 model test modules + walk-forward
  test_output/                 # Vital signs + renderer + PDF
  test_dashboard/              # Dashboard components + state
  test_cli_pipeline.py         # Click CLI subprocess smoke tests
  test_deduplicator.py
  test_base_parser.py
  test_scan_cli.py
  test_scaffold.py

Evaluation Targets

Model Metric Target
Categorization Top-1 accuracy > 92%
Categorization Top-3 accuracy > 98%
Cash-flow forecast 7-day MAE < 8%
Cash-flow forecast 30-day MAE < 15%
Overdraft prediction AUC-ROC > 0.85
Overdraft prediction Precision @ 80% recall > 0.70
Anomaly detection Precision > 0.80
Recurring detection F1 score > 0.90

These targets assume 12+ months of real data. The bundled sample fixtures are ~60 days — long enough to validate the pipeline end-to-end, not long enough to hit every metric. Test data uses synthetic frames designed to exercise each detector under controlled conditions.


Development

# Install (dev mode)
pip install -e ".[dev]"

# Run the full test suite with coverage
pytest --cov=cashpulse

# Lint + format (ruff config in pyproject.toml)
ruff check cashpulse tests
ruff format cashpulse tests

# Strict type-check
mypy cashpulse

# Launch the dashboard against any data directory
streamlit run cashpulse/dashboard/app.py -- --data-dir ~/.cashpulse

Tooling

  • Python 3.11+, packaged via pyproject.toml (PEP 621).
  • ruff — 88-char line width, double quotes, E/F/W/I/UP/B/SIM/RUF enabled.
  • mypy --strict — Pydantic plugin on; pandas-stubs handled with targeted # type: ignore[code] comments where the stubs are stricter than runtime behaviour.
  • pytest + hypothesis for property-based parser tests.

Sample data

Five realistic bundled exports under data/sample/ cover every parser:

bofa_checking.csv
capital_one.csv
chase_checking.csv
chase_credit.csv
wells_fargo.ofx

Try the full pipeline against them:

cashpulse analyze --input data/sample/

Tech Stack

Component Library
Data pandas, numpy
Categorization sentence-transformers, scikit-learn, rapidfuzz
Forecasting PyTorch (LSTM-Transformer), Prophet, XGBoost
Anomaly detection PyTorch (autoencoder), scikit-learn (Isolation Forest), XGBoost
Explainability SHAP
File parsing ofxparse
Storage SQLite (stdlib)
CLI Click + Rich
Dashboard Streamlit
PDF matplotlib + reportlab
Config / validation Pydantic, PyYAML
Testing pytest, hypothesis
Lint / type ruff, mypy

License

MIT

About

CashPulse is a privacy-first local finance CLI that turns bank exports into categorized transactions, 30-day cash-flow forecasts, and anomaly alerts. It runs fully on-device with no bank credentials, cloud uploads, or telemetry.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages