Tracking-error minimisation with Ledoit–Wolf covariance and a cardinality cap
Select at most five ETFs and weights minimising ex-ante tracking error to a benchmark composite using a Ledoit–Wolf covariance, with an optimality-gap check.
instruction.md
What the agent sees (CONVENTIONS.md is appended automatically)
Tracking-error minimisation with cardinality
From 12 candidate ETFs choose at most 5, long-only, weights summing to 1, max 40% each, minimising ex-ante annualised tracking error versus the benchmark column global_6040, using the Ledoit–Wolf (2004, constant-correlation target) shrinkage covariance of daily returns over the trailing 756 observations, which you must compute yourself.
Write /app/output/weights.json {weights, tracking_error_ann, shrinkage_intensity, method}.
Verification
reward.json metrics · weights sum to 1.00
| Metric | Weight | Check |
|---|---|---|
| covariance_correct | 0.3 | Shrinkage intensity abs 1e-6; TE recomputed from agent weights with oracle covariance matches the claimed TE rel 1e-6. |
| te_gap | 0.5 | TE <= 1.05 x oracle optimum. |
| constraints | 0.2 | Cardinality, bounds, sum to 1. |
Harbor scaffold
Generated from this record — task.toml, Dockerfile, verifier, oracle stub
schema_version = "1.4" [task] name = "portfolio-agent-evals/pf-opt-tracking-error-cardinality" version = "1.0.0" description = "Select at most five ETFs and weights minimising ex-ante tracking error to a benchmark composite using a Ledoit–Wolf covariance, with an optimality-gap check." keywords = ["etf", "portfolio", "rebalance", "tax-and-optimization", "covariance-shrinkage", "qp", "cardinality-optimization"] [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
- Ledoit–Wolf constant-correlation formula details (the 'Honey, I shrunk the sample covariance matrix' version).
- Benchmark returns must be aligned to the same dates.
- Greedy forward selection misses the optimum; exhaustive enumeration of 792 subsets is feasible.
Inputs
Fixtures mounted in the environment
- /app/data/prices/
- /app/data/benchmarks.csv
- /app/data/dividends.csv
Outputs
What the verifier reads from /app/output
- /app/output/weights.jsonJSONSelected weights and diagnostics.
Anti-gaming
Candidate set and benchmark composition are seeded.
Oracle notes
solution/solve.sh must score 1.0 on five seeds
Enumerate subsets, solve each QP with bounds, take the minimum.
Reviews (0)
Design review before a task is marked ready