First tagged release. The tool supports the full rebalance workflow end-to-end:
allocator setup— store Monarch credentials in the OS keychainallocator sync— pull live brokerage/retirement/crypto holdings from Monarch (via its aggregated Coinbase feed); archives a dated snapshotallocator show— current-vs-target allocation table per portfolio, plus a combined cross-portfolio summary when multiple portfolios are definedallocator drift— positions ranked by drift from targetallocator plan --withdraw N --from P— sell list summing exactly toNallocator plan --deposit N --to P— buy list summing exactly toNallocator plan --whole-shares CASH_SYMBOL— round equity trades to whole shares; route the dollar residual through the named cash positionallocator history— portfolio totals over time, with day-over-day deltasallocator optimize— Monte-Carlo / MPT efficient-frontier scan using yfinance + CoinGecko price history, with max-Sharpe and min-volatility portfolios computed via SLSQP under optional per-symbol bounds
- Drift-first and proportional modes for both withdrawals and deposits, with sub-cent reconciliation so the sell/buy list sums to the target amount
- Whole-share quantization with cash-position absorber
- All monetary arithmetic on
Decimal; neverfloatin the math path - Vectorized random-portfolio cloud + SLSQP-optimized max-Sharpe / min-vol
~/.config/allocator/targets.yaml— hierarchical target allocation (with optional per-symbolmin_weight/max_weight/cash: true/coingecko_id:fields consumed byoptimize)~/.config/allocator/config.toml— user defaults (portfolio, mode, staleness threshold, risk-free rate)~/.cache/allocator/snapshot.json— rolling snapshot (chmod 600)~/.cache/allocator/snapshots/YYYY-MM-DD.json— dated history- macOS Keychain via
keyringfor Monarch credentials — never on disk, never logged, never in exception strings
- 130+ tests, 85%+ branch coverage, dependency-injected throughout (no
monkeypatchanywhere in the suite) - Hypothesis property test:
sum(sells) == withdrawalover random portfolios - Regression test against a synthetic 13-position diversified portfolio
pyright --strictclean onsrc/;ruffclean across the repo- GitHub Actions CI: lint, format, types, tests,
gitleaks