TL;DR

Delta, gamma, theta, vega, rho — the partial derivatives of option price with respect to each risk factor. Delta and theta are usually the ones that move P&L day to day; gamma is the one that makes them move non-linearly near expiry; vega is the one that reprices the book when implied volatility shifts regime; rho matters mostly for long-dated positions. An LLM-driven options workflow has to aggregate these Greeks across legs to answer "what is this structure's net exposure?" — and LLMs confabulate signs and magnitudes when the prompt is unstructured. Below: what each Greek actually measures, the three practical rules that prevent the classic retail blow-ups, and a structured JSON prompt template that reliably extracts the aggregated Greeks profile of a multi-leg position with a built-in check-your-work step.

What each Greek measures

For a European option with price C, underlying price S, time to expiry τ, implied volatility σ, and risk-free rate r:

Greek Partial Intuition Units
Delta ∂C/∂S Change in option price per $1 move in underlying [0, 1] for calls, [−1, 0] for puts
Gamma ∂²C/∂S² Change in delta per $1 move in underlying per $
Theta ∂C/∂τ Change in option price per day of decay $/day (negative for long premium)
Vega ∂C/∂σ Change in option price per 1-vol-point move in IV $ per vol point
Rho ∂C/∂r Change in option price per 1-bp move in risk-free rate $ per bp

Delta, gamma, and theta come from the Black-Scholes closed form (Black & Scholes 1973).1 Vega is the partial with respect to σ; note that Black-Scholes treats σ as constant, yet every practitioner perturbs it anyway — vega is the correction term the model technically forbids.

Formulas (European, no dividends)

For a call with d₁ = (ln(S/K) + (r + σ²/2)τ) / (σ√τ) and d₂ = d₁ − σ√τ:

Delta_call  = Φ(d₁)
Delta_put   = Φ(d₁) − 1
Gamma       = φ(d₁) / (S · σ · √τ)
Vega        = S · φ(d₁) · √τ / 100             # per 1-vol-point
Theta_call  = −S · φ(d₁) · σ / (2√τ)
              − r · K · e^(−rτ) · Φ(d₂)         # per year; divide by 365 for per-day
Rho_call    = K · τ · e^(−rτ) · Φ(d₂) / 10000  # per 1-bp

Φ is the standard normal CDF, φ the PDF. Put Greeks derive symmetrically via put-call parity.

The three practical rules

Rule 1: Theta is the tax on long premium

Long calls and long puts decay every day the underlying does not move. A 30-DTE at-the-money option typically has theta around −0.5% of premium per day. Long-premium strategies must therefore have a directional thesis sharp enough to outpace theta. Most retail "lottery ticket" buying does not; the trade was dead at entry.

Selling premium (short calls, short puts, short strangles) collects the theta but incurs the opposite risk: negative gamma. Which brings Rule 2.

Rule 2: Never sell undefined-risk gamma near expiry

Gamma scales as 1 / √τ. A 30-DTE ATM position has moderate gamma; a 1-DTE ATM position has gamma an order of magnitude higher. Short-gamma positions (short strangles, naked short puts) that looked "safe" at 30-DTE have catastrophic risk in the last week as small underlying moves translate into large delta swings.

The concrete failure mode: a short strangle on SPX at 30-DTE has ±0.10 delta per leg and manageable gamma. At 5-DTE, if the underlying drifts 1%, the short put leg can flip to −0.40 delta, and the trader is suddenly net short four S&P futures they never intended to hold. This is how retail short-vol accounts die.

The rule: either close short-gamma positions before gamma explodes (roll at 21-DTE is a common choice), or use defined-risk structures (credit spreads, iron condors) whose maximum loss is capped regardless of gamma.

Rule 3: Vega flips sign with the vol regime

Long vega strategies (long options, long VIX calls, calendar spreads) profit when realised or implied volatility rises. Short vega strategies (short options, short strangles, short VIX) profit when vol falls. The direction of a vega-neutral position can invert when the vol-of-vol regime changes.

A calendar spread (long back-month, short front-month) has positive net vega at most volatility levels. It flips sign when front-month IV rises faster than back-month IV — the classic "vol curve inversion" pattern that occurs around earnings or macro events. Positions that were vega-positive yesterday can be vega-negative today, without the trader changing a thing.

The rule: recompute Greeks whenever IV moves more than roughly 2 points. Static Greek estimates drift silently.

Why LLMs confabulate Greeks

An LLM asked "what's the net delta of a 100-strike long call and a 105-strike short call?" can return the correct answer (positive, bounded by 1). An LLM asked "what's the net delta of the attached position?" with an unstructured table can return a confident wrong answer. The failure modes:

  1. Sign flipping — treating a short leg as long or vice versa.
  2. Multiplier omission — US equity options have multiplier 100; the LLM forgets and computes per-share.
  3. Strike/underlying confusion — using the strike as the spot price.
  4. Expiry aggregation — summing Greeks across different expiries as if they scaled identically.
  5. Fabricated magnitudes — producing a plausible number with no computation behind it.

The fix is not "better model." The fix is a structured prompt that forces per-leg reasoning, explicit sign-and-multiplier bookkeeping, and a cross-check.

The structured prompt template

SYSTEM:
You are a position-Greeks calculator. Follow the schema exactly. Do not invent
fields. Return only valid JSON. If any input is missing or ambiguous, return
`{"error": "<what's missing>"}`.

USER:
Compute the aggregated Greeks for the following multi-leg options position.

INPUTS:
- underlying: {ticker}
- spot: {spot_price}
- risk_free_rate_annual: {rf}
- valuation_date: {YYYY-MM-DD}
- legs: [
    { action: "long"|"short", contracts: int,
      option_type: "call"|"put",
      strike: float, expiry: "YYYY-MM-DD",
      implied_vol: float (decimal, e.g. 0.22) },
    ...
  ]
- contract_multiplier: 100   # US equity options standard

PROCEDURE:
1. For EACH leg, compute per-share Greeks using Black-Scholes (no dividend):
     delta, gamma, theta_per_day, vega_per_vol_point, rho_per_bp
2. For EACH leg, compute leg-level totals:
     leg_total_<greek> = per_share_<greek>
       · sign(long=+1, short=-1)
       · contracts
       · contract_multiplier
3. Sum leg totals into position totals.
4. Perform the CHECK step (see below) and report any discrepancy.

OUTPUT SCHEMA (JSON only):
{
  "legs": [
    {
      "description": "<e.g. Long 1 AAPL 190C 2026-05-16>",
      "per_share": { "delta": f, "gamma": f, "theta_per_day": f,
                     "vega_per_vol_point": f, "rho_per_bp": f },
      "leg_total": { "delta": f, "gamma": f, "theta_per_day": f,
                     "vega_per_vol_point": f, "rho_per_bp": f }
    }
  ],
  "position_total": {
    "delta": f, "gamma": f, "theta_per_day": f,
    "vega_per_vol_point": f, "rho_per_bp": f
  },
  "interpretation": {
    "directional_bias": "long"|"short"|"neutral",
    "convexity": "positive"|"negative"|"mixed",
    "premium_posture": "net_long"|"net_short",
    "dominant_risk": "<one of: delta, gamma, theta, vega>"
  },
  "check": {
    "delta_sign_matches_interpretation": bool,
    "theta_sign_matches_premium_posture": bool,
    "gamma_sign_matches_convexity": bool,
    "notes": "<free text if any check failed>"
  }
}

The template forces four things the unstructured prompt did not:

  1. Per-leg computation before aggregation. The model cannot skip the per-share step; the schema demands it.
  2. Explicit sign-and-multiplier arithmetic. The leg total is built from typed components, not pattern-matched.
  3. Interpretation tied to totals. The interpretation object is derived from the totals, creating a second chance to catch a sign error.
  4. A self-check step. The check object tests consistency (positive gamma ↔ positive convexity, negative theta ↔ net_long premium). An LLM that fabricated totals will usually fail at least one check.

This pattern generalises. Any LLM-driven analytical workflow where confabulated numbers matter should follow the same shape: structured inputs → typed per-item computation → typed aggregation → interpretation → machine-checkable verification step.

A minimal Python reference implementation

For ground-truth comparison against the LLM output, run the same math locally:

import numpy as np
from scipy.stats import norm

def bs_greeks(
    option_type: str,   # "call" or "put"
    S: float, K: float, tau: float,
    sigma: float, r: float,
) -> dict:
    if tau <= 0:
        return {"delta": 0.0, "gamma": 0.0, "theta_per_day": 0.0,
                "vega_per_vol_point": 0.0, "rho_per_bp": 0.0}
    d1 = (np.log(S / K) + (r + 0.5 * sigma ** 2) * tau) / (sigma * np.sqrt(tau))
    d2 = d1 - sigma * np.sqrt(tau)
    phi = norm.pdf(d1)

    if option_type == "call":
        delta = norm.cdf(d1)
        theta_annual = (-S * phi * sigma / (2 * np.sqrt(tau))
                        - r * K * np.exp(-r * tau) * norm.cdf(d2))
        rho_annual = K * tau * np.exp(-r * tau) * norm.cdf(d2)
    else:
        delta = norm.cdf(d1) - 1
        theta_annual = (-S * phi * sigma / (2 * np.sqrt(tau))
                        + r * K * np.exp(-r * tau) * norm.cdf(-d2))
        rho_annual = -K * tau * np.exp(-r * tau) * norm.cdf(-d2)

    gamma = phi / (S * sigma * np.sqrt(tau))
    vega = S * phi * np.sqrt(tau)

    return {
        "delta": float(delta),
        "gamma": float(gamma),
        "theta_per_day": float(theta_annual / 365.0),
        "vega_per_vol_point": float(vega / 100.0),
        "rho_per_bp": float(rho_annual / 10000.0),
    }

def aggregate_position(legs: list, multiplier: int = 100) -> dict:
    totals = {k: 0.0 for k in
              ("delta", "gamma", "theta_per_day",
               "vega_per_vol_point", "rho_per_bp")}
    for leg in legs:
        g = bs_greeks(leg["option_type"], leg["S"], leg["K"],
                      leg["tau"], leg["sigma"], leg["r"])
        sign = 1 if leg["action"] == "long" else -1
        scale = sign * leg["contracts"] * multiplier
        for k in totals:
            totals[k] += g[k] * scale
    return totals

Use it to score the LLM: parse the JSON, recompute position totals locally, flag any leg whose delta is more than 2% off from local ground truth. The Agent Skill Tester for Markets automates exactly this comparison across a battery of fixture positions.

When the prompt template is not enough

Three failure modes the template does not catch:

  • Wrong implied volatility. If the input implied_vol is stale or fabricated, every downstream Greek is wrong. Source IV from a broker API with a timestamp, not from the LLM.
  • American-exercise early-exercise premium. Black-Scholes prices European options. American options on dividend-paying stocks have an early-exercise premium the closed form ignores. For most retail equity-index and ETF options, the error is under 1% and does not matter for Greek aggregation; for deep ITM single-name calls on high-dividend names, it does.
  • Volatility-surface curvature. Real markets do not have a single σ — there is a full surface across strike and expiry. The Greeks at a strike computed with that strike's IV (the "market IV" standard) are correct per-leg but miss second-order effects when the surface shifts shape, not level. For multi-leg positions spanning multiple strikes, vega can mask vanna (∂²C / ∂S∂σ) and volga (∂²C / ∂σ²) exposure.

For most retail workflows, the structured-prompt + local-ground-truth pattern is sufficient. The surface effects matter only when the position size is large enough that second-order Greeks dominate.

Connects to

References

  • Hull, J. C. (2018). Options, Futures, and Other Derivatives (10th ed.), Pearson. Chapter 19 is the canonical Greeks reference.
  • Merton, R. C. (1973). "Theory of Rational Option Pricing." Bell Journal of Economics and Management Science 4(1).
  • Derman, E., & Kani, I. (1994). "Riding on a Smile." Risk Magazine 7(2). On vol-surface structure beyond flat-σ Black-Scholes.
  • Natenberg, S. (2015). Option Volatility and Pricing (2nd ed.), McGraw-Hill. The practitioner reference for Greeks behaviour across expiry and moneyness.

Footnotes

  1. Black, F., & Scholes, M. (1973). "The Pricing of Options and Corporate Liabilities." Journal of Political Economy 81(3), pp. 637–654.