Look-through exposure, pairwise overlap and hidden concentration
Compute look-through sector and region exposures, pairwise ETF overlap and hidden single-name concentration from constituent holdings files, including recursive fund-of-funds expansion.
instruction.md
What the agent sees (CONVENTIONS.md is appended automatically)
Look-through exposure and overlap
Each /app/data/etf_holdings/{TICKER}.csv lists constituents with weight, sector and country. Some ETFs are funds-of-funds: a constituent whose identifier is itself a ticker in etf_meta.csv must be expanded recursively (max depth 3). Weights in a file may not sum to 1; normalise to the listed total and assign the residual to sector "Cash & Other". Identifiers must be canonicalised using /app/data/id_map.csv (share-class and formatting variants).
Write:
- /app/output/lookthrough.json — household sector weights, region weights (country to region via /app/data/regions.csv), top 25 single names with weight and the list of ETFs contributing, and hidden_concentrations: names with household weight > 4%.
- /app/output/overlap.csv — symmetric matrix of pairwise overlap = sum over constituents of min(w_A, w_B) after recursive expansion.
Verification
reward.json metrics · weights sum to 1.00 · tolerance abs 1e-8
| Metric | Weight | Check |
|---|---|---|
| exposures | 0.4 | Sector and region weights within tolerance. |
| overlap_matrix | 0.35 | All entries within tolerance; symmetric; diagonal = 1 after normalisation. |
| concentrations_exact | 0.25 | hidden_concentrations set equals oracle; top-25 order exact. |
Harbor scaffold
Generated from this record — task.toml, Dockerfile, verifier, oracle stub
schema_version = "1.4" [task] name = "portfolio-agent-evals/pf-analyze-lookthrough-overlap" version = "1.0.0" description = "Compute look-through sector and region exposures, pairwise ETF overlap and hidden single-name concentration from constituent holdings files, including recursive fund-of-funds expansion." keywords = ["etf", "portfolio", "analyze", "portfolio-analytics", "look-through", "recursion", "identifier-normalisation"] [metadata] author_name = "portfolio-agent-evals" difficulty = "medium" category = "quant-finance" tags = ["portfolio-analytics", "tier-2", "analyze", "multi-metric"] theme = "Portfolio Analytics & Exposure" tier = 2 reward_type = "multi-metric" [agent] timeout_sec = 1800.0 [verifier] timeout_sec = 180.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
- Fund-of-funds recursion (depth up to 3) — one nested fund holds another nested fund.
- Identifier variants (case, whitespace, BRK.B vs BRK-B) must be merged via id_map before summing.
- One file has weights in percent.
- Overlap must be computed after expansion, otherwise the fund-of-funds overlap is understated.
Inputs
Fixtures mounted in the environment
- /app/data/etf_holdings/, /app/data/regions.csv, /app/data/id_map.csv
- /app/portfolio/holdings.csv
- /app/data/prices/
- /app/data/etf_meta.csv
Outputs
What the verifier reads from /app/output
- /app/output/lookthrough.jsonJSONExposures and concentrations.
- /app/output/overlap.csvCSV matrixPairwise overlap.
Anti-gaming
Nesting structure and identifier variants are seed-generated.
Oracle notes
solution/solve.sh must score 1.0 on five seeds
Recursive expansion with memoisation; overlap via aligned sparse vectors.
Reviews (0)
Design review before a task is marked ready