Purpose
This is a drawdown-focused personal stock/ETF portfolio tracking and analysis tool, with a read-only MCP plugin that lets AI assistants (such as Claude Desktop) query your portfolio as read-only tools. It does not execute trades, nor does it store your holdings—holdings are derived entirely from the append-only transaction log you provide, and the same input always produces the same output.
Main capabilities
- Drawdown-first briefing: Based on actual holdings, shows the drawdown from peak, time underwater, and recovery status; every sampled risk statistic comes with a bootstrap confidence interval (returns, as an accounting identity, do not carry intervals), and when data is insufficient it shows n/a or inconclusive rather than inventing numbers.
- Deterministic recommendations: For the target allocation you choose, gives buy/sell recommendations, and each recommendation is labeled with the named rule that triggered it, so you understand the rule rather than trusting it blindly.
- Number fencing: The Python deterministic core computes all numbers; optional AI narration may only place {{token}} placeholders, which the renderer replaces with values from the verified core; if the model itself inputs any digit in the Unicode number category (such as ½ or 3.2), the entire narration is rejected.
- Read-only Claude plugin: Exposes the portfolio to AI assistants as read-only tools via MCP, and the returned values all come from the same deterministic core; however, the assistant's own text is not subject to the fencing, and numbers that cannot be traced back to tool results should be treated as unverified.
- Targets and rebalancing: Supports preset risk postures (conservative/moderate/aggressive), equal weight, inverse volatility, and other rebalancing modes; supports 5/25 band rebalancing and cash-inflow-only rebalancing (tax-friendly); propose, simulate, and execute are enforced as separate steps, so strategy never silently becomes a trade.
- Backtesting and benchmark comparison: Simulates against targets and benchmarks (60-40/all-weather/permanent) over common history, and gives a verdict with a held-out recent window: shallower/deeper/inconclusive/insufficient, never saying "outperformed"; the verdict is based on the Ulcer index, requires CDaR not to contradict it and paired bootstrap confidence intervals to confirm it, with maximum drawdown used only as context.
- Discovery and screening: Can suggest screening ETFs suitable for your underweight role, and evaluate candidate instruments (cost, liquidity, age, overlap, and whether they truly diversify the worst drawdown).
- Output forms: Plain text is always output, optionally saved as markdown or sent as an HTML email; failure of one output does not crash the run, but if a requested output fails, the process exits non-zero so the scheduler can notice. If all holdings cannot be priced, the briefing still prints from the ledger but exits non-zero and prompts for a fix.
How to use
- Quick trial:
uvx --from git+https://github.com/disin7c9/asset-management asset-management --demo, using the bundled fake portfolio, with no setup required. You can also clone it and thenuv sync && uv run python -m app --demo(requires Python 3.12 and uv). - Using your own money: four steps (the specific four steps are not provided in the material).
- Input format: The transaction log CSV uses Ghostfolio's CSV import schema—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 the CASH code and put the amount in the Price column. Only USD is supported; non-USD rows raise an error and indicate the line number. Empty numeric cells are treated as zero, non-ISO dates raise an error, and UTF-8 BOM is tolerated. Bundled example
data/sample_data/transactions.csvshows all row types. - Ghostfolio users: You can point directly at a Ghostfolio JSON export (Portfolio → Activities → ⋯ → Export), and the loader detects and reads it automatically; non-USD, cryptocurrency, and non-security (ITEM/LIABILITY) rows are skipped with a warning.
- Configuration: In the repository root, in
.envsetASSET_BOOK=path/to/your.csv(optionalASSET_TARGET), then the barepython -m appis the briefing. Explicit flags take precedence. There is no built-in default ledger. - Offline first: prices come from the disk cache and are refreshed when running online. After the first clone, the cache must be populated once. Afterward,
--offlineand the Claude Desktop plugin run entirely from the cache. Optionally add a Tiingo API key as a second price source to handle Yahoo rate limiting. - Target acquisition: for an existing portfolio, use
--dump-targetto write out the current configuration and then edit it; use--onboardor--allocateto select a risk posture preset; use--discoverand--screento explore and build your own. - Validate target:
--backtestsimulates the performance of the target and the reference over their common history and gives a holdout-window verdict. - Scheduling: you can use cron to run the briefing every Monday; on Windows without WSL, use Task Scheduler to run wsl.exe, or run the installed uv directly.
Use cases
Individual investors who want to review their stock/ETF portfolio with drawdown as the core concern and need auditable, deterministic recommendations rather than black-box forecasts; who want to query the portfolio in natural language with an AI assistant but require the numbers to come from a deterministic core; who need tax-friendly rebalancing (cash contributions only); and who want to compare the drawdown difference between a target allocation and a benchmark, with conclusions that are conservative and not overstated.
Limitations
- USD only, long-only stocks/ETFs; non-USD lines are rejected.
- There is no built-in default ledger; it must be provided explicitly.
- The wording of the AI narrative is not constrained by the guardrails and may produce advisory or predictive sentences.
- The backtest verdict vocabulary has no "outperform"; when evidence is insufficient, it shows inconclusive/insufficient.
- Stock splits are adjusted automatically, but when split data is unavailable, it errors at a 2:1 threshold; data sources depend on Yahoo (primary) and Tiingo (secondary, requires a free API key), and some tickers may be missing due to rate limiting.
- No specific information on fees, pricing, platform, etc. is provided.