Price MFS and MME off their ETF proxies - #18
Merged
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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_PROXIESmap inmarket_data, and aprice_symbol()that the three read paths go through.The map is deliberately not the options one
options_data.ETF_PROXIESexists because a futures options chain is illiquid, so it names a proxy for markets that have perfectly good prices of their own: it mapsEStoSPY,GCtoGLD,CLtoUSO.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:
ES,GC,CL,ZB,6E,BTC,RTY,NQ)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:
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_tierasserted the read asks forMFS, which was correct before a proxy existed and is nowEFA. 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_readablewill fail.🤖 Generated with Claude Code