Portfolio Agent EvalsHarbor task suite · ETF analyze → backtest → rebalance
Tax-Aware & Constrained Optimization/pf-opt-min-turnover-milp

Minimum-turnover trade list restoring all bands (MILP with semi-continuous trades)

Solve the minimum-turnover trade list that brings every sleeve within bands under whole-share and cash constraints, verified by optimality gap against a MILP oracle.

T3hardRebalancemulti-metricready
Edit
readystatic
Agent budget
40 min
Verifier budget
5 min
Tier target
25–50% pass expected

instruction.md

What the agent sees (CONVENTIONS.md is appended automatically)

Minimum turnover to restore bands

Find integer share trades minimising the sum of |traded notional| subject to: every sleeve within its IPS band post-trade (weights on the post-trade total including cash; trading costs excluded from the denominator), cash >= buffer, no shorts, and each trade either 0 or at least 250 USD notional.

Write trades.csv and /app/output/solution.json {turnover, solver, gap_claimed}. scipy (HiGHS) is available; heuristics are acceptable if they reach the gap.

Verification

reward.json metrics · weights sum to 1.00

MetricWeightCheck
feasibilitygate
0.4
All constraints. GATE at 0.2.
objective_gap
0.6
turnover <= 1.005 x oracle: full; linear to 0 at 1.10 x oracle.

Gates: feasibility. A gate failure caps or zeroes the trial reward regardless of other metrics.

Harbor scaffold

Generated from this record — task.toml, Dockerfile, verifier, oracle stub

schema_version = "1.4"

[task]
name = "portfolio-agent-evals/pf-opt-min-turnover-milp"
version = "1.0.0"
description = "Solve the minimum-turnover trade list that brings every sleeve within bands under whole-share and cash constraints, verified by optimality gap against a MILP oracle."
keywords = ["etf", "portfolio", "rebalance", "tax-and-optimization", "milp", "optimization", "constraint-modelling"]

[metadata]
author_name = "portfolio-agent-evals"
difficulty = "hard"
category = "quant-finance"
tags = ["tax-and-optimization", "tier-3", "rebalance", "multi-metric"]
theme = "Tax-Aware & Constrained Optimization"
tier = 3
reward_type = "multi-metric"

[agent]
timeout_sec = 2400.0

[verifier]
timeout_sec = 300.0

[environment]
# Offline by design: all data is synthetic and generated at build time.
network_mode = "none"
cpus = 2
memory_mb = 4096
storage_mb = 10240
build_timeout_sec = 900.0

Traps

Each must carry signal: a trap-blind solution must lose credit

  • The semi-continuous minimum notional needs binary indicators; relaxing it yields infeasible tiny trades.
  • The cash sleeve has its own band.
  • Weights denominator excludes costs by instruction — including them shifts the answer.

Inputs

Fixtures mounted in the environment

Outputs

What the verifier reads from /app/output

  • /app/output/trades.csv
    CSV
    Trades.
  • /app/output/solution.json
    JSON
    Objective and solver info.

Anti-gaming

Seeded instances tuned so a greedy heuristic lands at 1.08-1.15 x optimum.

Oracle notes

solution/solve.sh must score 1.0 on five seeds

scipy.optimize.milp with big-M indicators; solves in under 2 s.

Reviews (0)

Design review before a task is marked ready

    Reviews are read-only in static export.
    Tier 3 · Expert25–50% pass expected. Created 2026-01-01, updated 2026-01-01.