get_earnings_window
Next scheduled earnings date for a ticker, and — given an expiration or an
OCC contract — whether that print lands ON OR BEFORE the expiration
(`earnings_in_window`). This is the doctrine hard-exclusion check: never
hold a long single-leg option through earnings (IV crush). The engine
applies this rail only at its own pick time, NOT in the pool — pool rows
CAN carry earnings-window names, so check every candidate yourself.
One call per candidate: pass the pool's `recommended_contract` verbatim
and both the ticker and expiration are derived for you.
FAIL-CLOSED: if the date is unknown (provider gap/outage, unannounced
small-cap), `earnings_in_window` is null and the response says to treat
the name as in-window. A confirmed date is still a provider estimate
until the company confirms — re-check near the date.
Args:
ticker: underlying symbol, e.g. "AAPL" (optional if contract given).
expiration: option expiration "YYYY-MM-DD" to test the window against
(optional; derived from contract when contract is given).
contract: OCC-style option ticker (e.g. "O:UNIT260717C00030000") —
supplies both ticker and expiration in one argument.
Returns:
{ticker, next_earnings_date, is_estimated, last_reported_date,
expiration, earnings_in_window, source, as_of, note}
— `earnings_in_window`: true (print on/before expiration — doctrine
says exclude), false (next print is after expiration), or null
(unknown — treat as in-window).
get_contract_marks
DAILY mark series (OHLCV) for one option contract over a date range — the
data you need to mark a live paper position day by day, or to replay a
closed one under YOUR OWN exit rule. Composes with `get_contract_snapshot`
(the right-now read).
Marks are option-premium daily bars from the upstream aggregates feed
(delayed per plan; thin contracts can have gap days with no bar — a
missing date means NO trades printed that day, not a data bug). The
close is the honest end-of-day mark on this quotes-less data plan.
This server does NOT simulate exits — bring your own rule (the RM-004
boundary). For distributional exit research use `estimate_exit_rule` /
`get_harvest_curve`; for excursion context use `get_opportunity_surface`.
Args:
contract: OCC-style option ticker exactly as served by the pool tools
(e.g. "O:UNIT260717C00030000").
from_date: start "YYYY-MM-DD" (default: 30 days before to_date).
to_date: end "YYYY-MM-DD" inclusive (default: today ET). Span is
capped at 120 days.
Returns:
{contract, from_date, to_date, bar_count, bars: [{date, open, high,
low, close, volume, vwap, transactions}], source, note}
replay_contract
INTRADAY minute path for one option contract on one session — the exact
tape an intraday entry/exit rule replays against (RM-002). Optionally
pass a bracket (target_pct/stop_pct, PERCENT of the 10:00 ET anchor) and
the response also reports the exact FIRST-CROSSING sequence: when each
level was first touched and which came first — measured from the tape,
not inferred from extremes.
Pool contracts' excursion windows (entry day + 2 sessions) are served
from the engine's minute-path table; anything else falls back to an
upstream minute-aggregates fetch, so ANY contract/session in plan history
works. Option tape is THIN — minutes with no prints have no bar, and
lows between prints are unobservable; treat touch times as evidence, not
tick-perfect truth.
This server does NOT simulate or validate exits (the first-crossing
readout is a fact about the past tape, not a recommendation) — the rule
engine is yours. For cohort-level rule scoring use `estimate_exit_rule`.
Args:
contract: OCC-style option ticker (e.g. "O:UNIT260717C00030000").
date: ET session date "YYYY-MM-DD".
target_pct: optional +X% level (percent of the anchor mark, e.g. 40).
stop_pct: optional -Y% level (e.g. 30 or -30 both mean -30%).
Returns:
{contract, date, bar_count, bars: [{t, open, high, low, close,
volume, ...}], anchor: {price, timestamp, definition},
first_crossing?: {target_level, stop_level, first_target_touch,
first_stop_touch, first: TARGET|STOP|AMBIGUOUS_SAME_BAR|NONE},
retrieved_from, note}
get_pool_features
Point-in-time FEATURE VECTORS for the labeled candidate pool, served from
the leakage-safe allowlist view `enriched_features_v1` (identity + features
+ cohort metadata only — no outcome, label, or telemetry column can appear
here by construction).
This is the quantitative substrate for research and for joining against
`query_outcomes` / `get_opportunity_surface`. NOTE: the labeled substrate
lags the live pool by ~1-2 trading days (rows appear once the same-day
replay has run). For TODAY'S live pool with narrative enrichment, use
`get_enriched_signals` instead.
Every feature is known as-of <= scan_date (the selection point). Caveats:
`recommended_oi` / `recommended_volume` (and derived `volume_oi_ratio`,
`moneyness_pct`) are session-frozen snapshots; `recommended_spread_pct` is
permanently NULL on the current data plan.
Args:
scan_date: YYYY-MM-DD. Defaults to the most recent labeled scan date.
ticker: Optional ticker filter.
limit: Max rows (default 50, clamped 1-100).
Returns:
{scan_date, row_count, rows: [feature vectors...]}
get_opportunity_surface
The OPPORTUNITY SURFACE — per-contract realized excursions of the option
premium over a fixed multi-day window with NO exit rule applied. This is
"profit potential with the exit left as a free variable": your agent
derives any entry/exit policy offline from these extremes.
Per contract: `opp_peak_return` (max favorable excursion / MFE) and
`opp_trough_return` (max adverse excursion / MAE) as FRACTIONS of the
10:00 ET entry cost basis (0.40 = +40%), `opp_minutes_to_peak/trough`
(minutes from entry to each extreme), `opp_window_days` (trading days in
the window, entry day included), and `opp_status`.
This is NOT a tradeable label and NOT a feature — it is realized excursion
over a closed window. Only rows whose window has fully closed are returned
by default (`opp_status='OK'`).
For the DISTRIBUTIONAL "typical path" summary of this surface — P(peak
reaches +X%) with confidence intervals, day-of-peak buckets (peaks land
day 2-3, not day 1), stop-touch rates, and the giveback pattern — use
`get_harvest_curve`; to score a specific exit rule against it, use
`estimate_exit_rule`. This tool returns the per-contract rows those
aggregate.
Args:
scan_date: YYYY-MM-DD — return just that scan date's pool.
ticker: Optional ticker filter (across the lookback if no scan_date).
days: Lookback window in days when scan_date is not given
(default 30, clamped 1-120).
include_open: Include rows whose excursion window has not closed yet
(opp_status != 'OK'; their MFE/MAE columns are NULL/partial).
Returns:
{row_count, rows: [...], meta: {statuses_included, note}}
query_outcomes
Row-level REALIZED LABELS for the full candidate pool, joined to their
point-in-time feature vectors. Ask questions like "how did pool contracts
with |delta| 0.20-0.46 behave under the same-day bracket?"
Two distinct label horizons — never pooled together:
* `same_day`: the live V7.1 GIGO bracket (enter 10:00 ET day after scan,
+40% target / -30% stop, flat 15:45 ET same day). Label =
`realized_return_pct` (FRACTION).
* `3d`: the legacy 3-trading-day companion bracket (+80% / -60%,
exit 15:50 ET day 3). Label = `realized_return_pct_3d`.
Features come from the leakage-safe `enriched_features_v1` allowlist view;
label columns are joined from the outcome table (label-join pattern). Rows
with NULL labels and (same-day) `illiquid_exit=TRUE` rows are EXCLUDED by
default — exclusion counts are reported in `meta` because the illiquid
tail (~28% of the pool) is non-random and must not be silently hidden.
Args:
horizon: "same_day" or "3d".
scan_date_from / scan_date_to: YYYY-MM-DD range bounds (inclusive).
ticker: Optional ticker filter.
delta_min / delta_max: Bounds on |recommended_delta| (0-1).
min_overnight_score: Floor on overnight_score (1-10).
exit_reason: Filter (TARGET | STOP | TIMEOUT | ...) on the chosen horizon.
limit: Max rows (default 100, clamped 1-200).
aggregate_only: True = skip row-level output and return summary stats
(n, win_rate, avg/median/p25/p75, avg MFE/MAE) over the filtered
set — rows are verbose; use this when you only need the shape.
Returns:
{horizon, row_count, rows: [...features + labels...],
meta: {excluded_null_label, excluded_illiquid, pool_rows_in_window, note}}
or, with aggregate_only: {horizon, aggregate: {...}, meta: {...}}.
get_outcome_summary
Aggregate realized-label statistics over the full labeled pool, optionally
grouped by a whitelisted feature dimension. The exploration companion to
`query_outcomes` — use it to see how outcomes distribute before pulling
row-level data.
Per group: n, win_rate (label > 0), avg/median/p25/p75 of the label,
avg MFE (`opp_peak_return`) and avg MAE (`opp_trough_return`). Labels and
excursions are FRACTIONS (0.40 = +40%).
IMPORTANT: the whole-pool composite under any fixed exit is NEGATIVE by
design of the problem — the pool sells opportunity, not a return. This
tool exists to study CONDITIONAL structure (which feature slices behave
differently), not to compute a strategy track record.
Args:
horizon: "same_day" (live V7.1 GIGO bracket) or "3d" (legacy +80/-60).
group_by: one of none | delta_bucket | overnight_score | premium_score
| exit_reason | day_of_week | moneyness_bucket. Strict whitelist.
scan_date_from / scan_date_to: YYYY-MM-DD range bounds (inclusive).
Returns:
{horizon, group_by, groups: [...], meta: {exclusions, disclaimer}}
estimate_exit_rule
RESEARCH-ONLY — "bring your exit, we score it": score YOUR exit rule
against every closed-window pool contract. Two rule families:
* rule="bracket" (default): fixed target/stop, classified against the
realized opportunity surface (MFE/MAE extremes over the 3-trading-day
window). Rows where BOTH levels were crossed are resolved by EXACT
first-crossing from the minute-path tape where coverage exists
(TARGET_EXACT / STOP_EXACT); only uncovered rows fall back to the
extreme-order heuristic — check `heuristic_share` (now typically ~0).
* rule="trailing" (TF-14): hard initial stop (stop_pct) + a trailing stop
that gives back trail_pct from the running peak, optionally armed only
after +activation_pct. Replayed bar-by-bar on the minute-path tape in
SQL; contracts never stopped ride to the window end (last bar close).
This tool surfaces excursion EVIDENCE; it does not prescribe or validate
an exit — the exit is yours. Measured context (2026-07-06 pool study):
every fixed target <= +80% tested EV-NEGATIVE pool-wide, because cheap
targets amputate the right tail that pays for the ~half of contracts that
never pop. Read any single rule's stats as a description of the surface,
never as a strategy.
Bracket classification per contract:
* TARGET / STOP — only one level was crossed (definitive from extremes).
* TARGET_EXACT / STOP_EXACT — both crossed; resolved by exact first
touch on the minute tape (same-bar touch resolves STOP-first,
matching the engine labeler's pessimistic rule).
* TARGET_HEURISTIC / STOP_HEURISTIC — both crossed, no minute coverage;
resolved by which EXTREME came first. Best-effort, not exact.
* TIMEOUT — neither level hit; true exit return bounded by
[avg MAE, avg MFE] of the timeout group.
Also returns `exact_label_match` when your bracket equals a rule the
engine labels exactly: same_day +40/-30 (`realized_return_pct`, the live
V7.1 GIGO policy) or 3d +80/-60 (`realized_return_pct_3d`) — exact labels
include real fill/slippage mechanics and beat any surface estimate.
Thin-tape caveat (both families): option minutes with no prints have no
bar and lows between prints are unobservable — touch-based results are
evidence, not tick-perfect truth. No slippage is applied.
Args:
target_pct: bracket profit target in PERCENT of entry premium
(e.g. 40 = +40%). Clamped 5-300. Required for rule="bracket";
ignored for rule="trailing".
stop_pct: initial/hard stop in PERCENT (e.g. -30 or 30 both mean a
-30% stop). Clamped magnitude 5-95. Used by BOTH rule families.
horizon: "3d" (the excursion window) or "same_day" (trailing only:
day-1 bars through 15:45 ET; bracket: exact-label stats only).
scan_date_from / scan_date_to: YYYY-MM-DD range bounds (inclusive).
rule: "bracket" (default) or "trailing".
trail_pct: trailing giveback in PERCENT off the running peak
(e.g. 25 = exit when premium falls 25% from its high-water mark).
Required for rule="trailing". Clamped 5-95.
activation_pct: arm the trail only once the premium has traded
at/above entry x (1 + this many PERCENT). Default 0 = armed once
the premium has traded at/above the entry mark. Clamped 0-300.
Returns:
bracket: {params, n_classified, buckets, heuristic_share,
est_win_rate, ev_bounds, exact_label_match?, meta}
trailing: {params, n_scored, n_excluded_no_bars, stop_share,
timeout_share, est_win_rate, avg_return, median_return,
p10, p90, meta}
get_harvest_curve
The HARVEST CURVE — for each profit target X, the probability a pool
contract's premium TOUCHED +X% at least once inside the 3-trading-day
excursion window (10:00 ET entry), with confidence intervals, which day
the peak landed on, and stop-touch rates. Computed live from the closed-
window opportunity surface, so it moves as data accrues.
This is the ceiling for any limit-at-+X% exit: a TOUCH IS NOT A FILL (bar-
high events, no exit slippage). Measured context (2026-07-06 study): about
half of contracts touch +20%, ~1 in 7 touches +100%, meaningful pops land
on day 2-3 not day 1, and every FIXED target tested EV-negative pool-wide
— use this curve to understand the surface, not as a strategy return.
Args:
targets: Profit targets in PERCENT (default [15,20,30,50,75,100]);
each clamped 5-300, max 12 values.
stops: Stop levels in PERCENT magnitude (default [30,60]); each
clamped 5-95, max 6 values.
scan_date_from / scan_date_to: YYYY-MM-DD range bounds (inclusive).
delta_min / delta_max: Bounds on |recommended_delta| (0-1).
Returns:
{window, n, median_peak_return, targets: [{target_pct, p_touch,
ci95, n_touch, day_of_peak: {day1,day2,day3}}], stops: [{stop_pct,
p_touch, ci95}], meta}
get_regime_context
Point-in-time market-regime context for a scan date: VIX close, VIX3M,
SPY trend state, and the 5-day VIX delta — all as-of <= scan_date (the
selection point, leakage-safe), plus the engine's regime safety rail
evaluated on those values.
The rail: the engine fail-closes (no trade) when spot VIX > VIX3M
(backwardation — the market pricing imminent volatility is an adverse
regime for short-dated directional longs).
Served from the labeled substrate, which lags the live pool by ~1-2
trading days. Values are constant per scan_date.
Args:
scan_date: YYYY-MM-DD. Defaults to the latest scan date carrying
regime features.
Returns:
{scan_date, vix_at_scan, vix3m_at_enrich, spy_trend_at_scan,
vix_5d_delta_at_scan, regime_rail_pass, rail_definition}
list_playbooks
List the methodology playbooks this server publishes.
Playbooks are versioned server-side documentation of HOW to use the data
tools: the daily workflow, the run-your-own-tournament selection pattern,
the exit lab, and the data contract / leakage rules. Fetch one with
`get_playbook(name)`.
Returns:
List of {name, title, summary}.
get_playbook
Fetch one methodology playbook (markdown) by name.
Start with `start-here`. Use `list_playbooks` to see everything published.
Playbooks are living documents — re-fetch rather than caching long-term;
the `changelog` playbook records dated methodology/data changes.
Args:
name: Playbook name as returned by `list_playbooks` (e.g. "start-here",
"daily-workflow", "run-your-own-tournament", "exit-lab",
"leakage-and-data-contract", "changelog").
Returns:
{name, title, content} — content is markdown.
get_signal_performance
UNDERLYING-STOCK directional outcomes for the broad enriched pool — did
the direction call work on the stock over the 3-day forward window?
This is NOT option PnL. On the same pool, the underlying moving the right
way (~54%) does not mean the option made money (~41%) — theta, IV and the
exit bracket eat the difference. For realized OPTION trades use
`get_position_history`; for the full-pool option labels use
`query_outcomes`.
Args:
scan_date: Filter by date (YYYY-MM-DD).
ticker: Filter to specific ticker.
direction: "bull" or "bear".
outcome: "win" or "loss" to filter.
limit: Max results (default 50).
Returns:
{universe, basis, note, rows: [{ticker, direction, score, entry_price,
current_price, underlying_pct_change, underlying_direction_outcome,
scan_date}]} — field names carry the universe on purpose.
get_win_rate_summary
Aggregate UNDERLYING-STOCK direction statistics for the broad enriched
pool over a lookback window.
This win rate answers "how often was the direction call right on the
STOCK" — it is NOT an option-PnL win rate and NOT the paper-trading track
record. For those use `get_historical_performance` (realized option
trades) or `get_outcome_summary` (full-pool option labels).
There is deliberately NO bare `win_rate` field in the response: the
headline is `underlying_direction_win_rate` (and bull_/bear_ variants),
so the number cannot be quoted without its universe.
Args:
days: Lookback period in days (default 30).
Returns:
Summary statistics object with universe/basis markers;
underlying_direction_win_rate is the headline metric.
get_position_history
The RECEIPTS — realized (closed) paper trades from the engine's own daily
selection, row-level. One tournament pick per day, simulated with real
fills under the bracket policy live at the time.
Realized-only by construction: rows appear only after the trade's exit,
never same-day, so this tool cannot front-run the engine's private
selection. No-trade days are reported separately in `skip_days` (they are
part of the honest track record); invalid-liquidity rows are excluded.
Live policy (`V7_1_TILTED_GIGO`, cohort since 2026-06-26): enter 10:00 ET
the day after scan, +40% target / -30% stop, flat 15:45 ET same day.
Earlier policy_version cohorts used different exits — do not mix cohorts
when computing aggregates.
Args:
days: Lookback window in days (default 30, clamped 1-365).
limit: Max rows (default 50, clamped 1-200).
policy_version: Cohort filter (default = the live cohort). Pass "all"
to see every era — comparison across eras is on you.
Returns:
{policy_version, row_count, rows: [{scan_date, ticker, direction,
recommended_contract, entry/target/stop prices, realized_return_pct,
exit_reason, benchmarks, timestamps, policy_version}]}
get_historical_performance
Aggregate realized paper-trading performance (the engine's RECEIPTS) over
a lookback window — one tournament pick per day, real-fill simulation.
Defaults to the LIVE cohort (`V7_1_TILTED_GIGO`, since 2026-06-26: enter
10:00 ET day after scan, +40% target / -30% stop, flat 15:45 ET same day).
The cohort is young — expect small N; small-N aggregates are noise-heavy
and should be quoted with their N. Pass policy_version="all" to see all
eras (different exit mechanics — comparison is on you).
Realized-only: rows appear after exit, never same-day. All returns are
FRACTIONS of entry premium (0.40 = +40%). Paper-traded. Not investment
advice.
Args:
lookback_days: Lookback window in calendar days (default 30, clamped 1-365).
direction: Optional filter — "bullish" or "bearish" (case-insensitive).
min_premium_score: Optional integer floor on premium_score (0-6 typical).
policy_version: Cohort filter (default = live cohort; "all" for every era).
Returns:
{
"total_trades": int,
"wins": int, # realized_return_pct > 0
"losses": int, # realized_return_pct <= 0
"win_rate": float, # 0.0-1.0
"avg_return": float, # mean of realized_return_pct (FRACTION)
"median_return": float,
"best": float,
"worst": float,
"period": str,
"filters": {direction, min_premium_score, lookback_days, policy_version},
}
get_daily_report
Returns the full daily intelligence report.
Args:
date: Filter by date (YYYY-MM-DD). Defaults to most recent.
Returns:
Full report with title, content (markdown), created_at, scan_date.
get_report_list
List available reports, most recent first. Repeated titles across dates
are deduplicated (the generator occasionally reuses a headline) — each
title appears once, at its most recent scan_date.
Args:
limit: Number of reports to return (default 10).
Returns:
List of {scan_date, title, created_at}.
get_available_dates
Returns which scan dates have data available.
Returns:
List of {scan_date, signal_count}
get_enriched_signal_schema
RESEARCH / POWER-USER tool. If you just need what a field MEANS,
`get_signal_explainer` is the everyday path — this is the formal contract
for grounding research code.
The substrate DATA CONTRACT, machine-readable: every column of the
outcome/label substrate with its leakage classification and as-of
boundary, plus the exact column set exposed by the point-in-time features
view (what `get_pool_features` serves).
Classifications: identity | feature | label | opportunity |
regime_telemetry. Only `feature` columns are safe as selection inputs —
everything else is realized after the selection point. Use this tool to
ground research code instead of hallucinating field names, and see
get_playbook("leakage-and-data-contract") for the rules in prose.
Returns:
{vocabulary, features_view_columns: [...],
columns: [{column, data_type, classification, as_of, description}]}
get_market_calendar_status
Returns whether the US equity market is open today + the next open/close.
Uses pandas_market_calendars (NYSE) so it knows about holidays + early
closes deterministically — eliminates the chat-agent "is the market
open?" hallucination class.
Returns:
{
"is_open_today": bool,
"current_date": "YYYY-MM-DD" (Eastern),
"current_time_et": "ISO8601" (Eastern),
"next_open": "ISO8601" (Eastern, schedule open boundary),
"next_close": "ISO8601" (Eastern, schedule close boundary),
"is_holiday": bool,
"holiday_name": str | None,
"is_early_close": bool,
}
get_signal_explainer
Return a plain-English definition + role of a GammaRips signal field.
Deterministic lookup table — no LLM, no hallucination. Use this for the
"what does X mean?" pattern when a chat user asks about a metric we
surfaced. If the field isn't in our dictionary, returns an "unknown" row
rather than guessing.
Args:
field_name: Field name as it appears in tool responses (e.g.,
"premium_score", "volume_oi_ratio", "recommended_contract").
Returns:
{field_name, label, definition, how_used, available_fields}
— `available_fields` is the full list of supported field names so the
agent can offer alternatives if the input was misspelled.
web_search
Performs a Google Web Search using the Custom Search JSON API via direct HTTP requests.
Useful for finding real-time information, news, or verifying facts (grounding).
Args:
query: The search query string.
num_results: Number of results to return (default 5, max 10).
Returns:
A formatted string containing the top search results (Title, Snippet, Link).