# `ZenQuant.Greeks`
[🔗](https://github.com/ZenHive/zen_quant/blob/v0.8.1/lib/zen_quant/greeks.ex#L1)

Portfolio Greeks aggregation and analysis.

Pure functions for aggregating option Greeks across positions
and analyzing portfolio-level risk exposure.

## Greek Definitions

  * **Delta** - Rate of change of option price with respect to underlying
  * **Gamma** - Rate of change of delta with respect to underlying
  * **Theta** - Time decay (value lost per day)
  * **Vega** - Sensitivity to implied volatility changes

## Example

    positions = [
      %{delta: 0.5, gamma: 0.02, theta: -10.0, vega: 25.0, quantity: 10},
      %{delta: -0.3, gamma: 0.015, theta: -8.0, vega: 20.0, quantity: 5}
    ]

    ZenQuant.Greeks.position_greeks(positions)
    # => %{delta: 3.5, gamma: 0.275, theta: -140.0, vega: 350.0}

## API Functions
| Function | Arity | Description | Param Kinds |
| --- | --- | --- | --- |
| `gamma_pnl` | 3 | Estimate profit from gamma if underlying moves by a given percentage. | `gamma: value`, `underlying_price: value`, `expected_move_pct: value` |
| `vega_exposure` | 1 | Calculate portfolio vega exposure. | `positions: value` |
| `daily_theta` | 1 | Calculate portfolio theta in daily terms. | `positions: value` |
| `from_chain` | 2 | Extract Greeks from option chain for aggregation. | `chain: exchange_data`, `positions: value` |
| `hedge_ratio` | 2 | Calculate hedge ratio to neutralize delta. | `portfolio_delta: value` |
| `delta_neutral?` | 2 | Check if portfolio is delta neutral within tolerance. | `delta: value` |
| `dollar_gamma` | 3 | Calculate dollar gamma (gamma exposure for 1% move in underlying). | `gamma: value`, `underlying_price: value` |
| `dollar_delta` | 3 | Calculate dollar delta (delta exposure in currency terms). | `delta: value`, `underlying_price: value` |
| `position_greeks` | 1 | Aggregate Greeks across multiple positions. | `positions: value` |

# `portfolio_greeks`

```elixir
@type portfolio_greeks() :: %{
  delta: float(),
  gamma: float(),
  theta: float(),
  vega: float()
}
```

Aggregated portfolio Greeks

# `position`

```elixir
@type position() :: %{
  optional(:symbol) =&gt; String.t(),
  optional(:delta) =&gt; number(),
  optional(:gamma) =&gt; number(),
  optional(:theta) =&gt; number(),
  optional(:vega) =&gt; number(),
  optional(:quantity) =&gt; number()
}
```

Position with Greeks data for aggregation

# `daily_theta`

```elixir
@spec daily_theta([position()]) :: float()
```

Calculate portfolio theta in daily terms.

## Parameters

  * `positions` - List of positions with Greeks (value)

## Returns

Daily theta (negative = losing value) (`float`)

### Example

```elixir
0.1095
```

```elixir
# descripex:contract
%{
  params: %{
    positions: %{description: "List of positions with Greeks", kind: :value}
  },
  returns: %{type: :float, description: "Daily theta (negative = losing value)"},
  returns_example: 0.1095
}
```

# `delta_neutral?`

```elixir
@spec delta_neutral?(number(), number()) :: boolean()
```

Check if portfolio is delta neutral within tolerance.

## Parameters

  * `delta` - Portfolio delta (value)

## Options

  * `tolerance` - Maximum acceptable delta (default: `0.1`)

## Returns

true if abs(delta) <= tolerance (`boolean`)

### Example

```elixir
true
```

```elixir
# descripex:contract
%{
  opts: %{
    tolerance: %{
      default: 0.1,
      type: :number,
      description: "Maximum acceptable delta"
    }
  },
  params: %{delta: %{description: "Portfolio delta", kind: :value}},
  returns: %{type: :boolean, description: "true if abs(delta) <= tolerance"},
  returns_example: true
}
```

# `dollar_delta`

```elixir
@spec dollar_delta(number(), number(), number()) :: float()
```

Calculate dollar delta (delta exposure in currency terms).

## Parameters

  * `delta` - Portfolio delta (value)
  * `underlying_price` - Current price of underlying (value)

## Options

  * `contract_multiplier` - Contract multiplier (default: `1`)

## Returns

Dollar delta exposure (`float`)

### Example

```elixir
0.1095
```

```elixir
# descripex:contract
%{
  opts: %{
    contract_multiplier: %{
      default: 1,
      type: :number,
      description: "Contract multiplier"
    }
  },
  params: %{
    delta: %{description: "Portfolio delta", kind: :value},
    underlying_price: %{
      description: "Current price of underlying",
      kind: :value
    }
  },
  returns: %{type: :float, description: "Dollar delta exposure"},
  returns_example: 0.1095
}
```

# `dollar_gamma`

```elixir
@spec dollar_gamma(number(), number(), number()) :: float()
```

Calculate dollar gamma (gamma exposure for 1% move in underlying).

## Parameters

  * `gamma` - Portfolio gamma (value)
  * `underlying_price` - Current price of underlying (value)

## Options

  * `contract_multiplier` - Contract multiplier (default: `1`)

## Returns

Delta change for a 1% move in underlying (`float`)

### Example

```elixir
0.1095
```

```elixir
# descripex:contract
%{
  opts: %{
    contract_multiplier: %{
      default: 1,
      type: :number,
      description: "Contract multiplier"
    }
  },
  params: %{
    gamma: %{description: "Portfolio gamma", kind: :value},
    underlying_price: %{
      description: "Current price of underlying",
      kind: :value
    }
  },
  returns: %{
    type: :float,
    description: "Delta change for a 1% move in underlying"
  },
  returns_example: 0.1095
}
```

# `from_chain`

```elixir
@spec from_chain(%{required(String.t()) =&gt; map()}, %{required(String.t()) =&gt; number()}) ::
  [position()]
```

Extract Greeks from option chain for aggregation.

## Parameters

  * `chain` - Map of symbol => option maps with :raw containing greeks (exchange_data)
  * `positions` - Map of symbol => quantity (positive=long, negative=short) (value)

## Returns

List of position maps suitable for position_greeks/1 (`list`)

### Example

```elixir
[
  %{
    symbol: "BTC-31JAN26-84000-C",
    delta: 0.52,
    gamma: 2.0e-5,
    theta: -15.0,
    vega: 48.0,
    quantity: 2
  }
]
```

```elixir
# descripex:contract
%{
  params: %{
    positions: %{
      description: "Map of symbol => quantity (positive=long, negative=short)",
      kind: :value
    },
    chain: %{
      description: "Map of symbol => option maps with :raw containing greeks",
      source: "Options.Deribit.chain(exchange_mod, enrich: :greeks)",
      kind: :exchange_data
    }
  },
  returns: %{
    type: :list,
    description: "List of position maps suitable for position_greeks/1"
  },
  returns_example: [
    %{
      symbol: "BTC-31JAN26-84000-C",
      delta: 0.52,
      gamma: 2.0e-5,
      theta: -15.0,
      vega: 48.0,
      quantity: 2
    }
  ]
}
```

# `gamma_pnl`

```elixir
@spec gamma_pnl(number(), number(), number()) :: float()
```

Estimate profit from gamma if underlying moves by a given percentage.

## Parameters

  * `gamma` - Portfolio gamma (value)
  * `underlying_price` - Current underlying price (value)
  * `expected_move_pct` - Expected move as percentage (e.g., 2.0 for 2%) (value)

## Returns

Estimated P&L from gamma exposure (`float`)

### Example

```elixir
0.1095
```

```elixir
# descripex:contract
%{
  params: %{
    gamma: %{description: "Portfolio gamma", kind: :value},
    underlying_price: %{description: "Current underlying price", kind: :value},
    expected_move_pct: %{
      description: "Expected move as percentage (e.g., 2.0 for 2%)",
      kind: :value
    }
  },
  returns: %{type: :float, description: "Estimated P&L from gamma exposure"},
  returns_example: 0.1095
}
```

# `hedge_ratio`

```elixir
@spec hedge_ratio(number(), number()) :: float()
```

Calculate hedge ratio to neutralize delta.

## Parameters

  * `portfolio_delta` - Current portfolio delta (value)

## Options

  * `hedge_delta` - Delta of hedging instrument (1.0 for spot/futures) (default: `1.0`)

## Returns

Units to buy (+) or sell (-) to achieve delta neutrality (`float`)

### Example

```elixir
0.1095
```

```elixir
# descripex:contract
%{
  opts: %{
    hedge_delta: %{
      default: 1.0,
      type: :number,
      description: "Delta of hedging instrument (1.0 for spot/futures)"
    }
  },
  params: %{
    portfolio_delta: %{description: "Current portfolio delta", kind: :value}
  },
  returns: %{
    type: :float,
    description: "Units to buy (+) or sell (-) to achieve delta neutrality"
  },
  returns_example: 0.1095
}
```

# `position_greeks`

```elixir
@spec position_greeks([position()]) :: portfolio_greeks()
```

Aggregate Greeks across multiple positions.

## Parameters

  * `positions` - List of positions with :delta, :gamma, :theta, :vega, :quantity fields (value)

## Returns

Map with aggregated :delta, :gamma, :theta, :vega (`map`)

### Example

```elixir
%{delta: 1.2, gamma: 0.04, theta: -85.0, vega: 220.0}
```

```elixir
# descripex:contract
%{
  params: %{
    positions: %{
      description: "List of positions with :delta, :gamma, :theta, :vega, :quantity fields",
      kind: :value
    }
  },
  returns: %{
    type: :map,
    description: "Map with aggregated :delta, :gamma, :theta, :vega"
  },
  returns_example: %{delta: 1.2, gamma: 0.04, theta: -85.0, vega: 220.0}
}
```

# `vega_exposure`

```elixir
@spec vega_exposure([position()]) :: float()
```

Calculate portfolio vega exposure.

## Parameters

  * `positions` - List of positions with Greeks (value)

## Returns

Portfolio value change for +1% IV change (`float`)

### Example

```elixir
0.1095
```

```elixir
# descripex:contract
%{
  params: %{
    positions: %{description: "List of positions with Greeks", kind: :value}
  },
  returns: %{
    type: :float,
    description: "Portfolio value change for +1% IV change"
  },
  returns_example: 0.1095
}
```

---

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