Assumptions and scope
Money and positions
- All values use the prices in the prices CSV; there is no price history.
as_ofin the portfolio file is the date used for holding periods and wash-sale windows. costof a lot is per unit, in the same currency as the price. Accounts are assumed to share one currency.- Idle cash is a class (
cash). Cash flows are added to the account's cash before optimising; a withdrawal is a negative flow and is satisfied from cash first, then sells. - A security that maps to several classes (a 60/40 fund) contributes
value x weightto each class. Selling it moves both. - Securities with
fractional: falsetrade in whole units; everything else to four decimals.
Tax
- Rates are flat per category. India: equity 20% short term, 12.5% long term above the exemption, holding period 12 months; debt funds (and anything marked
debt) are taxed at the slab rate with no long-term treatment; other categories can be added undertax.categories(the India example adds a gold category). US: one category, user rates, 1-year holding period. - The LTCG exemption (India, ₹1.25 lakh) is applied once per run, assuming none of it has been used in the financial year. Edit
exemptionif part of it is already used. - Tax is assumed to be paid from funds outside the portfolio; it is optimised and reported but does not reduce cash. Cess, surcharge, state tax, NIIT and AMT are ignored.
- Net losses are not carried forward. In the US preset, up to
loss_deduction_capof net loss is credited at the ordinary rate; in India the default cap is 0. - Tax-deferred and tax-free accounts (EPF, PPF, NPS, 401k, IRA, Roth) have no tax on internal trades. Their withdrawal tax only enters
location. - The exact tax nets short- and long-term results within a category; the optimiser uses a slightly more conservative convex version (see
model.md).
Constraints
- FIFO lots are enforced exactly where the account says
lot_method: fifo; HIFO likewise.min_taxpicks the cheapest lots. - Wash sale: the rule is applied to the identical security in any account, within 30 days (configurable) before
as_ofor in the plan itself. Substantially identical funds, dividend reinvestments and the 30 days after the plan are not modelled; hold off buying the same security for 30 days after executing a plan. - Minimum trade size applies per account and security and side. A liquidation of a whole position smaller than the minimum is allowed.
- Fixed fee and minimum trade are heuristics (ban and re-solve), see
model.md.
Targets and bands
- Band = min(absolute, relative x target); a class breaches when drift is strictly larger. Defaults are 5 points and 25%.
- Glide-path targets are linear interpolation by age and clamp at the ends. Class bands still come from the
classesentries. - Targets must sum to 100%; a security mapped to an unknown class is rejected.
Asset location
- Flat expected returns and tax-efficiency scores per class (defaults for common class names, overridable in
location). The wealth number is an estimate under those assumptions, useful for ranking placements rather than forecasting. - The suggestion only changes where classes sit; acting on it means swapping holdings, which can realise gains in taxable accounts. Use
planfor the actual trades.