Skip to content

Price MFS and MME off their ETF proxies - #18

Merged
mspinola merged 2 commits into
mainfrom
claude/price-proxy-symbols
Aug 21, 2026
Merged

Price MFS and MME off their ETF proxies#18
mspinola merged 2 commits into
mainfrom
claude/price-proxy-symbols

Conversation

@mspinola

Copy link
Copy Markdown
Owner

MFS and MME are ICE MSCI futures that Norgate carries no continuous series for, so there is no futures price to read. cotdata still holds their COT, which is why they are in the universe at all. Until now they had no prices whatsoever and every price-derived column for them was empty.

marketdata now registers EFA and EEM and the store holds their bars (mspinola/marketdata#17). This is the half that uses them: a PRICE_PROXIES map in market_data, and a price_symbol() that the three read paths go through.

The map is deliberately not the options one

options_data.ETF_PROXIES exists because a futures options chain is illiquid, so it names a proxy for markets that have perfectly good prices of their own: it maps ES to SPY, GC to GLD, CL to USO.

Reusing that map for prices would replace S&P futures prices with an ETF across the entire book, and the result would look plausible. So most of the new test file guards that blast radius rather than the feature:

  • eight markets asserted never to proxy (ES, GC, CL, ZB, 6E, BTC, RTY, NQ)
  • a check that the two maps share no keys
  • an exact assertion on the map's contents, so growing it fails here and has to be argued for rather than passing quietly

The substitution is real, and the map says so

An ETF tracks its index net of fees, in USD, on US session hours. The future carries basis, financing and a currency treatment it does not. Levels are not comparable and neither are returns over a dividend date, so anything comparing these two markets against genuinely futures-priced ones needs to know. Both are Role: heldout, so this feeds display and indexing rather than anything selected or traded.

Verification

Cold cache, real 47-market universe:

MSCI EAFE              rows=792  priced_weeks=792   last_close=108.09
MSCI Emerging Mkts     rows=792  priced_weeks=792   last_close=65.43
Gold                   rows=1929 priced_weeks=1180  last_close=4441.10   <- control, unchanged

Both go from zero priced weeks to fully priced. 294 passed, ruff clean.

One existing test changed rather than being added to: test_the_rejection_scores_read_does_not_pin_a_tier asserted the read asks for MFS, which was correct before a proxy existed and is now EFA. Its actual point, that the tier must be one an equity accepts, is unchanged.

Order

Merge mspinola/marketdata#17 first. Without it there is no EFA/EEM to resolve to, and test_the_proxies_are_actually_readable will fail.

🤖 Generated with Claude Code

mspinola and others added 2 commits August 20, 2026 21:50
Both are ICE MSCI futures that Norgate carries no continuous series for, so there is
no futures price to read. cotdata still holds their COT, which is why they are in the
universe. Until now they had no prices at all and every price-derived column for them
was empty.

marketdata now registers EFA and EEM and the store holds their bars
(marketdata claude/register-msci-proxies), so this is the half that uses them: a
PRICE_PROXIES map in market_data, and a price_symbol() the three read paths go through.

The map is deliberately NOT options_data.ETF_PROXIES, and the difference is the whole
point. That one exists because a futures OPTIONS chain is illiquid, so it names a proxy
for markets that have perfectly good prices of their own: it maps ES to SPY. Reusing it
here would replace S&P futures prices with an ETF across the entire book, and the result
would look plausible. Most of the new test file guards that blast radius rather than the
feature: eight markets asserted never to proxy, and a check that the two maps share no
keys.

The substitution is real and the map says so. An ETF tracks its index net of fees, in
USD, on US session hours; the future carries basis, financing and a currency treatment
it does not. Levels are not comparable and neither are returns over a dividend date.
Both markets are Role: heldout, so this feeds display and indexing rather than anything
selected or traded.

Verified on a cold cache against the real universe: MSCI EAFE and MSCI Emerging Mkts
both go from zero priced weeks to 792 of 792, with Gold unchanged as a control.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The bars half of test_the_proxies_are_actually_readable could only ever pass on a
machine with a populated store. CI points MARKETDATA_STORE at an empty /tmp directory,
so it failed on all four Python versions, and no amount of merging would have fixed it:
the registry half needed marketdata #17, but the bars half needed a deployment.

Split in two, because they are two different kinds of fact. The registry check is about
the INSTALLED marketdata and skips with a message naming the PR to pull. The bars check
is about this machine's store and skips with the exact seeding command. Run with -rs and
the skip says which, rather than the test either failing forever in CI or quietly
asserting nothing.

Verified both ways: against the real store 17 pass, and against an empty store 15 pass
with 2 skips naming EFA and EEM.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@mspinola
mspinola merged commit 0d06cf9 into main Aug 21, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant