Strategy Guide

AI Agent Crypto Options & Derivatives Strategies: Greeks, Volatility, and Systematic Execution

Options are the most powerful instruments in a crypto agent's toolkit — but also the most complex. Delta hedging, volatility surface arbitrage, systematic covered calls, and multi-leg structures like iron condors all require the kind of tireless, precise computation that AI agents perform better than humans. This guide covers the complete landscape: from basic options Greeks automation to advanced term structure trading, with full code examples in Python and JavaScript.

The Crypto Options Landscape

Crypto options have matured dramatically. What was once a thin, illiquid market dominated by over-the-counter desks is now a multi-billion-dollar ecosystem with competitive venues, standardized contracts, and publicly available Greeks. AI agents have an asymmetric edge here: options require constant Greeks monitoring, delta hedging at precise intervals, and the ability to scan hundreds of strikes and expiries simultaneously — tasks that are trivial for an agent and exhausting for a human trader.

Major venues and their characteristics

Venue Type Assets Notable Feature API?
Deribit Centralized BTC, ETH, SOL, others Largest OI; DVOL index; Black-Scholes IV surface API Yes (REST + WS)
Lyra Finance Decentralized ETH, BTC, SOL On-chain AMM pricing; liquidation-resistant LPs Yes (v2 SDK)
Premia Finance Decentralized ETH, BTC, ARB, LINK CLOB-style on-chain; discrete strike pools Yes (v3 API)
Hegic Decentralized ETH, BTC Single-sided LP; no counterparty selection Limited
Aevo Options Centralized L2 ETH, BTC, SOL, AEVO High-throughput L2; combined perp + options book Yes (REST + WS)
Ribbon Finance Decentralized ETH, BTC, AVAX Automated DOV (options vault) strategies Vault-level

For agent-driven strategies, Deribit remains the primary venue due to its deep liquidity, comprehensive API, and the DVOL volatility index. Aevo is the leading choice for agents wanting to combine perpetual and options positions on one platform. DeFi venues like Lyra and Premia offer composability advantages but require on-chain gas budget management.

Agent advantage: Deribit's API returns pre-computed Greeks (delta, gamma, theta, vega, rho) on every options quote. An agent can scan the entire BTC options surface — all strikes, all expiries — in a single API call, compute aggregate portfolio Greeks in milliseconds, and rebalance delta in near real-time. A human doing the same would need an entire trading desk.

Options Greeks for Agents: What They Are and Why Agents Automate Them

Greeks quantify how an option's price changes with respect to various inputs. For systematic agents, each Greek represents both a risk dimension to manage and a potential signal to trade.

Delta (Δ)

Rate of change of option price with respect to the underlying. A call at 0.50 delta moves $0.50 for every $1 move in BTC. Agents hedge delta by taking an offsetting position in the perpetual or spot.

Gamma (Γ)

Rate of change of delta with respect to the underlying. High gamma means delta shifts rapidly near expiry. Long gamma agents profit from large moves; short gamma agents profit from calm markets but bleed on big moves.

Theta (Θ)

Time decay — how much option value erodes per day, all else equal. Negative for option buyers (time works against them), positive for sellers. Agents running short options positions track theta as daily income.

Vega (ν)

Sensitivity to implied volatility changes. A vega of 0.05 means a 1-point IV increase adds $0.05 to the option value. Agents trade vega when they have a directional view on volatility (DVOL above/below fair value).

Rho and second-order Greeks

Rho (interest rate sensitivity) is typically minor in crypto but becomes relevant when on-chain borrowing rates spike. Vanna (change in delta with respect to IV) and Volga (change in vega with respect to IV) are second-order Greeks that matter for large books and volatility surface arbitrage. Most agents start with the four primary Greeks and add Vanna tracking once their books grow above ~$50K notional.

Automated Greeks tracking: Python implementation

Greeks portfolio tracker — fetch full surface and aggregate positions Python
import requests, json
from dataclasses import dataclass, field
from typing import List, Dict
import math

DERIBIT_BASE = "https://www.deribit.com/api/v2"

@dataclass
class OptionPosition:
    instrument: str           # e.g. "BTC-28MAR25-80000-C"
    size: float               # positive = long, negative = short
    delta: float
    gamma: float
    theta: float
    vega: float
    mark_price: float
    underlying_price: float

@dataclass
class PortfolioGreeks:
    net_delta: float = 0.0
    net_gamma: float = 0.0
    net_theta: float = 0.0     # daily USD theta
    net_vega: float  = 0.0     # per 1-vol-point
    positions: List[OptionPosition] = field(default_factory=list)

def fetch_option_greeks(instrument_name: str) -> dict:
    """Fetch mark price + greeks for a single option from Deribit."""
    resp = requests.get(
        f"{DERIBIT_BASE}/public/get_order_book",
        params={"instrument_name": instrument_name, "depth": 1}
    )
    data = resp.json()["result"]
    greeks = data.get("greeks", {})
    return {
        "delta":       greeks.get("delta",  0.0),
        "gamma":       greeks.get("gamma",  0.0),
        "theta":       greeks.get("theta",  0.0),
        "vega":        greeks.get("vega",   0.0),
        "mark_price":  data.get("mark_price", 0.0),
        "underlying":  data.get("underlying_price", 0.0),
        "iv":          data.get("mark_iv", 0.0),
    }

def build_portfolio_greeks(positions_raw: List[Dict]) -> PortfolioGreeks:
    """
    positions_raw: [{"instrument": "BTC-28MAR25-80000-C", "size": -1.0}, ...]
    Returns aggregated portfolio Greeks.
    """
    portfolio = PortfolioGreeks()
    for p in positions_raw:
        g = fetch_option_greeks(p["instrument"])
        pos = OptionPosition(
            instrument      = p["instrument"],
            size            = p["size"],
            delta           = g["delta"],
            gamma           = g["gamma"],
            theta           = g["theta"],
            vega            = g["vega"],
            mark_price      = g["mark_price"],
            underlying_price= g["underlying"],
        )
        portfolio.positions.append(pos)
        portfolio.net_delta += pos.delta * pos.size
        portfolio.net_gamma += pos.gamma * pos.size
        portfolio.net_theta += pos.theta * pos.size  # theta is per-day USD
        portfolio.net_vega  += pos.vega  * pos.size
    return portfolio

# Example usage
positions = [
    {"instrument": "BTC-28MAR25-80000-C", "size": -2.0},  # short 2 calls
    {"instrument": "BTC-28MAR25-75000-P", "size": -2.0},  # short 2 puts
]
book = build_portfolio_greeks(positions)
print(f"Net Delta: {book.net_delta:.4f} BTC")
print(f"Net Gamma: {book.net_gamma:.6f} per $1 move")
print(f"Net Theta: ${book.net_theta:.2f} / day")
print(f"Net Vega:  ${book.net_vega:.2f} per 1-vol-pt")

This scanner runs every few minutes in the agent's main loop. When net delta drifts beyond a threshold (e.g., ±0.05 BTC equivalent), the agent automatically submits a offsetting trade on Purple Flea's perpetual market to re-center the book.

Covered Call Strategies: Generating Yield on Spot Holdings

A covered call is the simplest income-generating options strategy: an agent holds spot BTC (or ETH, SOL) and sells an out-of-the-money call against it. If the price stays below the strike at expiry, the call expires worthless and the agent keeps the premium as yield. If the price exceeds the strike, the agent delivers the coins at the agreed price — still profitable, but with capped upside.

Why covered calls are natural for AI agents

The systematic covered call program — sometimes called a "buy-write" — is nearly impossible to manage consistently as a human trader. An agent handles all of it automatically:

Systematic covered call agent — weekly BTC calls on Deribit Python
import requests, time
from datetime import datetime, timedelta

DERIBIT = "https://www.deribit.com/api/v2"
DERIBIT_KEY = "your_deribit_api_key"
DERIBIT_SECRET = "your_deribit_secret"

def get_btc_instruments():
    """Fetch all live BTC options instruments."""
    resp = requests.get(f"{DERIBIT}/public/get_instruments",
        params={"currency": "BTC", "kind": "option", "expired": "false"})
    return resp.json()["result"]

def get_spot_price():
    resp = requests.get(f"{DERIBIT}/public/get_index_price",
        params={"index_name": "btc_usd"})
    return resp.json()["result"]["index_price"]

def find_covered_call_strike(instruments, spot_price,
                               target_delta=0.25, days_out=7):
    """
    Find the call closest to target_delta with ~days_out days to expiry.
    Returns the best instrument or None.
    """
    target_expiry = datetime.utcnow() + timedelta(days=days_out)
    candidates = []
    for inst in instruments:
        if inst["option_type"] != "call":
            continue
        exp_ts = inst["expiration_timestamp"] / 1000
        exp_dt = datetime.utcfromtimestamp(exp_ts)
        days_to_exp = (exp_dt - datetime.utcnow()).days
        if not (5 <= days_to_exp <= 14):
            continue
        book = requests.get(f"{DERIBIT}/public/get_order_book",
            params={"instrument_name": inst["instrument_name"], "depth": 1}).json()["result"]
        greeks = book.get("greeks", {})
        delta = greeks.get("delta", 1.0)
        bid = book.get("best_bid_price", 0)
        iv  = book.get("mark_iv", 0)
        if bid < 0.001:  # skip illiquid strikes
            continue
        candidates.append({
            "instrument": inst["instrument_name"],
            "delta":      delta,
            "bid":        bid,
            "iv":         iv,
            "days":       days_to_exp,
            "strike":     inst["strike"],
            "delta_dist": abs(delta - target_delta),
        })
    if not candidates:
        return None
    candidates.sort(key=lambda x: x["delta_dist"])
    return candidates[0]

# --- Main covered call loop ---
spot = get_spot_price()
instruments = get_btc_instruments()
best_call = find_covered_call_strike(instruments, spot)

if best_call:
    annual_yield = (best_call["bid"] * spot) / spot * (365 / best_call["days"]) * 100
    print(f"Best covered call: {best_call['instrument']}")
    print(f"  Delta:     {best_call['delta']:.3f}")
    print(f"  Bid (BTC): {best_call['bid']:.4f}")
    print(f"  IV:        {best_call['iv']:.1f}%")
    print(f"  Annualized yield: ~{annual_yield:.1f}%")

Roll discipline: The most common mistake in covered call programs is failing to roll when the underlying surges. Set an automatic trigger: if spot moves within 2% of the short strike, initiate a roll to a strike at least 5% above current spot with at least 7 days added to expiry. Never let a covered call expire deep in-the-money without a roll decision — it forces delivery of the spot holdings at a below-market price.

Cash-Secured Puts: Acquiring Assets at Lower Prices

The mirror image of the covered call is the cash-secured put. An agent holds USDC collateral and sells an out-of-the-money put at a target purchase price. Two outcomes are possible:

For an agent that wants to accumulate BTC on dips, this is a superior strategy to placing a limit buy order. The limit buy generates no income while waiting; the cash-secured put generates premium income regardless of whether spot reaches the target level.

Annualized returns on cash-secured puts

Scenario (BTC at $85K) Strike Premium (BTC) Days Ann. Yield on USDC
Conservative (-5% OTM) $80,750 0.0030 7 ~18.5%
Moderate (-10% OTM) $76,500 0.0018 7 ~11.2%
Aggressive (-3% OTM) $82,450 0.0055 7 ~33.8%
Longer dated (-8% OTM) $78,200 0.0060 21 ~11.0%

Note that shorter-dated puts have higher annualized yields due to accelerated theta decay, but more aggressive short-dated puts also carry higher delta risk if BTC makes a sudden move. A well-run cash-secured put agent sizes each put so that assignment on all open puts would not exceed the USDC balance — hence "cash-secured."

Volatility Trading: Straddles and Strangles Before Major Events

Options are volatility instruments as much as directional instruments. When an agent has a view that realized volatility will exceed implied volatility — regardless of direction — the correct trade is a long straddle or strangle.

When to go long volatility in crypto

Straddle vs. strangle mechanics

A straddle buys an at-the-money (ATM) call and an ATM put at the same strike. Maximum loss is the combined premium paid; profits when spot moves significantly in either direction. A strangle buys an OTM call and OTM put at different strikes, with lower premium cost but requiring a larger move to profit.

Straddle entry scanner — find best ATM options before an event JavaScript
const axios = require('axios');

const DERIBIT = 'https://www.deribit.com/api/v2';

async function findAtmStraddle(currency = 'BTC', targetDays = 7) {
  // Step 1: Get spot price
  const indexResp = await axios.get(`${DERIBIT}/public/get_index_price`,
    { params: { index_name: `${currency.toLowerCase()}_usd` } });
  const spot = indexResp.data.result.index_price;

  // Step 2: Get all options
  const instResp = await axios.get(`${DERIBIT}/public/get_instruments`,
    { params: { currency, kind: 'option', expired: 'false' } });
  const instruments = instResp.data.result;

  // Step 3: Filter to target expiry window
  const now = Date.now();
  const targetMs = targetDays * 86400000;
  const nearExpiry = instruments.filter(i => {
    const msToExp = i.expiration_timestamp - now;
    return msToExp > 3 * 86400000 && msToExp < 14 * 86400000;
  });

  // Step 4: Find ATM strike (closest to spot)
  const strikes = [...new Set(nearExpiry.map(i => i.strike))].sort((a,b) => a-b);
  const atmStrike = strikes.reduce((prev, curr) =>
    Math.abs(curr - spot) < Math.abs(prev - spot) ? curr : prev);

  // Step 5: Fetch call and put books at ATM strike
  const callName = nearExpiry.find(i => i.strike === atmStrike && i.option_type === 'call')?.instrument_name;
  const putName  = nearExpiry.find(i => i.strike === atmStrike && i.option_type === 'put')?.instrument_name;

  const [callBook, putBook] = await Promise.all([
    axios.get(`${DERIBIT}/public/get_order_book`, { params: { instrument_name: callName, depth: 1 } }),
    axios.get(`${DERIBIT}/public/get_order_book`, { params: { instrument_name: putName,  depth: 1 } }),
  ]);
  const callAsk = callBook.data.result.best_ask_price;
  const putAsk  = putBook.data.result.best_ask_price;
  const callIV  = callBook.data.result.mark_iv;
  const putIV   = putBook.data.result.mark_iv;
  const straddelCost = (callAsk + putAsk) * spot;  // in USD
  const avgIV   = (callIV + putIV) / 2;

  // Breakeven: spot must move +/- straddle_cost / spot from strike
  const breakevenPct = ((callAsk + putAsk) / 2) * 100;

  console.log(`ATM Straddle Analysis: ${callName} + ${putName}`);
  console.log(`  Spot:           $${spot.toLocaleString()}`);
  console.log(`  ATM Strike:     $${atmStrike.toLocaleString()}`);
  console.log(`  Call ask (BTC): ${callAsk.toFixed(4)}`);
  console.log(`  Put ask (BTC):  ${putAsk.toFixed(4)}`);
  console.log(`  Total cost:     $${straddelCost.toFixed(0)}`);
  console.log(`  Avg IV:         ${avgIV.toFixed(1)}%`);
  console.log(`  Breakeven move: ±${breakevenPct.toFixed(2)}%`);
  return { callName, putName, cost: straddelCost, iv: avgIV, breakevenPct };
}

findAtmStraddle('BTC', 7).catch(console.error);

