> ## Documentation Index
> Fetch the complete documentation index at: https://docs.backquant.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Greek trace - forward (time × price) projection

> Black-Scholes forward projection of dealer **gamma**, **charm**, or **vanna** across a (time × price) grid, holding today's chain constant and decaying τ toward each contract's expiry.

Returns a 2D `field` of cell values, the `time_axis_ms` and `price_axis` it's keyed on, and the contracts it consumed. Intended for desk-grade dealer-positioning visualisations (the BackQuant Pro Terminal's TRACE panel runs the same math client-side).

**Sign convention:** +1 for calls, −1 for puts — positive cell = call book dominates the put book at that (time, price).

**Units:**
* `gamma` → `$ per 1% spot move` (γ × S² × OI × 0.01).
* `charm` → 1/year (∂Δ/∂τ × OI).
* `vanna` → per IV unit (∂Δ/∂σ × OI).

**Performance:** the field is computed on cache miss in ~50–100 ms for typical grids. Cached for 30 s per `(symbol, full-param-hash)` so identical repeated calls are essentially free.

**What-if vol shifts:** `vol_shift_pct` multiplies every contract's σ by `1 + vol_shift_pct/100` before evaluation. Lets you build vol-up / vol-down surfaces without re-fetching.

Forward Black-Scholes projection of dealer **gamma**, **charm**, or **vanna** across a `(time × price)` grid - the same view that powers BackQuant Pro's TRACE panel, exposed as raw data for your own renderer.

Holding today's chain constant, the endpoint walks each point on the grid (a future timestamp + a future spot price), recomputes per-contract τ and the requested greek under those conditions, sums across the chain weighted by per-contract OI, and returns the resulting field.

## Why use it

A single point-in-time greek profile only tells you what dealer exposure looks like *now*. Trace tells you what it'll look like **as time and price evolve** - where gamma walls develop, decay, or migrate as τ runs to zero. It's the difference between a snapshot and a forward map.

Common uses:

* **Intraday flow planning** - `greek=gamma&expiry=0dte` shows where 0DTE dealer hedging will concentrate as the session progresses.
* **Charm bleed** - `greek=charm` exposes the passive delta drift dealers will accumulate from time alone, even with spot frozen.
* **Vol-shock surfaces** - `vol_shift_pct=±10` builds an instant what-if view for vol up / down without a re-fetch.
* **Multi-day overlays** - `expiry=all&horizon_hours=168` projects across the next week's term structure.

## Sign convention

`+1` for calls, `−1` for puts. A **positive** cell value means the call book dominates the put book at that `(time, price)` - supportive flow. A **negative** cell means the reverse. Identical to the rest of the BackQuant stack so cross-references between TRACE and the per-strike profiles are coherent.

## Units

| `greek` | Unit                | Formula per cell              |
| ------- | ------------------- | ----------------------------- |
| `gamma` | \$ per 1% spot move | `Σ sign × γ × S² × OI × 0.01` |
| `charm` | per year            | `Σ sign × ∂Δ/∂τ × OI`         |
| `vanna` | per IV unit         | `Σ sign × ∂Δ/∂σ × OI`         |

`field_units` is echoed on every response so renderers don't need to hardcode this.

## Cells, axes, and shape

The response body is rectangular:

```
field[t][p]   ← cell value at time_axis_ms[t], price_axis[p]
```

`time_axis_ms` runs from "now" to `now + horizon_hours`. `price_axis` runs from `spot × (1 − range/100)` to `spot × (1 + range/100)`. Both are evenly spaced.

`abs_field_max = max(|field_min|, |field_max|)` is included to make symmetric colour scales trivial: `value / abs_field_max` clamped to `[−1, +1]` is the standard input for diverging palettes.

## What-if vol shifts

`vol_shift_pct` adds a flat percent shift to every contract's IV - e.g. `vol_shift_pct=5` multiplies each σ by `1.05` before evaluation. Use it to build vol-up / vol-down surfaces in two requests instead of waiting for an actual vol move.

## Performance

Cached for **30 seconds** per `(symbol, full-param-hash)`. Identical repeated calls are essentially free; varying any parameter (greek, expiry, grid resolution, vol shift, OI threshold) creates a fresh cache entry. Cold compute is typically **50–100 ms** for default grid sizes; payload runs **30–80 KB** of JSON.

## Caps

