ZenQuant.Options.ZeroDTE (zen_quant v0.2.0)

Copy Markdown View Source

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

FunctionArityDescriptionParam Kinds
gamma_exposure3Gamma exposure concentration in near-expiry options.chain: exchange_data, spot: value
theta_acceleration3Measure theta decay acceleration comparing near vs far expiry.chain: exchange_data, spot: value
near_strikes3Filter chain to near-expiry strikes clustered around spot.chain: exchange_data, spot: value

Summary

Functions

Gamma exposure concentration in near-expiry options.

Filter chain to near-expiry strikes clustered around spot.

Measure theta decay acceleration comparing near vs far expiry.

Functions

gamma_exposure(chain, spot, opts \\ [])

@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

%{
  summary: %{total_gex: 1800.0, max_strike: 84000.0, concentration_pct: 68.2},
  walls: [%{type: :support, strike: 84000.0, gex: 1250.0}]
}
# 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(chain, spot, opts \\ [])

@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

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

Composes With

  • theta_acceleration
  • gamma_exposure
# 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(chain, spot, opts \\ [])

@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

[
  %{
    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
  }
]
# 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
    }
  ]
}