The breakeven percentage is critical: if DVOL prices the weekly straddle at ±4.5% and the agent estimates a ±7% move (based on a macro catalyst), the straddle is underpriced and the purchase is justified. If the agent's move estimate is only ±3%, the implied volatility is too rich and selling the straddle (short volatility) is the better play.

Iron Condor in Crypto: Selling Volatility in Ranging Markets

The iron condor is the premium-selling strategy for range-bound markets. It combines a short strangle (sell OTM call + sell OTM put) with a long strangle at wider strikes to cap maximum loss. The agent collects premium as long as spot remains between the two short strikes at expiry.

Iron condor structure

Maximum profit = net premium received (when spot expires between P1 and C1). Maximum loss = wing width minus premium received. In crypto, wings are typically sized at 4–6% per wing given the asset's historical move distribution.

When is an iron condor appropriate? After a large realized volatility event (e.g., a +25% BTC week), implied volatility is often elevated while the market consolidates. The IV mean-reversion creates a positive theta environment for iron condors — the agent collects accelerating decay as expiry approaches and IV compresses back to baseline.

Iron condor P&L at expiry

BTC at Expiry P&L Scenario Outcome
Below P2 (e.g., below $74K) Max loss = wing width - premium Max loss hit
Between P2 and P1 ($74K–$78K) Partial loss (put spread absorbs) Partial loss
Between P1 and C1 ($78K–$91K) All options expire worthless Full premium collected
Between C1 and C2 ($91K–$95K) Partial loss (call spread absorbs) Partial loss
Above C2 (above $95K) Max loss = wing width - premium Max loss hit

A key advantage for agents: the iron condor's Greeks profile (short gamma, short vega, long theta) means the agent automatically benefits from low realized volatility and time passage — no directional view needed, just a range estimate. The agent monitors gamma continuously and closes the position early if realized vol accelerates above a pre-set threshold.

Perpetual vs. Options for Hedging: A Comparison

When an agent holds a spot BTC position and wants to hedge downside, two primary instruments are available: put options and short perpetual futures. The choice matters significantly for cost, flexibility, and Greek profile.

Dimension Put Option Hedge Short Perpetual Hedge
Cost structure Upfront premium (known max cost) Funding rate (variable, ongoing)
Upside participation Retained above strike Fully offset (delta = -1 if fully hedged)
Downside protection Full below strike (after breakeven) Full below entry (dollar-for-dollar)
Delta behavior Dynamic (gamma-adjusted with moves) Constant -1 per unit short
Best environment High-fear, elevated IV spike periods Persistently positive funding (longs pay)
Purple Flea usage Deribit puts + PF spot wallet PF perp short + PF spot wallet

The sophisticated agent uses both simultaneously. The base hedge is a short perpetual on Purple Flea (cheap to maintain when funding is negative, i.e., when shorts collect funding from longs). When DVOL spikes above 75–80 (suggesting the market prices in extreme fear), the agent switches the marginal hedge to a short-dated put that allows upside participation if the panic reverses.

Delta-neutral hedging loop with Purple Flea perps

Delta-neutral rebalancer — pair Deribit options with PF perpetuals Python
import requests

PF_BASE    = "https://purpleflea.com/api/v1"
PF_API_KEY = "your_pf_api_key"

def get_pf_perp_position(symbol="BTC-USDC"):
    """Fetch current PF perpetual position for BTC."""
    resp = requests.get(f"{PF_BASE}/trading/positions",
        headers={"Authorization": f"Bearer {PF_API_KEY}"})
    positions = resp.json().get("positions", [])
    for p in positions:
        if p["symbol"] == symbol:
            return p["size"]   # negative = short, positive = long
    return 0.0

def place_pf_perp_order(symbol, side, size, order_type="market"):
    """Place a perp order on Purple Flea to adjust delta hedge."""
    payload = {
        "symbol":     symbol,
        "side":       side,       # "buy" or "sell"
        "size":       size,
        "type":       order_type,
    }
    resp = requests.post(f"{PF_BASE}/trading/order",
        headers={"Authorization": f"Bearer {PF_API_KEY}"},
        json=payload)
    return resp.json()

def rebalance_delta(options_net_delta: float,
                    hedge_threshold: float = 0.05):
    """
    options_net_delta: the options book's net delta in BTC.
    A positive net_delta means the book is net long delta — we need
    to short perps to bring the total portfolio delta to zero.
    hedge_threshold: minimum |delta| before placing a hedge trade.
    """
    current_perp_pos = get_pf_perp_position("BTC-USDC")
    # total portfolio delta = options_delta + perp_position
    total_delta = options_net_delta + current_perp_pos

    if abs(total_delta) < hedge_threshold:
        print(f"Delta within threshold ({total_delta:.4f} BTC). No trade.")
        return None

    # required adjustment: -total_delta on perps
    adj_size = abs(total_delta)
    adj_side = "sell" if total_delta > 0 else "buy"
    print(f"Rebalancing: {adj_side} {adj_size:.4f} BTC perp on PF")
    result = place_pf_perp_order("BTC-USDC", adj_side, adj_size)
    print(f"Order result: {result}")
    return result

# Example: options book has net delta of +0.30 BTC
# Agent will sell 0.30 BTC perp on Purple Flea to delta-neutral
rebalance_delta(options_net_delta=0.30, hedge_threshold=0.05)

This loop runs every 15–30 minutes during active markets. The agent's options book accumulates theta (daily income from short options) while the perpetual hedge on Purple Flea ensures the total portfolio remains delta-neutral — capturing volatility premium without directional risk.

Implied Volatility Surface Analysis

The implied volatility (IV) surface maps out the implied volatility of every option in the market across two dimensions: strike (or moneyness) and time to expiry. The shape of this surface contains rich information about market expectations and risk premiums.

Key features of the IV surface

IV surface builder — construct volatility surface from Deribit data Python
import requests, json
from collections import defaultdict

def build_iv_surface(currency="BTC"):
    """
    Build a simplified IV surface: {expiry_date: {strike: iv}}
    Returns a nested dict and a summary of ATM IVs per expiry.
    """
    DERIBIT = "https://www.deribit.com/api/v2"
    spot_resp = requests.get(f"{DERIBIT}/public/get_index_price",
        params={"index_name": f"{currency.lower()}_usd"})
    spot = spot_resp.json()["result"]["index_price"]

    inst_resp = requests.get(f"{DERIBIT}/public/get_instruments",
        params={"currency": currency, "kind": "option", "expired": "false"})
    instruments = inst_resp.json()["result"]

    surface = defaultdict(dict)   # surface[expiry][strike] = iv
    atm_ivs = {}                  # atm_ivs[expiry] = atm_iv

    # Batch fetch using get_book_summary_by_currency
    summary_resp = requests.get(f"{DERIBIT}/public/get_book_summary_by_currency",
        params={"currency": currency, "kind": "option"})
    summaries = summary_resp.json()["result"]

    inst_map = {i["instrument_name"]: i for i in instruments}

    for s in summaries:
        name = s.get("instrument_name", "")
        iv   = s.get("mark_iv", 0.0)
        if iv == 0.0 or name not in inst_map:
            continue
        inst = inst_map[name]
        strike  = inst["strike"]
        expiry  = name.split("-")[1]   # e.g. "28MAR25"
        surface[expiry][strike] = iv

    # Compute ATM IV per expiry (closest strike to spot)
    for expiry, strike_ivs in surface.items():
        atm = min(strike_ivs.keys(), key=lambda k: abs(k - spot))
        atm_ivs[expiry] = strike_ivs[atm]

    # Print term structure
    print("=== IV Term Structure (ATM) ===")
    for exp in sorted(atm_ivs.keys()):
        print(f"  {exp:10s}  ATM IV: {atm_ivs[exp]:.1f}%")

    return surface, atm_ivs

surface, atm_ivs = build_iv_surface("BTC")

Term Structure Trading: Calendar Spreads

A calendar spread exploits differences in the rate of time decay between two options at the same strike but different expiries. The classic calendar spread buys a longer-dated option and sells a shorter-dated option at the same strike — profiting when the front-month option decays faster than the back-month option.

Crypto calendar spread setup

In crypto, the most actionable calendar spread is the volatility term structure play: when near-term IV is temporarily elevated (e.g., due to an upcoming event or fear spike), sell the front-week option and buy the back-month option at the same strike. As the front-week IV reverts to normal after the event passes, the short leg decays rapidly while the long leg retains its value.

Calendar Spread Type When to Use Max Profit Max Loss
Long calendar (buy back, sell front) Near-term IV spike relative to back month Premium differential at convergence Net debit paid
Short calendar (sell back, buy front) Back-month IV elevated; anticipate near-term move Net credit received Potentially unlimited (back-month long gamma)
Diagonal calendar Directional + term structure view combined Strike difference + premium Net debit

Identifying calendar spread opportunities

Calendar spread scanner — find front/back IV divergences Python
def find_calendar_opportunities(surface, atm_ivs,
                                  spread_threshold=8.0):
    """
    Finds expiry pairs where front-month ATM IV is significantly
    higher than back-month ATM IV (long calendar opportunity).
    spread_threshold: minimum front-back IV spread in vol points.
    """
    expiries = sorted(atm_ivs.keys())
    opportunities = []

    for i in range(len(expiries) - 1):
        front = expiries[i]
        back  = expiries[i + 1]
        iv_front = atm_ivs[front]
        iv_back  = atm_ivs[back]
        spread   = iv_front - iv_back

        if spread >= spread_threshold:
            opportunities.append({
                "front_expiry": front,
                "back_expiry":  back,
                "iv_front":     iv_front,
                "iv_back":      iv_back,
                "spread_pts":   spread,
                "type":         "long_calendar",
            })

    opportunities.sort(key=lambda x: -x["spread_pts"])
    for opp in opportunities[:3]:
        print(f"Calendar: sell {opp['front_expiry']} ({opp['iv_front']:.1f}%) / "
              f"buy {opp['back_expiry']} ({opp['iv_back']:.1f}%) — spread {opp['spread_pts']:.1f} vol pts")
    return opportunities

find_calendar_opportunities(surface, atm_ivs, spread_threshold=6.0)

DVOL: Using the Deribit Volatility Index as a Signal

DVOL is Deribit's bitcoin volatility index — the crypto equivalent of the VIX for equities. It measures the 30-day forward-looking implied volatility derived from the BTC options surface and is expressed as an annualized percentage. DVOL is one of the most powerful signals available to an agent running options strategies.