| Param             | Min | Max | Default |
| ----------------- | --- | --- | ------- |
| `time_steps`      | 2   | 200 | 60      |
| `price_steps`     | 2   | 200 | 80      |
| `price_range_pct` | >0  | 50  | 8       |
| `horizon_hours`   | >0  | 720 | 24      |
| `vol_shift_pct`   | −50 | +50 | 0       |
| `min_oi`          | 0   | -   | 0       |

Going past the caps returns a `VALIDATION_ERROR` with a 422.

## See also

<CardGroup cols={2}>
  <Card title="Greeks beyond delta" href="/concepts/greeks" icon="bookmark" />

  <Card title="Greek profile" href="/api/v2/options/greeks/by-greek" icon="bookmark" />

  <Card title="Greek surfaces" href="/api/v2/options/greeks/surfaces" icon="bookmark" />

  <Card title="3D greek surface" href="/api/v2/options/greeks/3d-surface" icon="bookmark" />
</CardGroup>


## OpenAPI

````yaml GET /options/greeks/trace/{greek}
openapi: 3.1.0
info:
  title: BackQuant API v2
  description: >-

    # BackQuant API v2


    Options + gamma-exposure focused public API. Built on the same data the

    BackQuant Pro Terminal renders — pre-computed every 30s, served from cache.


    ## What's in v2


    * **Discovery**: `/v2/symbols` (universe + per-symbol freshness + supported
      endpoint list), `/v2/expiries` (active expiry tokens with DTE), `/v2/status`
      (per-symbol-per-category health with thresholds + overall classification).
    * **GEX**: composable levels (HVL / call wall / put support / max-pain /
      expected move / gamma-flip zones), strike profile with typed expiry
      filter, expiry profile, strike × expiry heatmap with downsampling,
      greek time-heatmap with DTE/OI/IV filters, history (cursor-paginated),
      Postgres-backed stress history, **per-expiry max-pain with pain curve**.
    * **Options**: filtered options chain with two-layer projection (top-level
      `?fields=` and per-contract `?include=oi,iv,greeks,bid_ask,volume,gex`)
      plus moneyness filter (`?moneyness_min=0.9&moneyness_max=1.1`), expiry
      summary table, full IV suite (surface / term structure / 25Δ-10Δ skew /
      curves / **single-expiry smile** / IV-RV history / VRP), expected move,
      **Breeden-Litzenberger probability density and surface**, typed greek
      profiles (delta / theta / vanna / charm / vega), strike × time charm/vega
      surfaces, strike × expiry 3D greek surface, OI by expiry + history,
      put/call ratio (intraday or daily), 0DTE & weekly premium tide,
      dated-futures term structure.
    * **Liquidation**: heatmap + leverage-tiered distribution.

    * **Multi**: `/v2/multi/gex/levels` — bundled multi-symbol read across the
      universe in one round-trip, with the same `?include=` model as the
      single-symbol endpoint.

    ## Authentication


    Every v2 route (except `/v2/openapi.json`, `/v2/docs`, `/v2/redoc`, and

    `/v2/health`) requires the `X-API-Key` header.


    ```

    X-API-Key: bq_live_your_api_key_here

    ```


    **Get your API key at
    [backquant.com/api-access](https://backquant.com/api-access).**


    The same key works across v1 and v2 — if you already have a v1 key, no

    re-issuance is needed.


    ## Rate limits


    Per-key, derived from your subscription tier:


    | Tier        | Limit                |

    |-------------|----------------------|

    | Monthly     | 60 requests/min      |

    | Yearly      | 120 requests/min     |

    | Enterprise  | No limit             |


    Headers `X-RateLimit-Limit / -Remaining / -Reset` are included in every

    response, and the same triple is echoed inside `meta.rate_limit` when

    populated by middleware.


    ## Response envelope


    ```json

    {
      "success": true,
      "data": { ... },
      "meta": {
        "version": "2.0",
        "timestamp": "2026-04-29T12:00:00.000Z",
        "request_id": "req_…",
        "symbol": "BTCUSDT",
        "spot_price": 67213.5,
        "computed_at": "2026-04-29T11:59:48.000Z",
        "freshness_seconds": 12.0,
        "source": ["deribit","bybit","okx","binance"],
        "exchanges_filtered": ["deribit","bybit"]
      }
    }

    ```


    ## Errors


    ```json

    {
      "success": false,
      "error": {
        "code": "NOT_FOUND",
        "message": "No data for BTCUSDT"
      },
      "meta": { "version": "2.0", "timestamp": "..." }
    }

    ```


    | Code                  | When |

    |-----------------------|------|

    | `UNAUTHORIZED`        | Missing or invalid API key |

    | `FORBIDDEN`           | Subscription doesn't allow API access |

    | `NOT_FOUND`           | Symbol/expiry/etc. not present in cache |

    | `VALIDATION_ERROR`    | Bad query parameters |

    | `RATE_LIMIT_EXCEEDED` | Per-tier limit hit |

    | `UPSTREAM_ERROR`      | Cache or DB temporarily unreachable |

    | `INTERNAL_ERROR`      | Anything else |
        
  version: 2.0.0
servers: []
security: []
tags:
  - name: Meta
    description: Unauthenticated metadata + endpoint catalog (planning your integration)
  - name: Discovery
    description: Symbol catalog, active expiries, and service status
  - name: GEX
    description: Gamma exposure analytics
  - name: Options
    description: Options chain, IV, greeks, probability, premium tide
  - name: Liquidation
    description: Liquidation heatmap and distribution
  - name: Multi
    description: Bundled multi-symbol endpoints (single round-trip across the universe)
paths:
  /options/greeks/trace/{greek}:
    get:
      tags:
        - Options
      summary: Forward (time × price) greek projection — gamma / charm / vanna
      description: >-
        Black-Scholes forward projection of dealer **gamma**, **charm**, or
        **vanna** across a (time × price) grid, holding today's chain constant
        and decaying τ toward each contract's expiry.


        Returns a 2D `field` of cell values, the `time_axis_ms` and `price_axis`
        it's keyed on, and the contracts it consumed. Intended for desk-grade
        dealer-positioning visualisations (the BackQuant Pro Terminal's TRACE
        panel runs the same math client-side).


        **Sign convention:** +1 for calls, −1 for puts — positive cell = call
        book dominates the put book at that (time, price).


        **Units:**

        * `gamma` → `$ per 1% spot move` (γ × S² × OI × 0.01).

        * `charm` → 1/year (∂Δ/∂τ × OI).

        * `vanna` → per IV unit (∂Δ/∂σ × OI).


        **Performance:** the field is computed on cache miss in ~50–100 ms for
        typical grids. Cached for 30 s per `(symbol, full-param-hash)` so
        identical repeated calls are essentially free.


        **What-if vol shifts:** `vol_shift_pct` multiplies every contract's σ by
        `1 + vol_shift_pct/100` before evaluation. Lets you build vol-up /
        vol-down surfaces without re-fetching.
      operationId: get_greek_trace_options_greeks_trace__greek__get
      parameters:
        - name: greek
          in: path
          required: true
          schema:
            enum:
              - gamma
              - charm
              - vanna
            type: string
            description: Which greek to project.
            title: Greek
          description: Which greek to project.
        - name: symbol
          in: query
          required: false
          schema:
            enum:
              - BTCUSDT
              - ETHUSDT
              - SOLUSDT
              - HYPEUSDT
            type: string
            description: 'Trading symbol: BTCUSDT, ETHUSDT, SOLUSDT, or HYPEUSDT.'
            default: BTCUSDT
            title: Symbol
          description: 'Trading symbol: BTCUSDT, ETHUSDT, SOLUSDT, or HYPEUSDT.'
        - name: expiry
          in: query
          required: false
          schema:
            type: string
            description: >-
              Expiry filter. `0dte` = today's UTC expiries only (the standard
              intraday read), `all` = every active expiry, or a specific Deribit
              token (e.g. `28MAR25`).
            default: 0dte
            title: Expiry
          description: >-
            Expiry filter. `0dte` = today's UTC expiries only (the standard
            intraday read), `all` = every active expiry, or a specific Deribit
            token (e.g. `28MAR25`).
        - name: time_steps
          in: query
          required: false
          schema:
            type: integer
            maximum: 200
            minimum: 2
            description: >-
              Number of buckets along the time axis. Higher = smoother surface,
              larger payload. Capped at 200.
            default: 60
            title: Time Steps
          description: >-
            Number of buckets along the time axis. Higher = smoother surface,
            larger payload. Capped at 200.
        - name: price_steps
          in: query
          required: false
          schema:
            type: integer
            maximum: 200
            minimum: 2
            description: >-
              Number of buckets along the price axis. Higher = smoother, larger
              payload. Capped at 200.
            default: 80
            title: Price Steps
          description: >-
            Number of buckets along the price axis. Higher = smoother, larger
            payload. Capped at 200.
        - name: price_range_pct
          in: query
          required: false
          schema:
            type: number
            maximum: 50
            exclusiveMinimum: 0
            description: >-
              Price half-width as a percent of spot. Default 8 = ±8% around
              spot. Capped at ±50% — wider than that and BS gamma at the wings
              is essentially zero anyway.
            default: 8
            title: Price Range Pct
          description: >-
            Price half-width as a percent of spot. Default 8 = ±8% around spot.
            Capped at ±50% — wider than that and BS gamma at the wings is
            essentially zero anyway.
        - name: horizon_hours
          in: query
          required: false
          schema:
            type: number
            maximum: 720
            exclusiveMinimum: 0
            description: >-
              Time horizon in hours from now. Default 24 = one trading day. Use
              longer horizons for multi-week trace overlays — capped at 720 h
              (30 days).
            default: 24
            title: Horizon Hours
          description: >-
            Time horizon in hours from now. Default 24 = one trading day. Use
            longer horizons for multi-week trace overlays — capped at 720 h (30
            days).
        - name: vol_shift_pct
          in: query
          required: false
          schema:
            type: number
            maximum: 50
            minimum: -50
            description: >-
              What-if shift applied to every contract's IV (additive percent of
              σ — `+5` ⇒ multiply σ by 1.05). Use to build vol-up / vol-down
              surfaces without re-fetching.
            default: 0
            title: Vol Shift Pct
          description: >-
            What-if shift applied to every contract's IV (additive percent of σ
            — `+5` ⇒ multiply σ by 1.05). Use to build vol-up / vol-down
            surfaces without re-fetching.
        - name: min_oi
          in: query
          required: false
          schema:
            type: number
            minimum: 0
            description: >-
              Drop contracts with OI below this threshold before summing. Useful
              for de-noising the wings.
            default: 0
            title: Min Oi
          description: >-
            Drop contracts with OI below this threshold before summing. Useful
            for de-noising the wings.
        - name: X-API-Key
          in: header
          required: false
          schema:
            anyOf:
              - type: string
              - type: 'null'
            title: X-Api-Key
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TraceResponse'
        '401':
          description: Invalid or missing API key
          content:
            application/json:
              example:
                success: false
                error:
                  code: UNAUTHORIZED
                  message: Invalid API key
                meta:
                  version: '2.0'
                  timestamp: '2026-04-29T12:00:00Z'
        '404':
          description: No data available for the requested resource
          content:
            application/json:
              example:
                success: false
                error:
                  code: NOT_FOUND
                  message: No data for BTCUSDT
                meta:
                  version: '2.0'
                  timestamp: '2026-04-29T12:00:00Z'
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/V2ErrorEnvelope'
          description: Unprocessable Entity
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              example:
                success: false
                error:
                  code: RATE_LIMIT_EXCEEDED
                  message: Rate limit exceeded. Try again later.
                meta:
                  version: '2.0'
                  timestamp: '2026-04-29T12:00:00Z'
      security:
        - ApiKeyAuth: []
