# `ZenQuant.Options.ZeroDTE`
[🔗](https://github.com/ZenHive/zen_quant/blob/v0.8.1/lib/zen_quant/options/zero_dte.ex#L1)

Analytics for near-expiry (0DTE) options where greeks behave non-linearly.

Near expiry, theta decays explosively and gamma creates outsized hedging
flows. These functions filter, measure, and analyze options approaching
expiration.

All functions accept the same chain format as `ZenQuant.Options` — a map
of `%{symbol => option_map}` with Deribit-format symbols.

## Example

    ZeroDTE.near_strikes(chain, 68000.0, max_dte: 1)
    # => %{"BTC-24FEB26-68000-C" => %{...}, ...}

    ZeroDTE.theta_acceleration(chain, 68000.0)
    # => [%{strike: 68000.0, near_expiry: ~D[2026-02-24], ...}]

    ZeroDTE.gamma_exposure(chain, 68000.0)
    # => %{walls: [...], summary: %{total_gex: ..., max_strike: ..., concentration_pct: ...}}

## API Functions
| Function | Arity | Description | Param Kinds |
| --- | --- | --- | --- |
| `gamma_exposure` | 3 | Gamma exposure concentration in near-expiry options. | `chain: exchange_data`, `spot: value` |
| `theta_acceleration` | 3 | Measure theta decay acceleration comparing near vs far expiry. | `chain: exchange_data`, `spot: value` |
| `near_strikes` | 3 | Filter chain to near-expiry strikes clustered around spot. | `chain: exchange_data`, `spot: value` |

# `gamma_exposure`

```elixir
@spec gamma_exposure(map(), number(), keyword()) :: %{walls: [map()], summary: map()}
```

Gamma exposure concentration in near-expiry options.

## Parameters

  * `chain` - Full option chain with gamma in :raw (exchange_data)
  * `spot` - Current spot price (value)

## Options

  * `max_dte` - Maximum days to expiry for near-expiry (default: `1`)
  * `side` - :dealer or :customer sign convention (default: `:dealer`)
  * `min_oi` - Minimum OI to include (default: `0`)
  * `top_n` - Return only top N walls by absolute GEX
  * `now_dt` - Current time (for testing) (default: `"DateTime.utc_now()"`)

## Returns

%\{walls: [%\{strike, gex, type\}], summary: %\{total_gex, max_strike, concentration_pct\}\} (`map`)

### Example

```elixir
%{
  summary: %{total_gex: 1800.0, max_strike: 84000.0, concentration_pct: 68.2},
  walls: [%{type: :support, strike: 84000.0, gex: 1250.0}]
}
```

```elixir
# descripex:contract
%{
  opts: %{
    side: %{
      default: :dealer,
      type: :atom,
      description: ":dealer or :customer sign convention"
    },
    max_dte: %{
      default: 1,
      type: :integer,
      description: "Maximum days to expiry for near-expiry"
    },
    now_dt: %{
      default: "DateTime.utc_now()",
      type: :datetime,
      description: "Current time (for testing)"
    },
    min_oi: %{default: 0, type: :number, description: "Minimum OI to include"},
    top_n: %{
      default: nil,
      type: :integer,
      description: "Return only top N walls by absolute GEX"
    }
  },
  params: %{
    spot: %{description: "Current spot price", kind: :value},
    chain: %{
      description: "Full option chain with gamma in :raw",
      source: "Options.Deribit.chain(exchange_mod, enrich: :greeks)",
      kind: :exchange_data
    }
  },
  returns: %{
    type: :map,
    description: "%{walls: [%{strike, gex, type}], summary: %{total_gex, max_strike, concentration_pct}}"
  },
  returns_example: %{
    summary: %{total_gex: 1800.0, max_strike: 84000.0, concentration_pct: 68.2},
    walls: [%{type: :support, strike: 84000.0, gex: 1250.0}]
  }
}
```

# `near_strikes`

```elixir
@spec near_strikes(map(), number(), keyword()) :: map()
```

Filter chain to near-expiry strikes clustered around spot.

## Parameters

  * `chain` - Option chain map %\{symbol => option_map\} (exchange_data)
  * `spot` - Current spot price (value)

## Options

  * `threshold_pct` - Max percentage distance from spot (default: `5.0`)
  * `max_dte` - Maximum days to expiry (default: `1`)
  * `now_dt` - Current time (for testing) (default: `"DateTime.utc_now()"`)

## Returns

Filtered chain %\{symbol => option_map\} — same shape as input (`map`)

### Example

```elixir
%{"BTC-31JAN26-84000-C" => %{open_interest: 1200.0}}
```

## Composes With

  * `theta_acceleration`
  * `gamma_exposure`

```elixir
# descripex:contract
%{
  opts: %{
    threshold_pct: %{
      default: 5.0,
      type: :float,
      description: "Max percentage distance from spot"
    },
    max_dte: %{
      default: 1,
      type: :integer,
      description: "Maximum days to expiry"
    },
    now_dt: %{
      default: "DateTime.utc_now()",
      type: :datetime,
      description: "Current time (for testing)"
    }
  },
  params: %{
    spot: %{description: "Current spot price", kind: :value},
    chain: %{
      description: "Option chain map %{symbol => option_map}",
      source: "Options.Deribit.chain(exchange_mod)",
      kind: :exchange_data
    }
  },
  returns: %{
    type: :map,
    description: "Filtered chain %{symbol => option_map} — same shape as input"
  },
  returns_example: %{"BTC-31JAN26-84000-C" => %{open_interest: 1200.0}},
  composes_with: [:theta_acceleration, :gamma_exposure]
}
```

# `theta_acceleration`

```elixir
@spec theta_acceleration(map(), number(), keyword()) :: [map()]
```

Measure theta decay acceleration comparing near vs far expiry.

## Parameters

  * `chain` - Full option chain with theta in :raw (exchange_data)
  * `spot` - Current spot price (value)

## Options

  * `threshold_pct` - Max percentage distance from spot (default: `5.0`)
  * `now_dt` - Current time (for testing) (default: `"DateTime.utc_now()"`)

## Returns

List of %\{strike, near_expiry, far_expiry, near_theta, far_theta, acceleration\} sorted by acceleration desc (`list`)

### Example

```elixir
[
  %{
    strike: 84000.0,
    near_expiry: ~D[2026-01-31],
    far_expiry: ~D[2026-02-28],
    near_theta: -22.0,
    far_theta: -8.0,
    acceleration: 2.75
  }
]
```

```elixir
# descripex:contract
%{
  opts: %{
    threshold_pct: %{
      default: 5.0,
      type: :float,
      description: "Max percentage distance from spot"
    },
    now_dt: %{
      default: "DateTime.utc_now()",
      type: :datetime,
      description: "Current time (for testing)"
    }
  },
  params: %{
    spot: %{description: "Current spot price", kind: :value},
    chain: %{
      description: "Full option chain with theta in :raw",
      source: "Options.Deribit.chain(exchange_mod, enrich: :greeks)",
      kind: :exchange_data
    }
  },
  returns: %{
    type: :list,
    description: "List of %{strike, near_expiry, far_expiry, near_theta, far_theta, acceleration} sorted by acceleration desc"
  },
  returns_example: [
    %{
      strike: 84000.0,
      near_expiry: ~D[2026-01-31],
      far_expiry: ~D[2026-02-28],
      near_theta: -22.0,
      far_theta: -8.0,
      acceleration: 2.75
    }
  ]
}
```

---

*Consult [api-reference.md](api-reference.md) for complete listing*
