diff --git a/README.md b/README.md index 1f169dc..2f08ed7 100644 --- a/README.md +++ b/README.md @@ -208,9 +208,15 @@ Accept: application/json | `expiry_agg` | boolean | Aggregate by expiry | | `skew_adj` | boolean | Apply skew adjustment | | `limit_y` | boolean | Limit y-axis range | +| `series` | string | Term-view series grouping: `moneyness`, `strikes`, `deltas` | | `contract_filter` | string | Filter contracts: `calls`, `puts`, `all` | | `moneyness_filter` | string | Filter by moneyness: `atm`, `itm`, `ntm`, `otm` | +Not every parameter applies to every request — applicability depends on the selected `metric` and `view`, and +inapplicable parameters are silently ignored. See +[docs/research-parameter-applicability.md](docs/research-parameter-applicability.md) for the full applicability +matrix and the `x-applicable_views` / `x-chart_only` / `x-dedicated_metrics` spec extensions. + ### subscription tiers Subscriptions are available for different data packages at https://www.gexbot.com/: diff --git a/docs/research-parameter-applicability.md b/docs/research-parameter-applicability.md new file mode 100644 index 0000000..4d7bf57 --- /dev/null +++ b/docs/research-parameter-applicability.md @@ -0,0 +1,80 @@ +# research parameter applicability + +The `GET /research/{ticker}/{metric}` endpoint accepts a flat list of optional query parameters, but not every +parameter applies to every request. This document defines the OpenAPI extensions used to encode those rules in +[`latest/gexbot.spec3.yaml`](../latest/gexbot.spec3.yaml) and provides the full applicability matrix, so clients +(such as interactive URL builders) can disable inapplicable controls up front. + +## request routing + +Requests are routed in two steps: + +1. **Dedicated metrics** — a small set of metric values always render a fixed chart. The `view` parameter and all + view-scoped parameters are ignored. +2. **Views** — every other metric renders one of three views selected by the `view` parameter: `skew` (the + default), `term`, or `surface`. + +Inapplicable or invalid optional query parameters are **silently ignored** and server defaults are applied; they +do not cause a `400` response. A request that mixes inapplicable parameters still succeeds — the extra parameters +simply have no effect. + +## extensions + +### `x-applicable_views` (parameter level) + +An allowlist of the views in which the query parameter takes effect. When omitted, the parameter applies to all +views. Example: + +```yaml +- name: strikes + in: query + x-applicable_views: [skew] +``` + +Clients should disable the control when the effective view (the `view` parameter, or `skew` when unset) is not in +the list, or when the selected metric is a dedicated metric that does not support the parameter. + +### `x-chart_only` (parameter level) + +`true` when the parameter only affects rendered charts. It has no effect when `format` is `json` or `csv`. + +### `x-dedicated_metrics` (operation level) + +Maps each dedicated metric value to the query parameters it supports (`supported_parameters`). All other query +parameters — including `view` — are ignored for these metrics. + +## applicability matrix + +Views apply to all non-dedicated metrics. ✓ means the parameter takes effect; ✗ means it is ignored. + +| parameter | skew | term | surface | max_pain | parity / put_call_parity | gamma_flip | chart only | +|---------------------|:----:|:----:|:-------:|:--------:|:------------------------:|:----------:|:----------:| +| `format` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | +| `theme` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| `start_dte` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | +| `end_dte` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | +| `expiration_filter` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | +| `view` | — | — | — | ✗ | ✗ | ✗ | | +| `type` | ✓ | ✓ | ✗ | ✗ | ✗ | ✗ | ✓ | +| `strikes` | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | | +| `series` | ✗ | ✓ | ✗ | ✗ | ✗ | ✗ | ✓ | +| `contract_filter` | ✓ | ✓ | ✓ | ✗ | ✓ | ✗ | | +| `moneyness_filter` | ✓ | ✓ | ✓ | ✗ | ✓ | ✗ | | +| `contract_agg` | ✓ | ✓ | ✗ | ✗ | ✗ | ✗ | | +| `expiry_agg` | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | | +| `skew_adj` | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ | +| `limit_y` | ✗ | ✓ | ✗ | ✗ | ✗ | ✗ | ✓ | + +Notes: + +- `view` selects the view for non-dedicated metrics (`—`) and is ignored by dedicated metrics. +- "chart only" parameters are ignored when `format` is `json` or `csv`, regardless of view. +- Defaults may vary by metric (for example, the default `type` and the default `strikes` count depend on the + metric, and implied-volatility metrics default `moneyness_filter` to `ntm`). The spec documents the common + defaults. + +## maintenance + +These extensions describe server routing behavior and must be updated together with the API implementation +whenever parameter handling changes. The YAML spec is the source of truth; regenerate the JSON spec after any +change. diff --git a/latest/gexbot.spec3.json b/latest/gexbot.spec3.json index a967826..8ac12bf 100644 --- a/latest/gexbot.spec3.json +++ b/latest/gexbot.spec3.json @@ -130,7 +130,7 @@ "$ref": "#/components/parameters/ticker_in_path" }, { - "$ref": "#/components/schemas/category_orderflow" + "$ref": "#/components/parameters/orderflow_category_in_path" }, { "$ref": "#/components/parameters/user_agent_header" @@ -713,7 +713,7 @@ "/research/{ticker}/{metric}": { "get": { "summary": "Get research chart data for a ticker and metric", - "description": "Returns research chart data for the specified ticker and metric. Supports various output formats, chart types, and filtering options.", + "description": "Returns research chart data for the specified ticker and metric. Supports various output formats, chart views, and filtering options.\n\nNot every query parameter applies to every request. Requests are routed first by `metric`, then by `view`:\na small set of dedicated metrics (listed in `x-dedicated_metrics` below) always render a fixed chart and\nignore `view` and all view-scoped parameters, while every other metric renders the `skew` (default),\n`term`, or `surface` view. View-scoped query parameters are annotated with `x-applicable_views`\n(omitted means the parameter applies to all views), and parameters that only affect rendered charts —\nignored when `format` is `json` or `csv` — are annotated with `x-chart_only`.\n\nInapplicable or invalid optional query parameters are silently ignored and server defaults are applied;\nthey do not cause a `400` response. See `docs/research-parameter-applicability.md` for the full\napplicability matrix and extension semantics.\n", "security": [ { "bearer_auth": [] @@ -722,6 +722,51 @@ "tags": [ "Research" ], + "x-dedicated_metrics": { + "description": "Requests for these metric values always render a fixed, dedicated chart. The `view` parameter and all view-scoped query parameters are ignored; only the listed query parameters take effect.", + "metrics": { + "max_pain": { + "supported_parameters": [ + "format", + "theme", + "start_dte", + "end_dte", + "expiration_filter" + ] + }, + "parity": { + "supported_parameters": [ + "format", + "theme", + "start_dte", + "end_dte", + "expiration_filter", + "contract_filter", + "moneyness_filter" + ] + }, + "put_call_parity": { + "supported_parameters": [ + "format", + "theme", + "start_dte", + "end_dte", + "expiration_filter", + "contract_filter", + "moneyness_filter" + ] + }, + "gamma_flip": { + "supported_parameters": [ + "format", + "theme", + "start_dte", + "end_dte", + "expiration_filter" + ] + } + } + }, "parameters": [ { "$ref": "#/components/parameters/research_ticker_in_path" @@ -744,8 +789,10 @@ "name": "format", "in": "query", "required": false, + "description": "Output format. Chart formats return a rendered chart; `json` and `csv` return structured data and ignore chart-only parameters (see `x-chart_only`). Defaults to `svg`.", "schema": { "type": "string", + "default": "svg", "enum": [ "png", "jpeg", @@ -761,8 +808,10 @@ "name": "view", "in": "query", "required": false, + "description": "Chart view. Defaults to `skew`. Ignored for dedicated metrics (see `x-dedicated_metrics`).", "schema": { "type": "string", + "default": "skew", "enum": [ "skew", "term", @@ -774,6 +823,12 @@ "name": "type", "in": "query", "required": false, + "description": "Chart draw type. Applies to the skew and term views; the default depends on the metric.", + "x-applicable_views": [ + "skew", + "term" + ], + "x-chart_only": true, "schema": { "type": "string", "enum": [ @@ -789,6 +844,7 @@ "in": "query", "required": false, "description": "Chart color theme. Defaults to dark.", + "x-chart_only": true, "schema": { "type": "string", "default": "dark", @@ -802,14 +858,21 @@ "name": "strikes", "in": "query", "required": false, + "description": "Maximum number of strikes to include. Applies to the skew view only. Values are clamped to the range 5-250.", + "x-applicable_views": [ + "skew" + ], "schema": { - "type": "number" + "type": "number", + "minimum": 5, + "maximum": 250 } }, { "name": "start_dte", "in": "query", "required": false, + "description": "Start of the days-to-expiration window.", "schema": { "type": "number" } @@ -818,6 +881,7 @@ "name": "end_dte", "in": "query", "required": false, + "description": "End of the days-to-expiration window.", "schema": { "type": "number" } @@ -826,6 +890,7 @@ "name": "expiration_filter", "in": "query", "required": false, + "description": "Expiration date filter: `m` (monthly), `w` (weekly), or `q` (quarterly).", "schema": { "type": "string" } @@ -834,40 +899,83 @@ "name": "contract_agg", "in": "query", "required": false, + "description": "Aggregate calls and puts together. Applies to the skew and term views. Defaults to true.", + "x-applicable_views": [ + "skew", + "term" + ], "schema": { - "type": "boolean" + "type": "boolean", + "default": true } }, { "name": "expiry_agg", "in": "query", "required": false, + "description": "Aggregate across expirations. Applies to the skew view only. Defaults to false.", + "x-applicable_views": [ + "skew" + ], "schema": { - "type": "boolean" + "type": "boolean", + "default": false } }, { "name": "skew_adj", "in": "query", "required": false, + "description": "Apply skew adjustment to the rendered chart. Applies to the skew view only. Defaults to false.", + "x-applicable_views": [ + "skew" + ], + "x-chart_only": true, "schema": { - "type": "boolean" + "type": "boolean", + "default": false } }, { "name": "limit_y", "in": "query", "required": false, + "description": "Limit the y-axis range of the rendered chart. Applies to the term view only. Defaults to true.", + "x-applicable_views": [ + "term" + ], + "x-chart_only": true, + "schema": { + "type": "boolean", + "default": true + } + }, + { + "name": "series", + "in": "query", + "required": false, + "description": "Group term-structure results into separate series lines. Applies to the term view only; omit for a single aggregated series.", + "x-applicable_views": [ + "term" + ], + "x-chart_only": true, "schema": { - "type": "boolean" + "type": "string", + "enum": [ + "moneyness", + "strikes", + "deltas" + ] } }, { "name": "contract_filter", "in": "query", "required": false, + "description": "Filter by contract type. Applies to all views. Defaults to `all`.", "schema": { "type": "string", + "default": "all", "enum": [ "calls", "puts", @@ -879,6 +987,7 @@ "name": "moneyness_filter", "in": "query", "required": false, + "description": "Filter by moneyness. Applies to all views; omit for no moneyness filtering (implied-volatility metrics default to `ntm`).", "schema": { "type": "string", "enum": [ @@ -1013,7 +1122,7 @@ "group": "ES_SPX_orderflow_orderflow" }, { - "hub": "state_greeks_zero", + "hub": "state_greeks", "group": "SOXL_state_gamma_20260717" } ] @@ -2322,6 +2431,14 @@ ] } }, + "orderflow_category_in_path": { + "name": "category", + "in": "path", + "required": true, + "schema": { + "$ref": "#/components/schemas/category_orderflow" + } + }, "package_in_path": { "name": "package", "in": "path", diff --git a/latest/gexbot.spec3.yaml b/latest/gexbot.spec3.yaml index f4fe123..c4168e6 100644 --- a/latest/gexbot.spec3.yaml +++ b/latest/gexbot.spec3.yaml @@ -73,7 +73,7 @@ paths: - bearer_auth: [ ] parameters: - $ref: "#/components/parameters/ticker_in_path" - - $ref: "#/components/schemas/category_orderflow" + - $ref: "#/components/parameters/orderflow_category_in_path" - $ref: "#/components/parameters/user_agent_header" - $ref: "#/components/parameters/accept_header" responses: @@ -417,11 +417,36 @@ paths: /research/{ticker}/{metric}: get: summary: Get research chart data for a ticker and metric - description: Returns research chart data for the specified ticker and metric. Supports various output formats, chart types, and filtering options. + description: | + Returns research chart data for the specified ticker and metric. Supports various output formats, chart views, and filtering options. + + Not every query parameter applies to every request. Requests are routed first by `metric`, then by `view`: + a small set of dedicated metrics (listed in `x-dedicated_metrics` below) always render a fixed chart and + ignore `view` and all view-scoped parameters, while every other metric renders the `skew` (default), + `term`, or `surface` view. View-scoped query parameters are annotated with `x-applicable_views` + (omitted means the parameter applies to all views), and parameters that only affect rendered charts — + ignored when `format` is `json` or `csv` — are annotated with `x-chart_only`. + + Inapplicable or invalid optional query parameters are silently ignored and server defaults are applied; + they do not cause a `400` response. See `docs/research-parameter-applicability.md` for the full + applicability matrix and extension semantics. security: - bearer_auth: [ ] tags: - Research + x-dedicated_metrics: + description: >- + Requests for these metric values always render a fixed, dedicated chart. The `view` parameter and all + view-scoped query parameters are ignored; only the listed query parameters take effect. + metrics: + max_pain: + supported_parameters: [format, theme, start_dte, end_dte, expiration_filter] + parity: + supported_parameters: [format, theme, start_dte, end_dte, expiration_filter, contract_filter, moneyness_filter] + put_call_parity: + supported_parameters: [format, theme, start_dte, end_dte, expiration_filter, contract_filter, moneyness_filter] + gamma_flip: + supported_parameters: [format, theme, start_dte, end_dte, expiration_filter] parameters: - $ref: "#/components/parameters/research_ticker_in_path" - name: metric @@ -434,8 +459,12 @@ paths: - name: format in: query required: false + description: >- + Output format. Chart formats return a rendered chart; `json` and `csv` return structured data and + ignore chart-only parameters (see `x-chart_only`). Defaults to `svg`. schema: type: string + default: svg enum: - png - jpeg @@ -447,8 +476,11 @@ paths: - name: view in: query required: false + description: >- + Chart view. Defaults to `skew`. Ignored for dedicated metrics (see `x-dedicated_metrics`). schema: type: string + default: skew enum: - skew - term @@ -456,6 +488,10 @@ paths: - name: type in: query required: false + description: >- + Chart draw type. Applies to the skew and term views; the default depends on the metric. + x-applicable_views: [skew, term] + x-chart_only: true schema: type: string enum: @@ -467,6 +503,7 @@ paths: in: query required: false description: Chart color theme. Defaults to dark. + x-chart_only: true schema: type: string default: dark @@ -476,48 +513,91 @@ paths: - name: strikes in: query required: false + description: >- + Maximum number of strikes to include. Applies to the skew view only. Values are clamped to the + range 5-250. + x-applicable_views: [skew] schema: type: number + minimum: 5 + maximum: 250 - name: start_dte in: query required: false + description: Start of the days-to-expiration window. schema: type: number - name: end_dte in: query required: false + description: End of the days-to-expiration window. schema: type: number - name: expiration_filter in: query required: false + description: "Expiration date filter: `m` (monthly), `w` (weekly), or `q` (quarterly)." schema: type: string - name: contract_agg in: query required: false + description: >- + Aggregate calls and puts together. Applies to the skew and term views. Defaults to true. + x-applicable_views: [skew, term] schema: type: boolean + default: true - name: expiry_agg in: query required: false + description: >- + Aggregate across expirations. Applies to the skew view only. Defaults to false. + x-applicable_views: [skew] schema: type: boolean + default: false - name: skew_adj in: query required: false + description: >- + Apply skew adjustment to the rendered chart. Applies to the skew view only. Defaults to false. + x-applicable_views: [skew] + x-chart_only: true schema: type: boolean + default: false - name: limit_y in: query required: false + description: >- + Limit the y-axis range of the rendered chart. Applies to the term view only. Defaults to true. + x-applicable_views: [term] + x-chart_only: true schema: type: boolean + default: true + - name: series + in: query + required: false + description: >- + Group term-structure results into separate series lines. Applies to the term view only; omit for a + single aggregated series. + x-applicable_views: [term] + x-chart_only: true + schema: + type: string + enum: + - moneyness + - strikes + - deltas - name: contract_filter in: query required: false + description: Filter by contract type. Applies to all views. Defaults to `all`. schema: type: string + default: all enum: - calls - puts @@ -525,6 +605,9 @@ paths: - name: moneyness_filter in: query required: false + description: >- + Filter by moneyness. Applies to all views; omit for no moneyness filtering (implied-volatility + metrics default to `ntm`). schema: type: string enum: @@ -1608,6 +1691,12 @@ components: oneOf: - $ref: "#/components/schemas/category_classic" - $ref: "#/components/schemas/category_state" + orderflow_category_in_path: + name: category + in: path + required: true + schema: + $ref: "#/components/schemas/category_orderflow" package_in_path: name: package in: path