DVOL signal framework

DVOL Level Market Regime Recommended Agent Posture
< 40 Extreme complacency Long vol: buy straddles, long calendar, buy protection
40–55 Normal low-vol regime Theta strategies: covered calls, cash-secured puts
55–75 Moderate volatility Iron condors, selective covered calls with wider strikes
75–100 Elevated fear Reduce short vol exposure; begin buying back short options
> 100 Crisis / capitulation Long vol only; sell puts for cash-secured acquisition if conviction is high
DVOL signal poller — fetch live DVOL and adjust strategy mode JavaScript
const axios = require('axios');

async function getDvol(currency = 'BTC') {
  const resp = await axios.get('https://www.deribit.com/api/v2/public/get_volatility_index_data', {
    params: {
      currency,
      start_timestamp: Date.now() - 300000,  // last 5 minutes
      end_timestamp:   Date.now(),
      resolution:      '60',               // 1-minute candles
    }
  });
  const candles = resp.data.result.data;
  if (!candles.length) return null;
  const latest = candles[candles.length - 1];
  return latest[4]; // close value
}

function getStrategyMode(dvol) {
  if (dvol < 40)  return { mode: 'long_vol',    action: 'Buy straddles / long calendars' };
  if (dvol < 55)  return { mode: 'theta_farm',  action: 'Covered calls + cash-secured puts' };
  if (dvol < 75)  return { mode: 'condor',      action: 'Iron condors + wide strangles' };
  if (dvol < 100) return { mode: 'reduce_short', action: 'Close short vol; switch to delta hedge' };
  return           { mode: 'crisis',       action: 'Long vol only; no naked short options' };
}

async function main() {
  const dvol = await getDvol('BTC');
  const strategy = getStrategyMode(dvol);
  console.log(`BTC DVOL: ${dvol.toFixed(1)}`);
  console.log(`Mode:     ${strategy.mode}`);
  console.log(`Action:   ${strategy.action}`);
  // An agent would pass strategy.mode to its position-sizing and
  // entry-criteria modules to adjust behavior accordingly.
}

main();

Automated Options Strategies: Systematic Covered Calls and Delta Hedging Bots

Systematic options programs are one of the highest-value applications of AI agents in crypto. A well-designed options bot outperforms human traders not because it has better judgment, but because it is consistent — it never skips a roll, never forgets to rebalance delta, never lets theta decay go unmonitored over a weekend.

Architecture of a production options agent

Purple Flea integration: The delta hedge module uses Purple Flea's perpetual trading API at https://purpleflea.com/api/v1/trading/order. With 275 markets and 0.05% maker fee, BTC-USDC is one of the cheapest places to run continuous delta hedging. Funding rates on Purple Flea perps also contribute carry income or cost that the agent factors into its total position P&L calculation.

Automated covered call program — full agent loop

Production covered call agent — weekly cycle with auto-roll Python
import requests, time, logging
from datetime import datetime, timezone

logging.basicConfig(level=logging.INFO,
    format="%(asctime)s %(levelname)s %(message)s")
log = logging.getLogger("covered_call_agent")

DERIBIT    = "https://www.deribit.com/api/v2"
PF_BASE    = "https://purpleflea.com/api/v1"
PF_HEADERS = {"Authorization": "Bearer your_pf_api_key"}

BTC_SPOT_HOLDINGS = 1.0    # agent holds 1 BTC spot
TARGET_DELTA      = 0.25  # sell 25-delta calls
ROLL_TRIGGER      = 0.45  # roll if short call delta exceeds 0.45

def check_existing_short_calls():
    """Return list of active short call positions on Deribit."""
    # (requires Deribit auth — omitted for brevity)
    return []

def should_roll(position):
    g = fetch_option_greeks(position["instrument"])
    return g["delta"] > ROLL_TRIGGER

def run_covered_call_cycle():
    log.info("--- Covered call cycle starting ---")
    spot = get_spot_price()
    log.info(f"BTC spot: ${spot:,.0f}")

    existing = check_existing_short_calls()
    if existing:
        for pos in existing:
            if should_roll(pos):
                log.warning(f"Rolling {pos['instrument']} — delta too high")
                # close existing + open new further-dated call
                # (Deribit order placement omitted — requires auth)
        log.info("Existing short calls checked; no new position needed.")
        return

    # No existing position — find and sell a new call
    instruments = get_btc_instruments()
    best_call   = find_covered_call_strike(instruments, spot,
                    target_delta=TARGET_DELTA, days_out=7)
    if not best_call:
        log.warning("No suitable call found this cycle.")
        return

    ann_yield = best_call["bid"] * (365 / best_call["days"]) * 100
    log.info(f"Selling {best_call['instrument']} | delta={best_call['delta']:.3f} | "
            f"IV={best_call['iv']:.1f}% | annualized={ann_yield:.1f}%")

    # Submit sell order on Deribit (auth + order placement omitted)
    # After sell, rebalance delta on Purple Flea perp
    options_delta = -BTC_SPOT_HOLDINGS * best_call["delta"]
    rebalance_delta(options_net_delta=options_delta)
    log.info("Cycle complete.")

# Run every 4 hours
while True:
    try:
        run_covered_call_cycle()
    except Exception as e:
        log.error(f"Cycle error: {e}")
    time.sleep(4 * 3600)

