Loading live CAPM inputs, tax defaults, and the current model sheet.
0% · BUILDING MODEL VIEW
The allocator is a tax-aware constrained optimizer on factor risk, CAPM expected returns (with optional Black-Litterman blending, off by default), duration/liquidity controls, and explicit greeks. It produces decision-support ideas with scorecards (FoF, tails), not advice or order routing. Numbers are model outputs — precision ≠ certainty.
maximize after-tax utility subject to hard constraints
factor covariance plus portfolio greeks
reviewable proposal with audit flags
Fama-French 5 (market, size, value, profitability, investment) plus momentum, 5 ETF style factor proxies (quality, min-vol, momentum, value, large-cap value), and 11 GICS sector SPDR proxies (tech, health, financial, energy, industrial, staples, utilities, materials, real estate, comms, discretionary) reconstruct covariance from exposures instead of relying only on noisy pairwise history.
An optional overlay that blends market-implied equilibrium returns with model views. It ships disabled: the default path uses CAPM expected returns directly, without blending. See the model-view note below.
Every candidate is converted to after-tax expected return after expense, ordinary income, NIIT, state tax, LTCG, and wrapper treatment.
The solve respects sleeve weights, duration bands, liquidity floors, per-holding caps, muni caps, and wash-sale exclusions.
The model turns market data, fund metadata, tax rules, and client constraints into a single audited weight vector.
| Layer | Formula | Feeds |
|---|---|---|
| Factor exposure regression | R_i,t = alpha_i + beta_i * F_t + epsilon_i,t | beta loadings, residual risk, factor attribution |
| Covariance reconstruction | Sigma_assets = B * Sigma_factors * B' + D_epsilon | risk matrix for mean-variance and stress math |
| Black-Litterman posterior | E[R] = pi + tau Sigma P' (P tau Sigma P' + Omega)^-1 (Q - P pi) | shrunk expected returns from equilibrium plus views — optional overlay, off by default (default path uses CAPM views directly) |
| Return shrinkage | mu_i <- sleeve_mean + (1 - delta)(mu_i - sleeve_mean), delta=0.5 | regularizes after-tax returns within each sleeve so noise-level input error can't reshuffle the book (on by default) |
| Tax-aware utility | score(w) = w' mu_after_tax - lambda w' Sigma w - costs - penalties | weights optimized for client-specific after-tax tradeoffs |
| Tax drag | drag_i = yield_i * effective_rate_i + wrapper_adjustments_i | ordinary, NIIT, state, muni, Treasury, and LTCG treatment |
| Concentration (ENB) | ENB = 1 / sum(p_i^2) where p_i = PC variance share | PCA effective number of bets — prevents VOO+VTI+QQQ from looking diversified |
| Parametric portfolio risk simulation | N multivariate Student-t (df=6) draws under model μ,Σ (conservative default) | VaR/CVaR + multi-year path DD; calibration JSON is advisory until production_ready; not plan MC |
| Cash / FI horizon glide | gross = y * locked(dur,H) + (cash_neutral + term_premium) * (1 - locked) | Short FI and BOXX share the same rate anchor; tax character differs after glide |
| FoF complexity scorecard | matched-risk after-tax edge vs AOR-class (or income baseline); ≥25 bps full path | fof_scorecard only — implementation always multi-ETF (never “use AOR” CALL) |
| Efficient frontier sweep | solve for max after-tax return at each equity grid point | Pareto boundary of feasible stock/bond allocations |
| Horizon equity glide (optional) | equity_pct -= max(0, 25 - horizon) * 0.01, floor 20% | reduces equity for shorter investment horizons when enabled |
| Constraint | Expression | Why It Matters |
|---|---|---|
| Full investment | sum(w_i) = 1 | No unmodeled residual cash unless a cash sleeve is explicit. |
| Sleeve controls | min_s <= sum(w_sleeve) <= max_s | Keeps equity, bond, muni, Treasury, and alternatives in mandate. |
| Duration bounds | floor_d <= sum(w_bond * duration_bond) <= cap_d | Prevents yield chasing by hiding rate risk in long bonds. |
| Liquidity floor | sum(w_true_liquidity) >= liquidity_floor | Requires real cash-like ballast for short-horizon capital. |
| Concentration caps | w_i <= cap_i and role_count penalties | Stops one cheap ticker from swallowing the portfolio. |
| Wash-sale hygiene | blocked symbols and substitute-risk pairs excluded | Keeps tax-loss harvesting assumptions from being fake precision. |
| Instrument | Federal | NIIT | State | Modeled As |
|---|---|---|---|---|
Taxable MMF SWVXX | — | — | — | Ordinary income drag |
Treasury ETF USFR, TFLO | — | — | 0% | Federal plus NIIT, state exempt |
National Muni MEAR, IBMx | 0% | 0% | —* | Federal tax-free, state source checked |
NC Long-Muni NTFIX | 0% | 0% | 0% | In-state tax-exempt income |
Deferred LTCG (BOXX) BOXX | — | — | — | LTCG/deferral with suitability flags |
State defaults use the active tax profile. Out-of-state municipal income and fund-specific source breakdowns require review.
These features are available through the REST API but not exposed in the web wizard. They require inputs the UI does not collect.
| Feature | Required Input | What It Does |
|---|---|---|
| Tax-loss harvesting | current_positions with cost basis | Scans for underwater positions, proposes non-substantially-identical swap partners, values losses at IRC 1211 rates, enforces 30-day wash-sale window with outside-account checking. |
| Sensitivity analysis | POST /allocator/sensitivity | Re-runs the optimizer with expected returns shocked +/-10% and reports weight stability. A stable recommendation is a prerequisite for a defensible allocation. |
| Foreign tax credit | foreign_tax_credit_rate | Reduces effective tax drag on international ETFs by the foreign tax credit rate. UI sends 0.0; API callers can pass the actual rate. |
| Transition optimization | current_positions + transition params | Models the tax cost of moving from current holdings to the target portfolio, amortizes one-time costs over the horizon, and recommends whether to transition now or phase it. |
Review Before Implementation
All allocations are proposals for review. Tax treatment, suitability, liquidity, and fund-specific assumptions still need human verification before client use.