contract-intel
Skill8 starsChanged 4 months agoApache-2.0View on GitHub
Symbol discovery, front-month resolution, rollover-imminence classification, and product-family awareness (full ↔ micro pairs like ES/MES) for futures contracts. Resolves bare product codes like "ES" or "NQ" to the actual tradeable front-month contract (e.g., ESU6) by open-interest rank across maturities. Classifies rollover status as not_imminent / approaching / imminent / rolled, with calendar-spread candidate flag when both legs are liquid. Use when the user asks "what symbol", "which contract to trade", "front month", "roll" or "rollover", "micro" or "full", or "calendar spread". Also use when the user gives a bare product code (ES, NQ, YM, CL, GC, etc.) without a maturity. Also handles product-family metadata via search_contracts includeFamilySiblings flag.
In this repository13 other files it gives its agents.
- AGENTS.mdAGENTS.md
- alerts-composerSkill
- chart-renderSkill
- correlation-hedgeSkill
- event-watchSkill
- market-contextSkill
- position-watchdogSkill
- pretrade-riskSkill
- risk-coachSkill
- scale-managerSkill
- trade-debriefSkill
- trade-journalSkill
- trade-replaySkill
The file
We split this skill into the rules it gives an agent
9 rules. About 0 are common, 3 are distinctive, and 6 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈3
Distinctive · estimate
This author's own choices. Worth a look.
6
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 25
Call it with includeFamilySiblings=true.
- Very specific: line 52
Use front_month.symbol for any follow-up tool call (place_order, market_history, etc.).
- Very specific: line 56
When the user asks "is ES about to roll?" or "should I switch contracts?", run rollover.py on the same input:
- Very specific: line 86
When the user asks "is there a micro of ES?" or "ES vs MES?" — call search_contracts with the includeFamilySiblings field.
- Very specific: line 98
When the user asks about Kalshi markets — read the kalshi-events MCP resource, not search_contracts.
- Very specific: line 108
Always quote the exact contract symbol — never invent.
- Distinctive: line 112
Not imminent: "Liquidity is in {symbol} ({oi_fmt} OI, {days} days).
- Distinctive: line 113
No rollover action needed right now."
- Distinctive: line 120
When narrating full vs micro:
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
contract-intel
Purpose
This skill turns a user's bare product code ("ES") into the actual tradeable contract. It flags rollover risk. It surfaces the full-vs-micro sibling when relevant. This skill does not resolve symbols server-side, for two reasons. The per-maturity OI query costs the same either place. Also, the skill gains more narrative flexibility this way.
Environment routing
This covers symbol and market data only, with no account binding. A sibling skill's account resolution might already fix a session to demo (simulation) or live. If so, stay on that same MCP server for consistency.
MCP tools used
Tool names below are bare. The NinjaTrader MCP server provides them. Your client adds its own prefix. See AGENTS.md at the repo root.
market_snapshot— resolve the front-month contract and its rollover status from a bare product code. Prune withfields=["snapshots[].symbol","snapshots[].expirationDate","snapshots[].totalVolume","snapshots[].openInterest","snapshots[].lastPrice"].search_contracts— look up the full/micro sibling for a product. Call it withincludeFamilySiblings=true.
Workflow
1. Front-month resolution
When the user says "buy ES" or asks "what's NQ doing?", resolve the bare product code to a specific contract. Do this before any other tool call. Save the tool result to a file. Pass its path with --file. Never re-type or inline a large JSON payload in the command.
market_snapshot(
product="ES",
fields=["snapshots[].symbol","snapshots[].expirationDate","snapshots[].totalVolume","snapshots[].openInterest","snapshots[].lastPrice"]
)
# Save that response to market_snapshot.json, then:
python3 scripts/resolve.py --file market_snapshot.jsonmarket_snapshot with product returns every non-expired maturity. Prune the response to the five fields that the resolve and rollover scripts read. resolve.py returns:
front_month— the contract with the highest OI among the nearest two maturities. This handles mid-rollover, when the next maturity overtakes the nearest.next_month— the maturity immediately after frontoi_ratio— front OI / next OIrolled_already— true if the second-nearest maturity has more OI than the nearest
Use front_month.symbol for any follow-up tool call (place_order, market_history, etc.).
2. Rollover status
When the user asks "is ES about to roll?" or "should I switch contracts?", run rollover.py on the same input:
market_snapshot(
product="ES",
fields=["snapshots[].symbol","snapshots[].expirationDate","snapshots[].totalVolume","snapshots[].openInterest","snapshots[].lastPrice"]
)
# Run rollover.py on the same saved response:
python3 scripts/rollover.py --file market_snapshot.jsonReturns a status classification. The script applies these rules in order, and the first match wins:
rolled— next OI > front OI, at any day count. Trade the next contract.imminent— 5 days or fewer to expiry, at any open interest. Proximity overrides open interest here. Tell the user to roll the position or to close it before expiration.not_imminent— days > 15 AND the next month cannot absorb a roll. Either the next month holds no open interest, or the front holds more than 5x it. No action needed.imminent— 5 to 15 days out AND next OI is 50% of front OI or more. Rollover happens now. Execution runs thinner than usual.approaching— every other case. Prefer the front contract. Watch for rollover in a few days.
Also emits a ready-to-narrate narrative string and a calendar_spread_candidate flag. This flag is true when both legs have liquidity. The OI ratio is then between 0.3 and 3, during approaching or imminent status.
3. Product family (micro / full)
When the user asks "is there a micro of ES?" or "ES vs MES?" — call search_contracts with the includeFamilySiblings field. That field adds each hit's full/micro counterpart to the result:
search_contracts(text="ES", includeFamilySiblings=true)Each result's familySibling field (when present) gives the counterpart's product name, description, isMicro flag, and valuePerPoint. Narrate the contrast directly. No script needed.
The product family might not appear in the search results. If so, load references/product-glossary.md for the common-pairs table and margin intuition.
4. Event contracts (Kalshi)
When the user asks about Kalshi markets — read the kalshi-events MCP resource, not search_contracts. Read it by its URI, through whatever resource-read action your client provides:
tradovate://kalshi-eventsEvent contracts resolve to a single date (no rollover) and live in the separate tradovate://kalshi-events resource. Detect a Kalshi entry by that resource URI, not by a productType value. See references/product-glossary.md § Event contracts for more.
Output idioms
Always quote the exact contract symbol — never invent. ESU6, not ES or @ES. Pulled from market_snapshot.symbol or search_contracts.symbol.
When narrating rollover:
- Not imminent: "Liquidity is in {symbol} ({oi_fmt} OI, {days} days). No rollover action needed right now."
- Approaching: "{front} is still the front contract, but {next} is picking up. Expect rollover in the next few sessions."
- Imminent: "{front} vs {next} — rollover window. Liquidity is split; execution may be thinner than usual. Consider rolling now."
- Rolled: "{front} has already lost liquidity to {next}. Trade {next}."
When narrating full vs micro:
- "The micro of ES is MES — 1/10th the notional ($5/point vs $50/point for ES), same tick size. Use it for finer sizing or to round out your full-size exposure."
Disambiguation
- vs
correlation-hedge: contract-intel handles same-underlying alternatives (ESU6 vs MES, ES front vs next month). Cross-underlying pairs like ES/NQ — how correlated, how to hedge one with another — live incorrelation-hedge. - vs
pretrade-risk: this skill resolves the symbol. Pretrade-risk sizes the trade on that symbol. Always run resolve first. - vs
search_contractsdirectly: if the user already named a specific contract (ESU6, not "ES"), skip this skill. Go straight to the target tool. This skill is for disambiguation from bare product codes.
Known gotchas
- Contract symbols are exact.
ESU6trades.ESdoes not. Never accept a bare code from the LLM as a tradeable symbol without running it throughresolve.pyfirst. - Monthly contracts (CL, NG) expire the month before the contract
month (CLU6 expires late August, not September). Never infer from the
symbol. Always use
market_snapshot.expirationDate. rolled_alreadyinresolve.pydiffers fromstatus = "rolled"inrollover.py. The first is a fact about the two nearest maturities. The second is a classification that also weighs OI ratio and days.
Resource layout
scripts/resolve.py— bare product code → front-month resolution (input:market_snapshot(product=...)response)scripts/rollover.py— rollover-status classification + narrative (same input)scripts/fixtures/— three synthetic ES snapshots covering not_imminent, imminent, and rolled states for regression testingreferences/product-glossary.md— full/micro pairs, tick intuition, settlement types, rollover conventions. Load it when you narrate a cross-product contrast, or whenmarket_snapshotdoes not provide the needed context
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

