Skip to main content
ClaudeWave
disin7c9 avatar
disin7c9

asset-management

Ver en GitHub

Drawdown-first portfolio tool with a read-only MCP addon for Claude — a deterministic core computes every number; the AI is fenced out of arithmetic.

MCP ServersRegistry oficial1 estrellas0 forksPythonAGPL-3.0Actualizado today
Install in Claude Code / Claude Desktop
Method: UVX (Python) · --from
Claude Code CLI
claude mcp add asset-management -- uvx --from
claude_desktop_config.json (Claude Desktop)
{
  "mcpServers": {
    "asset-management": {
      "command": "uvx",
      "args": ["--from"],
      "env": {
        "TIINGO_API_KEY": "<tiingo_api_key>"
      }
    }
  }
}
1. Run the command above in your terminal (Claude Code), or paste the JSON config into claude_desktop_config.json (Claude Desktop).
2. Replace any <placeholder> values with your API keys or paths.
3. Restart Claude. The MCP server and its tools appear automatically.
Detected environment variables
TIINGO_API_KEY
Casos de uso

Resumen de MCP Servers

# asset-management

[![gate](https://github.com/disin7c9/asset-management/actions/workflows/ci.yml/badge.svg)](https://github.com/disin7c9/asset-management/actions/workflows/ci.yml) [![asset-management MCP server](https://glama.ai/mcp/servers/disin7c9/asset-management/badges/score.svg)](https://glama.ai/mcp/servers/disin7c9/asset-management)

**TL;DR:** `uvx --from git+https://github.com/disin7c9/asset-management asset-management --demo` — a drawdown-first portfolio brief on a bundled example book, one command, no setup. USD-only, long-only stock/ETF; you keep your own transaction log.

**Track a personal stock/ETF portfolio and get suggestions you can audit. Python computes every number; the optional AI narrates — and is structurally unable to write a figure of its own.**

## 🔢 The number fence

Many AI finance tools let the model produce the numbers. Here the model may only place `{{token}}` placeholders: a deterministic renderer substitutes figures from the validated core and **refuses the entire narration if the model typed even one digit itself**:

```text
 the model wrote                             │  the reader gets
─────────────────────────────────────────────┼─────────────────────────────────────────────
 "Your deepest stretch fell                  │  "Your deepest stretch fell -9.84% from
  {{max_drawdown}} from its peak, and an     │   its peak, and an ulcer index of 2.38%
  ulcer index of {{ulcer}} says the ride     │   says the ride stayed shallow."
  stayed shallow."                           │  ✔ every figure substituted from the
                                             │    validated core
─────────────────────────────────────────────┼─────────────────────────────────────────────
 "Your portfolio fell 12% but recovered      │  (no summary at all)
  nicely — don't worry."                     │  ✘ REFUSED — one model-typed digit voids
                                             │    the entire note; the brief prints
                                             │    without it
```

Run both sides yourself — it drives the real production fence, no API key needed: `uv run python scripts/demo_fence.py`

## 🎁 What you get

- A **drawdown-first brief** of your real holdings — how far you fell from your peak, how long underwater, what came back — with a bootstrap confidence band on every sampled risk statistic (returns are accounting identities, so they honestly carry none).
- **Deterministic buy/sell suggestions** toward a target you choose, each line paired to the **named rule** that produced it — you learn the rule rather than trust a bot.
- Optional, fenced **AI narration**, and a read-only **Claude Desktop addon** ("chat with your portfolio") over the same validated core.

Holdings are *derived* from an append-only transaction log (date, ticker, action, quantity, price, fee per row) — never stored — so the same input always produces the same output. Prices are fetched with a provider fallback (Yahoo Finance primary; Tiingo secondary, via a free API key) and an on-disk cache; every displayed number is traceable to its source, and figures that can't be computed honestly (too short a window, no real solution) print `n/a` rather than a fabricated number. **Stock splits are adjusted automatically** (share counts are reconciled with the split-adjusted price history), so a split during your holding period doesn't distort the returns.

## 📑 Contents

- [🚀 Start here](#-start-here)
  - [⚡ Try it in 60 seconds (bundled fake portfolio, no setup)](#-try-it-in-60-seconds-bundled-fake-portfolio-no-setup)
  - [💵 Use it with your own money — four steps](#-use-it-with-your-own-money--four-steps)
- [🔍 Why you can trust the numbers](#-why-you-can-trust-the-numbers)
  - [🚫 Not financial advice — structurally, not as fine print](#-not-financial-advice--structurally-not-as-fine-print)
  - [✅ Correctness is a claim you can check](#-correctness-is-a-claim-you-can-check)
  - [🔬 Validation — reconciled against two independent tools](#-validation--reconciled-against-two-independent-tools)
- [💬 Chat with your portfolio — the Claude Desktop addon (read-only MCP)](#-chat-with-your-portfolio--the-claude-desktop-addon-read-only-mcp)
  - [🛟 If something goes wrong](#-if-something-goes-wrong)
- [📖 Reference](#-reference)
  - [💻 Core brief](#-core-brief)
  - [🔁 Rebalance modes](#-rebalance-modes)
  - [📈 Backtest details](#-backtest-details)
  - [🔭 Discovery & the curated universe](#-discovery--the-curated-universe)
  - [🔍 Screen a candidate](#-screen-a-candidate)
  - [📝 Narration (optional plain-language summary)](#-narration-optional-plain-language-summary)
  - [🔑 Configuration — every key in one place](#-configuration--every-key-in-one-place)
- [🔧 Project](#-project)
  - [🧪 Develop](#-develop)
  - [📁 Layout](#-layout)
- [🔒 Privacy Policy](#-privacy-policy)
- [📜 License](#-license)

## 🚀 Start here

### ⚡ Try it in 60 seconds (bundled fake portfolio, no setup)

```bash
uvx --from git+https://github.com/disin7c9/asset-management asset-management --demo
```

or from a clone: `uv sync && uv run python -m app --demo` (needs Python 3.12 and [uv](https://docs.astral.sh/uv/)).

**The full tour** (still the bundled book, ~a minute online) — the two commands below show the tool's characteristic features end to end: a preset target is *proposed*, then *validated* against a known 60-40 reference with a walk-forward held-out verdict, and threshold-band rebalance suggestions are laid out with the named rule behind every line, plus per-fund facts:

```bash
uvx --from git+https://github.com/disin7c9/asset-management asset-management --demo --allocate moderate --allocate-out demo_target.csv
uvx --from git+https://github.com/disin7c9/asset-management asset-management --demo --backtest --target demo_target.csv --benchmark 60-40 --rebalance bands --metadata
```

Note what it *doesn't* say: the verdict reads like "no clear drawdown difference from 60-40; the paired bootstrap does not confirm the gap" when the evidence is thin — never "beats the benchmark". When the output earns your trust, the four steps below point it at your own money.

### 💵 Use it with your own money — four steps

#### Step 1 — your book (the input)

Everything is derived from one transaction log. The CSV format is **Ghostfolio's own CSV-import schema** (so a book you keep here imports straight into Ghostfolio too) — columns `Date, Code, DataSource, Currency, Price, Quantity, Action, Fee, Note`. `Action` is one of `buy`, `sell`, `dividend`, `fee`, `interest`, `deposit`, `withdraw`. Cash flows (`deposit`/`withdraw`) use a `CASH` code and put the amount in the `Price` column. **This tool is USD-only** (long-only stock/ETF): `Currency` must be `USD` — a non-USD row is refused with an error naming the row, never silently booked as dollars 1:1. Empty cells in numeric columns are treated as zero. Non-ISO dates are rejected with a clear error. UTF-8 BOM is tolerated. The bundled example ([data/sample_data/transactions.csv](data/sample_data/transactions.csv)) shows every row type.

**Already use [Ghostfolio](https://ghostfol.io)?** Point the input straight at a Ghostfolio **JSON** export (Portfolio → Activities → ⋯ → Export) — the loader detects it and reads it directly, no conversion step. It reads the activities (a dividend's cash = `quantity × unitPrice`; Ghostfolio's UTC timestamps are rounded back to your local date) and skips non-USD, crypto, and non-security (`ITEM`/`LIABILITY`) rows with a warning (USD-only, long-only equity/ETF for now). Brokers without a native Ghostfolio account can run a community converter such as [Export-To-Ghostfolio](https://github.com/dickwolff/Export-To-Ghostfolio) (26 brokers → a Ghostfolio JSON) first.

```bash
uv run python -m app --book your.csv                     # or ghostfolio-export.json — auto-detected
uv run python -m app --book your.csv --dry-run           # preview an import BEFORE trusting it:
                                                         # format, events, skipped rows with reasons,
                                                         # derived holdings — fetches nothing
```

**Set your default once** in a gitignored `.env` at the repo root — `ASSET_BOOK=path/to/your.csv` (and optionally `ASSET_TARGET=path/to/target.csv`) — and a bare `python -m app` becomes your brief. Explicit flags always win. There is **no silent built-in default**: without `--book` or `ASSET_BOOK`, a book-dependent action errors out and a bare run prints a hint — the bundled example is opt-in (`--demo`), never assumed.

#### Step 2 — warm the cache (once)

The core is offline-first: prices come from an on-disk cache, refreshed when you run online. After a fresh clone, fill it once:

```bash
uv run python -m app --book your.csv --warm        # your tickers + the benchmark references
uv run python -m app --book your.csv --warm full   # + the ~375-ETF discovery universe (slow) —
                                                   # only needed for offline --discover
```

After that, `--offline` runs and the Claude Desktop addon serve entirely from this cache (`--cache-dir` / `ASSET_CACHE_DIR` override the location).

**Optional but recommended:** add a free [Tiingo](https://www.tiingo.com) API key to `.env` — `TIINGO_API_KEY=...` — to enable the second price source. Yahoo Finance throttles bursts of requests now and then; with a key the fetch falls back to Tiingo instead of reporting tickers missing. Without one, the tool fetches from Yahoo only.

#### Step 3 — choose a target

Most of the decision features (`--rebalance`, `--backtest`, the walk-forward checks) work toward a **target allocation** — a small CSV (`Ticker,Weight`) that *you* own and edit. Three ways to get one, by where you're starting from:

- **You already hold a portfolio** → `--dump-target target.csv` writes your **current** allocation; edit it toward the mix you want. (A target is a *complete spec* — see [Rebalance modes](#-rebalance-modes) for the exit seman
backtestingclaudeclaude-desktopdrawdownetfmcpmodel-context-protocolpersonal-financeportfolio-managementpythonrisk-management

Lo que la gente pregunta sobre asset-management

¿Qué es disin7c9/asset-management?

+

disin7c9/asset-management es mcp servers para el ecosistema de Claude AI. Drawdown-first portfolio tool with a read-only MCP addon for Claude — a deterministic core computes every number; the AI is fenced out of arithmetic. Tiene 1 estrellas en GitHub y se actualizó por última vez today.

¿Cómo se instala asset-management?

+

Puedes instalar asset-management clonando el repositorio (https://github.com/disin7c9/asset-management) o siguiendo las instrucciones del README en GitHub. ClaudeWave también te ofrece bloques de instalación rápida en esta misma página.

¿Es seguro usar disin7c9/asset-management?

+

disin7c9/asset-management aún no ha sido auditado por nuestro agente de seguridad. Revisa el repositorio original en GitHub antes de usarlo en producción.

¿Quién mantiene disin7c9/asset-management?

+

disin7c9/asset-management es mantenido por disin7c9. La última actividad registrada en GitHub es de today, con 0 issues abiertos.

¿Hay alternativas a asset-management?

+

Sí. En ClaudeWave puedes explorar mcp servers similares en /categories/mcp, ordenados por popularidad o actividad reciente.

Despliega asset-management en tu cloud

Lleva este repo a producción en minutos. Cada plataforma genera su propio entorno con variables de entorno editables.

¿Mantienes este repo? Añade un badge a tu README

Pega el badge en tu README de GitHub para mostrar que está auditado por ClaudeWave. Cada badge enlaza de vuelta a esta página y muestra el Trust Score actual.

Featured on ClaudeWave: disin7c9/asset-management
[![Featured on ClaudeWave](https://claudewave.com/api/badge/disin7c9-asset-management)](https://claudewave.com/repo/disin7c9-asset-management)
<a href="https://claudewave.com/repo/disin7c9-asset-management"><img src="https://claudewave.com/api/badge/disin7c9-asset-management" alt="Featured on ClaudeWave: disin7c9/asset-management" width="320" height="64" /></a>

Más MCP Servers

Alternativas a asset-management