components:
  schemas:
    TraceResponse:
      properties:
        success:
          type: boolean
          const: true
          title: Success
          default: true
        data:
          $ref: '#/components/schemas/TraceData'
        meta:
          $ref: '#/components/schemas/V2Meta'
      type: object
      required:
        - data
        - meta
      title: TraceResponse
    V2ErrorEnvelope:
      properties:
        success:
          type: boolean
          const: false
          title: Success
          default: false
        error:
          $ref: '#/components/schemas/V2Error'
        meta:
          $ref: '#/components/schemas/V2Meta'
      type: object
      required:
        - error
        - meta
      title: V2ErrorEnvelope
      description: Returned for every non-2xx response.
    TraceData:
      properties:
        greek:
          type: string
          enum:
            - gamma
            - charm
            - vanna
          title: Greek
          description: Which greek the field encodes.
        expiry:
          type: string
          title: Expiry
          description: Expiry filter applied — `all`, `0dte`, or a Deribit token.
        spot_price:
          type: number
          title: Spot Price
          description: Spot at the time of computation.
        vol_shift_pct:
          type: number
          title: Vol Shift Pct
          description: >-
            What-if IV shift applied to every contract (percent, additive in σ
            multiplier).
        field_units:
          type: string
          title: Field Units
          description: >-
            Units of each cell — `dealer_gamma_dollars_per_pct_spot` for gamma
            (γ × S² × OI × 1%), `dealer_charm_per_year` for charm (∂Δ/∂τ × OI),
            `dealer_vanna_per_iv_unit` for vanna (∂Δ/∂σ × OI). Sign convention:
            +1 for calls, −1 for puts.
        time_axis_ms:
          items:
            type: integer
          type: array
          title: Time Axis Ms
          description: Unix-ms timestamps along the time axis. Length = `time_steps`.
        price_axis:
          items:
            type: number
          type: array
          title: Price Axis
          description: Spot prices along the price axis. Length = `price_steps`.
        field:
          items:
            items:
              type: number
            type: array
          type: array
          title: Field
          description: >-
            2D field. `field[t][p]` is the cell value at time `time_axis_ms[t]`
            and price `price_axis[p]`.
        field_min:
          type: number
          title: Field Min
        field_max:
          type: number
          title: Field Max
        abs_field_max:
          type: number
          title: Abs Field Max
          description: >-
            `max(|field_min|, |field_max|)`. Convenient symmetric scale for
            renderers.
        contracts_used:
          type: integer
          title: Contracts Used
          description: Number of per-contract rows that contributed to the field.
        expiries_in_window:
          items:
            type: string
          type: array
          title: Expiries In Window
          description: Deribit-style expiry tokens of contracts that contributed.
        tau_floor_seconds:
          type: number
          title: Tau Floor Seconds
          description: >-
            Floor on τ used near expiry to prevent the BS-gamma cliff. Cells
            right at expiry are computed with τ = `tau_floor_seconds`.
      type: object
      required:
        - greek
        - expiry
        - spot_price
        - vol_shift_pct
        - field_units
        - time_axis_ms
        - price_axis
        - field
        - field_min
        - field_max
        - abs_field_max
        - contracts_used
        - expiries_in_window
        - tau_floor_seconds
      title: TraceData
      description: Single forward-projected greek field.
    V2Meta:
      properties:
        version:
          type: string
          const: '2.0'
          title: Version
          description: API version tag.
        timestamp:
          type: string
          title: Timestamp
          description: ISO 8601 wall-clock when the response was built.
        request_id:
          anyOf:
            - type: string
            - type: 'null'
          title: Request Id
          description: X-Request-ID for tracing across logs / Sentry.
        symbol:
          anyOf:
            - type: string
            - type: 'null'
          title: Symbol
          description: Symbol the response is about, if applicable.
        spot_price:
          anyOf:
            - type: number
            - type: 'null'
          title: Spot Price
          description: Current spot price for the symbol.
        computed_at:
          anyOf:
            - type: string
            - type: 'null'
          title: Computed At
          description: ISO 8601 of when the underlying cache value was last written.
        freshness_seconds:
          anyOf:
            - type: number
            - type: 'null'
          title: Freshness Seconds
          description: '`now - computed_at` in seconds; useful for staleness alarms.'
        source:
          anyOf:
            - items:
                type: string
              type: array
            - type: 'null'
          title: Source
          description: Upstream venue list the data flowed through.
        exchanges_filtered:
          anyOf:
            - items:
                type: string
              type: array
            - type: 'null'
          title: Exchanges Filtered
          description: Echo of the `?exchanges=` filter when one was applied.
        rate_limit:
          anyOf:
            - additionalProperties: true
              type: object
            - type: 'null'
          title: Rate Limit
          description: '`{limit, remaining, reset}` echo of the rate-limit headers.'
        extra:
          anyOf:
            - additionalProperties: true
              type: object
            - type: 'null'
          title: Extra
          description: Open dict for endpoint-specific metadata (filter_hash, etc.).
      type: object
      required:
        - version
        - timestamp
      title: V2Meta
      description: |-
        The meta block returned alongside every v2 response.

        Every field after `version`/`timestamp` is optional because endpoints
        attach different combinations — e.g. `/v2/status` skips `symbol`, the
        chain endpoint sets `extra.filter_hash`, etc. Listing them here means
        SDKs get a typed accessor for each instead of a generic `meta: dict`.
    V2Error:
      properties:
        code:
          type: string
          title: Code
          description: Stable machine-readable error code (see /v2/meta).
        message:
          type: string
          title: Message
          description: Human-readable description.
        details:
          anyOf:
            - additionalProperties: true
              type: object
            - type: 'null'
          title: Details
          description: >-
            Optional structured payload — e.g. validation_error returns the
            failing field list.
      type: object
      required:
        - code
        - message
      title: V2Error
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: Your BackQuant API key (same key as v1)

````