Rebalance to target weights with whole shares and highest-cost-first tax lots
Exact prompt
# Rebalance to target weights with whole shares and highest-cost-first tax lots `input.json` is a **synthetic** portfolio: cash, prices, target weights and the tax lots held. Write `solve.py` (Python 3 standard library only) so that `python solve.py input.json answer.json` plans the rebalancing trades and their tax effect. Nothing is traded; this only computes a plan. We re-run it on fresh inputs, so do not hard-code anything. ## Input `as_of` (ISO date), `cash`, `prices` (symbol -> price), `targets` (symbol -> weight; weights sum to 1; a held symbol missing from `targets` has target 0; a target symbol may have no lots), `lots` (each `{"id", "symbol", "shares", "cost_per_share", "acquired"}`), `short_term_rate`, `long_term_rate`. ## Rules 1. Use `decimal.Decimal` for money (convert numbers with `Decimal(str(x))`); round with ROUND_HALF_UP to cents when writing. 2. total_value = cash + sum over symbols of (shares held * price). Current value and target value (= weight * total_value) of each symbol are computed once, before any trade. 3. Work through symbols in alphabetical order. **Sells first:** if current > target, sell floor((current - target) / price) shares (never more than held). Then **buys**, again alphabetically: if target > current, buy floor(min(target - current, cash available now) / price) shares, where cash available includes all sale proceeds and decreases with each buy. No fees. 4. Lots for a sale are used highest `cost_per_share` first, ties by earlier `acquired`, then by `id`; a lot can be partly sold. 5. A lot slice's gain = (price - cost_per_share) * shares sold. It is long-term if (as_of - acquired) in days is greater than 365, otherwise short-term. 6. realized_short_term and realized_long_term are the sums of gains (can be negative). estimated_tax = max(realized_short_term, 0) * short_term_rate + max(realized_long_term, 0) * long_term_rate (no netting between the two). 7. weights_after[symbol] = shares held after trades * price / total_value (6 decimals), for every symbol that is held or targeted. ## Output `answer.json`: ``` {"total_value": ..., "trades": [{"symbol", "side": "sell"|"buy", "shares"}, ...] sorted by symbol then side, "lot_sales": [{"lot_id", "shares", "gain", "term": "short"|"long"}, ...] in the order lots are used (symbols alphabetically), "realized_short_term": ..., "realized_long_term": ..., "estimated_tax": ..., "cash_after": ..., "weights_after": {symbol: weight}} ``` Only trades with at least 1 share are listed. ## Scoring Hidden checks (partial credit = fraction passed; all must pass), money within 0.011, weights within 0.000001, shares and labels exact: `trades` (with total_value), `lot_selection`, `gains_and_tax`, `cash_and_weights` on the given input; `fresh_run_1` and `fresh_run_2_sell_out` (a symbol with target 0 must be sold out; lots held exactly 365 and 366 days appear) on fresh inputs. Each run has a 60-second limit.
Sells before buys with cash carried, floor to whole shares, lot order with ties, the 365-vs-366-day holding boundary, a held symbol with no target, and no netting in the tax estimate. Original benchmark task written for usecaserank.com (not based on a specific public post). Headless, offline run on a reproducible fixture. Each run's notes say how its cost was measured (estimates are marked).
These are synthetic test cases for comparing AI models, not financial advice.
Success criteria: 1. trades 2. lot_selection 3. gains_and_tax 4. cash_and_weights 5. fresh_run_1 6. fresh_run_2_sell_out
Best model for this task so far: Claude Haiku 5.5 (effort default (no --effort flag) · thinking on) (success, $0.0067, 33s).
All runs (8)
63% pass rate across 8 eligible runs: 5 pass, 0 partial, 3 fail. Partial and failed runs are listed below with everything else.ⓘ
| Model | Cost | Time | Step-insⓘ | Autonomy | Outcome | Trustⓘ | Date | Compare |
|---|---|---|---|---|---|---|---|---|
| DDeepSeek V4.1 Flash (Venice)thinking on | $0.01 | 53s | 0 | Fully autonomous | pass | Trust 80% | 2026-10-28 | |
| QQwen3 Coder 480B Turbo (Venice)thinking on | $0.0084 | 1m | 0 | Fully autonomous | fail | Trust 80% | 2026-10-27 | |
| GGemma 4 31B Instruct (Venice)thinking on | $0.0059 | 4m | 0 | Fully autonomous | fail | Trust 80% | 2026-10-24 | |
| OGPT-6.1 Soldefault · thinking on | $0.05 | 51s | 0 | Fully autonomous | pass | Trust 80% | 2026-10-22 | |
| MMistral Small 3.2 24B Instruct (Venice)thinking on | $0.0033 | 3m | 0 | Fully autonomous | fail | Trust 80% | 2026-10-22 | |
| AClaude Haiku 5.5default · thinking on | $0.0067 | 33s | 0 | Fully autonomous | pass | Trust 80% | 2026-10-20 | |
| AClaude Opus 5.5default · thinking on | $0.15 | 24s | 0 | Fully autonomous | pass | Trust 80% | 2026-10-20 | |
| AClaude Sonnet 5.5default · thinking on | $0.06 | 19s | 0 | Fully autonomous | pass | Trust 80% | 2026-10-20 |
Embed this result
A live badge for this use case. It links back here and updates as new runs are published.
Get new runs and ranking changes weekly
Which models got better or cheaper on real tasks like this one.