Portfolio Agent EvalsHarbor task suite · ETF analyze → backtest → rebalance
Tax-Aware & Constrained Optimization/pf-tax-loss-harvest-swap

Tax-loss harvesting into partner ETFs with exposure and wash-sale guards

Identify and execute tax-loss harvests into designated partner ETFs while maintaining sleeve exposure and respecting the wash-sale window in both directions.

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

instruction.md

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

Tax-loss harvesting

Find lots in the taxable account with unrealised loss >= 1,000 USD and >= 2% of cost. Sell them and buy the designated partner ETF (tlh_pairs in ips.yaml) so that each sleeve's household weight moves by less than 1%. Do not harvest a lot if the ticker or its identical pair was bought within the last 30 days anywhere in the household, and record a 31-day blackout for each harvested ticker in /app/output/blackout.json. Respect the single-ETF concentration limit in ips.yaml.

Estimate tax alpha = harvested loss x applicable rate. Write trades.csv and /app/output/harvest_report.json.

Verification

reward.json metrics · weights sum to 1.00

MetricWeightCheck
harvested_loss
0.4
>= 98% of oracle's harvestable loss with no ineligible lot included.
violations_zerogate
0.3
Wash-sale and concentration violations = 0. GATE at 0.2.
exposure_maintained
0.3
Every sleeve moves < 1%.

Gates: violations_zero. 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-tax-loss-harvest-swap"
version = "1.0.0"
description = "Identify and execute tax-loss harvests into designated partner ETFs while maintaining sleeve exposure and respecting the wash-sale window in both directions."
keywords = ["etf", "portfolio", "rebalance", "tax-and-optimization", "tax-loss-harvesting", "wash-sale", "exposure-management"]

[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 = 240.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 partner ETF is already held; the swap can breach the concentration limit for one seed group — harvest partially.
  • Threshold is per lot, not per position.
  • A recent IRA purchase of an identical pair blocks one otherwise-attractive harvest.

Inputs

Fixtures mounted in the environment

  • /app/portfolio/
  • /app/policy/ips.yaml, /app/policy/tax_profile.yaml, /app/policy/identical_pairs.csv
  • /app/data/prices/

Outputs

What the verifier reads from /app/output

  • /app/output/trades.csv
    CSV
    Harvest sells and partner buys.
  • /app/output/harvest_report.json
    JSON
    Lots harvested, tax alpha.
  • /app/output/blackout.json
    JSON
    Blackout windows.

Anti-gaming

Loss lots, partner holdings and recent buys are seeded.

Oracle notes

solution/solve.sh must score 1.0 on five seeds

Enumerate eligible lots, then LP for partial harvest under the concentration cap.

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.