Fetching Options Chains and Calculating Greeks: JavaScript SDK Example

Not all agents run on Python. The following JavaScript example shows how to fetch a full options chain, filter for tradeable strikes, and compute a custom Black-Scholes delta without relying on the API's pre-computed values — useful for validating data or pricing non-standard instruments.

Options chain fetcher + custom Black-Scholes Greeks in JS JavaScript
const axios = require('axios');

// Cumulative standard normal distribution (Abramowitz & Stegun approximation)
function normCdf(x) {
  const a1 = 0.254829592, a2 = -0.284496736, a3 = 1.421413741;
  const a4 = -1.453152027, a5 = 1.061405429, p = 0.3275911;
  const sign = x < 0 ? -1 : 1;
  x = Math.abs(x);
  const t = 1.0 / (1.0 + p * x);
  const y = 1.0 - (((((a5*t + a4)*t + a3)*t + a2)*t + a1)*t * Math.exp(-x*x));
  return 0.5 * (1.0 + sign * y);
}

function bsGreeks(S, K, T, r, sigma, type = 'call') {
  // S=spot, K=strike, T=years to expiry, r=rate, sigma=IV decimal
  const d1 = (Math.log(S/K) + (r + sigma*sigma/2)*T) / (sigma * Math.sqrt(T));
  const d2 = d1 - sigma * Math.sqrt(T);
  const nd1 = normCdf(d1);
  const phi = Math.exp(-d1*d1/2) / Math.sqrt(2 * Math.PI);
  const delta = type === 'call' ? nd1 : nd1 - 1;
  const gamma = phi / (S * sigma * Math.sqrt(T));
  const theta = (-(S * phi * sigma) / (2 * Math.sqrt(T))
               - r * K * Math.exp(-r*T) * normCdf(type === 'call' ? d2 : -d2)) / 365;
  const vega  = S * phi * Math.sqrt(T) / 100;  // per 1-vol-point
  return { delta, gamma, theta, vega };
}

async function fetchAndAnalyzeChain(currency = 'BTC', targetExpiry = null) {
  const DERIBIT = 'https://www.deribit.com/api/v2';

  const [idxResp, sumResp] = await Promise.all([
    axios.get(`${DERIBIT}/public/get_index_price`,
      { params: { index_name: `${currency.toLowerCase()}_usd` } }),
    axios.get(`${DERIBIT}/public/get_book_summary_by_currency`,
      { params: { currency, kind: 'option' } }),
  ]);

  const spot = idxResp.data.result.index_price;
  const chain = sumResp.data.result;
  const r = 0.05;  // risk-free rate estimate

  const results = chain
    .filter(o => !targetExpiry || o.instrument_name.includes(targetExpiry))
    .filter(o => o.mark_iv > 0 && o.open_interest > 0)
    .map(o => {
      const parts  = o.instrument_name.split('-');
      const strike = parseFloat(parts[2]);
      const type   = parts[3] === 'C' ? 'call' : 'put';
      const T      = (o.creation_timestamp
        ? Math.max(0.001, (o.expiration_timestamp - Date.now()) / (365 * 86400000))
        : 7/365);
      const sigma  = o.mark_iv / 100;
      const g      = bsGreeks(spot, strike, T, r, sigma, type);
      return {
        instrument: o.instrument_name,
        type, strike, T: (T * 365).toFixed(1),
        iv: o.mark_iv.toFixed(1), bid: o.best_bid_price, ask: o.best_ask_price,
        delta:  g.delta.toFixed(4),
        gamma:  g.gamma.toFixed(6),
        theta:  g.theta.toFixed(4),
        vega:   g.vega.toFixed(4),
        oi: o.open_interest,
      };
    });

  // Print top 10 by open interest
  results.sort((a, b) => b.oi - a.oi).slice(0, 10).forEach(r =>
    console.log(JSON.stringify(r, null, 2))
  );
  return results;
}

fetchAndAnalyzeChain('BTC').catch(console.error);

Risk Management: Max Loss, Greeks Limits, and Liquidity Risk

Options positions can experience non-linear losses. A short straddle that appears to collect $500/week in theta can lose $5,000 in a single day if BTC moves 15%. Rigorous risk management is non-negotiable for any agent running options books.

Greeks limits framework

Define hard limits for each Greek at the portfolio level. When any limit is breached, the agent automatically initiates a reduction trade before placing any new positions:

Greek Meaning of Limit Example Limit Breach Action
Net Delta Directional exposure in BTC equivalent ±0.10 BTC Rebalance via PF perp
Net Gamma How quickly delta changes; loss in a fast move -0.005 BTC/$1 Buy back front-month options
Net Theta Daily time decay (income if short, cost if long) Min -$50/day Add short options if theta too negative
Net Vega P&L sensitivity to 1% IV change -$300/vol-pt Reduce short options notional

Liquidity risk in crypto options

The most underappreciated risk in crypto options is liquidity risk — the inability to exit a position at a reasonable price during a market crisis. When BTC drops 20% in an hour, all bid-ask spreads widen catastrophically, put options become nearly untradeable, and the agent may be forced to hold through a loss that would otherwise be manageable.

Risk monitor — check Greeks limits and trigger alerts Python
from dataclasses import dataclass
from typing import List

@dataclass
class RiskLimits:
    max_abs_delta:  float = 0.10    # BTC
    min_gamma:      float = -0.005  # BTC per $1
    min_theta_daily:float = -50.0  # USD per day
    max_abs_vega:   float = 300.0   # USD per 1 vol point

def check_risk_limits(portfolio: PortfolioGreeks,
                      limits: RiskLimits) -> List[str]:
    """Returns a list of breach messages. Empty = within limits."""
    breaches = []

    if abs(portfolio.net_delta) > limits.max_abs_delta:
        breaches.append(
            f"DELTA BREACH: {portfolio.net_delta:.4f} BTC (limit ±{limits.max_abs_delta})")

    if portfolio.net_gamma < limits.min_gamma:
        breaches.append(
            f"GAMMA BREACH: {portfolio.net_gamma:.6f} (limit {limits.min_gamma})")

    if portfolio.net_theta < limits.min_theta_daily:
        breaches.append(
            f"THETA BREACH: ${portfolio.net_theta:.2f}/day (limit ${limits.min_theta_daily})")

    if abs(portfolio.net_vega) > limits.max_abs_vega:
        breaches.append(
            f"VEGA BREACH: ${portfolio.net_vega:.2f}/vol-pt (limit ±${limits.max_abs_vega})")

    return breaches

def risk_monitor_loop(positions_raw, limits=None):
    if limits is None:
        limits = RiskLimits()
    portfolio = build_portfolio_greeks(positions_raw)
    breaches  = check_risk_limits(portfolio, limits)

    if breaches:
        for b in breaches:
            print(f"[RISK ALERT] {b}")
        # Trigger automatic delta rebalance if delta breached
        if any("DELTA" in b for b in breaches):
            rebalance_delta(portfolio.net_delta, hedge_threshold=0.02)
    else:
        print(f"[RISK OK] delta={portfolio.net_delta:.4f} gamma={portfolio.net_gamma:.6f} "
              f"theta=${portfolio.net_theta:.2f}/day vega=${portfolio.net_vega:.2f}/vol-pt")

    return portfolio, breaches

Max Loss Scenarios: Stress Testing Your Options Book

Every agent running a short-options strategy should stress-test its book against historical worst-case crypto moves before committing real capital. The following scenarios represent historically observed extremes:

Scenario BTC Move IV Move Impact on Short Straddle Impact on Iron Condor
March 2020 crash -50% in 48h +80 vol pts -8 to -15x premium Max loss on put wing
Nov 2022 FTX collapse -25% in 72h +40 vol pts -4 to -7x premium Max loss on put wing
Oct 2021 ATH rally +35% in 14d -5 vol pts -5 to -10x premium (call loss) Max loss on call wing
Typical ranging week ±3% ±5 vol pts Full premium captured Full premium captured

Critical sizing rule: Size short options positions so that the max loss scenario (full wing loss on iron condor, or 10x premium loss on a straddle) never exceeds 5% of total portfolio capital in a single expiry cycle. If running multiple expiry cycles simultaneously, ensure non-correlated sizing so a correlated crash does not simultaneously hit all short-gamma positions.

Putting It All Together: A Multi-Strategy Options Agent

A production-grade AI options agent does not run a single strategy — it dynamically allocates across strategies based on market conditions, available capital, and risk budget. The architecture below describes a complete multi-strategy options agent that integrates with both Deribit options and Purple Flea perpetuals:

  1. Boot sequence: Agent registers with Purple Flea (or loads existing API key), claims USDC from the faucet if new, and establishes WebSocket connections to Deribit market data streams.
  2. DVOL read: Fetch DVOL and determine strategy mode (theta farm, condor, long vol). This mode persists until the next hourly DVOL check.
  3. Portfolio scan: Fetch all existing options positions from Deribit, compute portfolio Greeks, check risk limits.
  4. Position management: Roll any positions approaching expiry or strike. Close positions that have captured >70% of max theoretical theta profit (locking in gains early rather than gambling the last 30% against gamma risk).
  5. New position entry: If capital is available and risk limits allow, enter new positions per the active strategy mode.
  6. Delta rebalancing: Calculate net portfolio delta, submit rebalancing order to Purple Flea perp market if delta exceeds ±0.05 BTC. Log the funding rate paid/received.
  7. Sleep: Wait 15 minutes, then repeat from step 2.

Run your options strategies with Purple Flea

Purple Flea provides the perpetual trading backbone for your delta hedging: 275 markets, 0.05% maker fee, live funding rates, and a wallet API for multi-asset collateral management. Register an agent and claim $1 USDC to start.

Register free →

Summary: Crypto Options for AI Agents

Options are one of the most powerful instruments available to AI agents in crypto, precisely because they require the kind of systematic, tireless, multi-dimensional analysis that agents excel at. The key takeaways from this guide:

The agent that runs these strategies systematically — never missing a rebalance, never skipping a roll, always checking DVOL before entry — will outperform a human trader running the same book not because of superior judgment, but because of superior execution consistency. That consistency is the core competitive advantage of AI agents in financial markets.


Related: The Crypto Carry Trade for AI Agents · Perpetual Futures: Complete Agent Guide · Risk Management for Trading Agents · Purple Flea Trading API