Trading Strategy

Options Greeks for
AI Trading Agents

Delta, gamma, theta, vega, rho — the five sensitivities that govern every options position. This guide shows AI agents how to compute, monitor, and act on Greeks automatically, using Purple Flea's 275 perpetual markets as the primary hedging instrument.

March 6, 2026
22 min read
Purple Flea Research
Strategy Guide Tools

The Five Options Greeks

Options Greeks are partial derivatives of an option's price with respect to various market parameters. They form the mathematical backbone of every professional options desk and — increasingly — every autonomous trading agent operating in crypto markets. Unlike spot positions where P&L is straightforward, options expose agents to multiple simultaneous risk dimensions that require continuous monitoring and rebalancing.

For an AI agent running 24/7 across dozens of markets, Greeks are not just academic curiosities — they are the primary control signals. An agent that ignores delta will drift directional without knowing it. One that ignores gamma will be blindsided by convexity at expiration. Theta eats premiums silently overnight. Vega explodes on earnings-equivalent events in crypto. This guide gives agents the tools to handle all five.

Δ
Delta

Rate of change of option price per $1 move in the underlying. Range: −1 to +1.

Γ
Gamma

Rate of change of delta per $1 move. Highest for ATM options near expiration.

Θ
Theta

Daily time decay in option premium. Negative for buyers, positive for sellers.

ν
Vega

Sensitivity to implied volatility. A 1% IV move changes option price by vega.

ρ
Rho

Sensitivity to interest/funding rates. Measurable in crypto via perpetual funding.

Delta (Δ) — Directional Exposure

Delta is the most fundamental Greek. It answers: if the underlying moves $1, how much does my option position change in value? A call option has positive delta (0 to +1); a put has negative delta (−1 to 0). An at-the-money (ATM) option has delta ≈ ±0.50. Deep in-the-money options approach ±1.00; far out-of-the-money options approach 0.

For AI agents, delta translates directly to equivalent spot/perp exposure. A position with +200 delta on BTC-USD acts like holding 200 USD worth of BTC. Delta aggregates across all legs, giving the agent its net directional bet at any moment. The Black-Scholes formula computes call delta as N(d1), where d1 = (ln(S/K) + 0.5σ²T) / (σ√T).

# Black-Scholes greeks: core implementation
import math
from scipy.stats import norm

def d1(S, K, T, r, sigma):
    return (math.log(S / K) + (r + 0.5 * sigma**2) * T) / (sigma * math.sqrt(T))

def d2(S, K, T, r, sigma):
    return d1(S, K, T, r, sigma) - sigma * math.sqrt(T)

def call_delta(S, K, T, r, sigma):
    return norm.cdf(d1(S, K, T, r, sigma))

def put_delta(S, K, T, r, sigma):
    return norm.cdf(d1(S, K, T, r, sigma)) - 1

# Example: BTC ATM call, 7 days to expiry, 80% IV
S, K, T, r, sigma = 65000, 65000, 7/365, 0.0, 0.80
print(f"Call delta: {call_delta(S, K, T, r, sigma):.4f}")  # ~0.5000
print(f"Put delta:  {put_delta(S, K, T, r, sigma):.4f}")   # ~-0.5000
Agent Insight

In crypto markets, agents typically use perpetual funding rates as a proxy for r. On Purple Flea's 275-market perp exchange, funding updates every 8 hours and can swing significantly, making rho-awareness more material than in traditional equities.

Gamma (Γ) — Convexity and Acceleration

Gamma measures how fast delta changes. It is the second derivative of option price with respect to the underlying. High gamma means delta shifts rapidly with price moves — which is both an opportunity (gamma scalping) and a risk (rapid P&L swings near expiry). Gamma is always positive for both calls and puts when long, always negative when short.

ATM short-dated options carry the highest gamma. This is why agents running short-gamma books (selling straddles, iron condors) face outsized danger in the final 24–48 hours before expiration. The formula: Γ = N'(d1) / (S × σ × √T).

def gamma(S, K, T, r, sigma):
    d1_val = d1(S, K, T, r, sigma)
    return norm.pdf(d1_val) / (S * sigma * math.sqrt(T))

# Gamma explodes near expiry — critical for short-gamma agents to monitor
for days in [30, 7, 1, 0.25]:
    T = days / 365
    g = gamma(65000, 65000, T, 0.0, 0.80)
    print(f"{days:5.2f}d to expiry → gamma = {g:.8f}")
# Output shows gamma scaling ~5x from 7d to 1d, ~15x from 7d to 6h

Theta (Θ) — Time Decay

Theta is the daily erosion of option premium assuming all else constant. Long options have negative theta (they lose value over time). Short options have positive theta (premium sellers benefit from time passing). In crypto markets that never close, theta accrues continuously — there is no weekend reprieve. An agent selling weekly BTC straddles collects theta 24/7, which is both the appeal and the trap.

def call_theta(S, K, T, r, sigma):
    d1_val = d1(S, K, T, r, sigma)
    d2_val = d2(S, K, T, r, sigma)
    term1 = -(S * norm.pdf(d1_val) * sigma) / (2 * math.sqrt(T))
    term2 = -r * K * math.exp(-r * T) * norm.cdf(d2_val)
    return (term1 + term2) / 365  # convert to daily theta

def put_theta(S, K, T, r, sigma):
    d1_val = d1(S, K, T, r, sigma)
    d2_val = d2(S, K, T, r, sigma)
    term1 = -(S * norm.pdf(d1_val) * sigma) / (2 * math.sqrt(T))
    term2 = +r * K * math.exp(-r * T) * norm.cdf(-d2_val)
    return (term1 + term2) / 365

# ATM 7-day call at 80% IV: daily theta per contract
theta_daily = call_theta(65000, 65000, 7/365, 0.0, 0.80)
print(f"Daily theta: ${theta_daily:.2f}")  # approximately -$350 per contract

Vega (ν) — Volatility Sensitivity

Vega measures how much an option's price changes for a 1% change in implied volatility. Vega is positive for both calls and puts when long. It is highest for longer-dated, ATM options. In crypto, where IV can swing from 50% to 200% in a single day, vega is often the dominant risk factor — dwarfing delta on event-driven moves like ETF approvals or exchange hacks.

def vega(S, K, T, r, sigma):
    d1_val = d1(S, K, T, r, sigma)
    return S * norm.pdf(d1_val) * math.sqrt(T) / 100  # per 1% IV move

# Longer-dated options have significantly more vega exposure
for days in [7, 30, 90]:
    T = days / 365
    v = vega(65000, 65000, T, 0.0, 0.80)
    print(f"{days:3d}d vega = ${v:.2f} per 1% IV move")
# 7d:  ~$62   | 30d: ~$128  | 90d: ~$221

Rho (ρ) — Rate Sensitivity

Rho measures sensitivity to interest rates (or in crypto, perpetual funding rates). For short-dated options it is typically the least important Greek, but on perpetuals where funding can reach ±0.1% per 8 hours (annualized ±109%), rho-equivalent exposures become material for large deep-ITM positions. Agents should substitute annualized perpetual funding for r in the Black-Scholes formula.

def call_rho(S, K, T, r, sigma):
    d2_val = d2(S, K, T, r, sigma)
    return K * T * math.exp(-r * T) * norm.cdf(d2_val) / 100

def put_rho(S, K, T, r, sigma):
    d2_val = d2(S, K, T, r, sigma)
    return -K * T * math.exp(-r * T) * norm.cdf(-d2_val) / 100

# Crypto: annualize perpetual 8h funding as interest rate proxy
funding_8h = 0.0005           # 0.05% per 8h — positive funding environment
annualized_r = funding_8h * 3 * 365  # ~54.75% annualized
rho_val = call_rho(65000, 65000, 30/365, annualized_r, 0.80)
print(f"Call rho (crypto-adjusted): ${rho_val:.4f}")

How AI Agents Use Greeks to Manage Options Risk

A human trader might glance at their greek dashboard once an hour. An AI agent running on Purple Flea's infrastructure checks Greeks every few seconds and acts within milliseconds. The workflow is a continuous loop:

  1. Fetch positions — retrieve all open options legs and perpetual hedges.
  2. Compute portfolio Greeks — sum deltas, gammas, thetas, vegas across all legs.
  3. Compare to limits — check each Greek against configured thresholds.
  4. Generate hedge orders — compute the perp size needed to neutralize out-of-bounds Greeks.
  5. Execute and confirm — place orders via the Purple Flea REST/WebSocket API, await fills.
  6. Log and sleep — record state, sleep for the configured interval (e.g., 30 seconds).

This loop runs independently of the strategy layer. The strategy decides what positions to hold; the Greek monitor decides how to hedge them. Separating these concerns is critical for agent reliability — a bug in one should not cascade to the other.

Purple Flea Advantage

With 275 perpetual markets and up to 50x leverage, agents can hedge delta exposures in virtually any crypto market without needing to find a matching options liquidity pool. The perp becomes the universal hedging tool across the entire Greek management stack.

Delta-Neutral Hedging with Perpetual Swaps

Delta-neutral hedging is the practice of offsetting directional exposure so that small moves in the underlying do not affect portfolio value. The goal is to isolate pure volatility, time decay, or spread P&L — whatever edge the agent is actually trying to capture — without being exposed to random directional drift.

The Hedge Calculation

Given a portfolio delta of +ΔP, the agent needs to short ΔP units of the underlying perpetual to reach zero net delta. In practice, agents maintain a tolerance band (e.g., ±0.05 delta) to avoid constant small rebalances that erode profits through fees.

delta_hedger.py Python
import requests
import time
from dataclasses import dataclass
from typing import List

BASE_URL = "https://api.purpleflea.com/v1"
API_KEY  = "pf_live_your_key_here"
HEADERS  = {"Authorization": f"Bearer {API_KEY}"}

@dataclass
class OptionLeg:
    symbol: str
    strike: float
    expiry_days: float
    option_type: str   # 'call' or 'put'
    size: float          # positive = long, negative = short
    iv: float            # implied volatility (decimal, e.g. 0.80)

class DeltaHedger:
    def __init__(self, symbol: str, tolerance: float = 0.05):
        self.symbol = symbol         # e.g. "BTC-USD"
        self.tolerance = tolerance   # delta tolerance band before rebalancing

    def get_spot_price(self) -> float:
        r = requests.get(f"{BASE_URL}/markets/{self.symbol}/ticker", headers=HEADERS)
        return r.json()["mark_price"]

    def portfolio_delta(self, legs: List[OptionLeg], S: float) -> float:
        total_delta = 0.0
        for leg in legs:
            T = leg.expiry_days / 365
            if leg.option_type == "call":
                d = call_delta(S, leg.strike, T, 0.0, leg.iv)
            else:
                d = put_delta(S, leg.strike, T, 0.0, leg.iv)
            total_delta += d * leg.size
        return total_delta

    def get_perp_position(self) -> float:
        r = requests.get(
            f"{BASE_URL}/positions/{self.symbol}-PERP",
            headers=HEADERS
        )
        data = r.json()
        return data.get("size", 0.0)  # positive=long, negative=short (base units)

    def place_hedge_order(self, delta_to_hedge: float, S: float):
        size_in_base = delta_to_hedge / S
        side = "sell" if size_in_base > 0 else "buy"
        abs_size = abs(size_in_base)
        payload = {
            "symbol": f"{self.symbol}-PERP",
            "side": side, "size": f"{abs_size:.6f}",
            "type": "market", "reduce_only": False
        }
        r = requests.post(f"{BASE_URL}/orders", json=payload, headers=HEADERS)
        print(f"[HEDGE] {side} {abs_size:.4f} {self.symbol}-PERP | HTTP {r.status_code}")
        return r.json()

    def run_loop(self, legs: List[OptionLeg], interval: int = 30):
        print(f"[HEDGER] Starting delta-neutral loop for {self.symbol}")
        while True:
            S = self.get_spot_price()
            port_delta = self.portfolio_delta(legs, S)
            perp_pos   = self.get_perp_position()
            perp_delta_usd = perp_pos * S
            net_delta  = port_delta + perp_delta_usd

            print(f"[HEDGER] S={S:.0f} | options_D={port_delta:.3f} | perp_D={perp_delta_usd:.3f} | net={net_delta:.3f}")

            if abs(net_delta) > self.tolerance * S:
                self.place_hedge_order(net_delta, S)
            time.sleep(interval)

Rebalancing Costs vs. Frequency

Every hedge order incurs trading fees. On Purple Flea, maker/taker fees are competitive, but frequent small rebalances will erode theta gains. Use a bandwidth hedge: only rebalance when delta drifts beyond ±N% of position size. Tune N based on IV level.

IV Level Recommended Band Rebalance Frequency Fee Impact
Low (<40%)±0.05 deltaEvery 2–4 hoursLow
Medium (40–80%)±0.10 deltaEvery 30–60 minMedium
High (80–150%)±0.15 deltaEvery 10–20 minElevated
Extreme (>150%)±0.20 deltaEvery 5 min maxCritical — cap order size

Gamma Scalping Algorithms

Gamma scalping is the strategy of buying long options (positive gamma) and continuously rebalancing delta to lock in profits from realized volatility moves. When the underlying moves up, delta increases (because you're long gamma); you sell the perp. When the underlying moves down, delta decreases; you buy the perp. Each round-trip captures the realized move as P&L.

The P&L of a gamma scalp is approximately: P&L ≈ 0.5 × Γ × (ΔS)² − Θ × Δt. You profit if realized volatility exceeds implied volatility. You lose if the market sits still and theta bleeds you dry.

gamma_scalper.py Python
class GammaScalper:
    """
    Long ATM straddle + continuous delta rebalancing.
    Profits when realized vol > implied vol.
    Rebalances on price movement, not fixed intervals.
    """
    def __init__(self, symbol, strike, expiry_days, iv, contracts):
        self.symbol    = symbol
        self.K         = strike
        self.T0        = expiry_days / 365
        self.iv        = iv
        self.contracts = contracts
        self.S_prev    = None
        self.hedge_pnl = 0.0
        self.num_rebalances = 0

    def gamma_pnl_estimate(self, S_now, S_prev, T):
        G = gamma(S_now, self.K, T, 0.0, self.iv)
        dS = S_now - S_prev
        return 0.5 * G * (dS ** 2) * self.contracts

    def straddle_delta(self, S, T):
        cd = call_delta(S, self.K, T, 0.0, self.iv)
        pd = put_delta(S, self.K, T, 0.0, self.iv)
        return (cd + pd) * self.contracts  # near-zero for ATM straddle

    def capture_threshold(self, S, T, fee_usd=20) -> bool:
        # Only rebalance if expected gamma capture exceeds round-trip fee
        G = gamma(S, self.K, T, 0.0, self.iv)
        expected = 0.5 * G * (S * 0.003) ** 2  # 0.3% move estimate
        return expected > fee_usd

    def run(self, hedger: DeltaHedger, duration_hours=24):
        import datetime
        end = datetime.datetime.utcnow() + datetime.timedelta(hours=duration_hours)
        elapsed = 0
        while datetime.datetime.utcnow() < end:
            S = hedger.get_spot_price()
            T = max(self.T0 - elapsed/365, 0.001)
            if self.S_prev is not None:
                g_pnl = self.gamma_pnl_estimate(S, self.S_prev, T)
                t_cost = call_theta(S, self.K, T, 0.0, self.iv) * self.contracts * (30/86400)
                net = g_pnl + t_cost
                self.hedge_pnl += net
                print(f"S={S:.0f} | gammaP={g_pnl:.2f} | thetaCost={t_cost:.2f} | net={net:.2f} | total={self.hedge_pnl:.2f}")
            straddle_d = self.straddle_delta(S, T)
            perp_pos   = hedger.get_perp_position()
            net_delta  = straddle_d + perp_pos * S
            if abs(net_delta) > 0.08 * S and self.capture_threshold(S, T):
                hedger.place_hedge_order(net_delta, S)
                self.num_rebalances += 1
            self.S_prev = S
            elapsed += 30 / 86400
            time.sleep(30)
        print(f"Done: {self.num_rebalances} rebalances, PnL=${self.hedge_pnl:.2f}")
Gamma Scalping Risk

Gamma scalping requires realized volatility to consistently exceed implied vol paid at entry. In crypto, this often holds — but during low-vol consolidation periods typical of bear-market bases, agents can bleed theta for weeks before a catalytic move arrives. Always monitor the IV/RV spread before initiating a gamma-long position.

Theta Decay Exploitation (Selling Premium)

The inverse of gamma scalping is theta farming: selling options to collect time decay. The agent is short gamma (net negative), which means it suffers on large moves, but earns steady theta income when the market stays range-bound. This is the approach behind iron condors, covered strangles, and calendar spreads.

The critical metric is the theta-to-vega ratio. An agent selling weekly BTC straddles earns theta rapidly, but carries vega risk. Monitoring this ratio tells the agent whether it is being adequately compensated for its volatility exposure.

theta_farmer.py Python
class ThetaFarmer:
    """
    Sells weekly ATM straddles when IV is elevated.
    Collects theta; closes at 70% time elapsed to avoid gamma risk.
    """
    IV_ENTRY_MIN   = 0.60   # only sell premium when IV > 60%
    THETA_VEGA_MIN = 0.12   # minimum theta/vega ratio for entry
    MAX_GAMMA_RISK = 2000   # max USD loss on a 2-sigma daily move

    def __init__(self, symbol, budget_usd):
        self.symbol = symbol
        self.budget = budget_usd

    def evaluate_entry(self, S, iv, days) -> dict:
        T = days / 365
        if iv < self.IV_ENTRY_MIN:
            return {"enter": False, "reason": "IV below minimum"}
        th = abs(call_theta(S, S, T, 0.0, iv))
        ve = vega(S, S, T, 0.0, iv)
        tv_ratio = th / ve if ve > 0 else 0
        if tv_ratio < self.THETA_VEGA_MIN:
            return {"enter": False, "reason": f"theta/vega {tv_ratio:.3f} too low"}
        sigma_1d = iv / math.sqrt(365)
        two_sigma = 2 * sigma_1d * S
        G = gamma(S, S, T, 0.0, iv)
        gamma_loss_1c = 0.5 * G * two_sigma ** 2
        max_contracts = int(self.MAX_GAMMA_RISK / gamma_loss_1c) if gamma_loss_1c > 0 else 10
        weekly_theta = th * 7 * max_contracts
        return {
            "enter": True, "contracts": max_contracts,
            "weekly_theta_usd": weekly_theta,
            "theta_vega_ratio": tv_ratio,
            "gamma_2sigma_risk": gamma_loss_1c * max_contracts
        }

    def exit_rule(self, entry_iv, current_iv, days_elapsed, days_total) -> str:
        if current_iv > entry_iv * 1.30:
            return "EXIT_VEGA_SPIKE"      # IV spiked 30% — cut vega risk
        if days_elapsed / days_total > 0.70:
            return "EXIT_GAMMA_RISK"     # final 30% of life = gamma danger zone
        return "HOLD"

The Theta Decay Curve

Theta does not decay linearly. It accelerates as expiration approaches. For weekly options, roughly 50% of total theta is collected in the final two days. This means agents selling weekly options should plan their exit around 70% of the expiration window — capturing rich late-week theta while avoiding the gamma danger zone near expiry.

Vega Trading — Volatility Arbitrage

Vega trading (vol arb) involves positions based on the spread between implied volatility (what the market prices) and realized volatility (what actually happened). If BTC 30-day IV is 90% but realized vol over the past 30 days was 60%, IV is "rich" — a signal to sell premium. The reverse signals buying cheap vol.

vega_arb.py Python
import numpy as np
from collections import deque

class VegaArbAgent:
    """
    Monitors the IV - RV spread and signals long/short vol when statistically extreme.
    RV is computed from Purple Flea OHLCV data (hourly candles).
    """
    def __init__(self, symbol, lookback_days=30, z_threshold=1.5):
        self.symbol      = symbol
        self.lookback    = lookback_days
        self.z_threshold = z_threshold
        self.spread_history = deque(maxlen=lookback_days)

    def fetch_hourly_closes(self, n=720) -> list:
        r = requests.get(
            f"{BASE_URL}/candles/{self.symbol}-PERP",
            params={"interval": "1h", "limit": n},
            headers=HEADERS
        )
        return [c["close"] for c in r.json()["candles"]]

    def realized_vol(self, prices: list) -> float:
        log_ret = np.diff(np.log(prices))
        daily_vol = np.std(log_ret) * np.sqrt(24)  # hourly → daily
        return daily_vol * np.sqrt(365)              # daily → annualized

    def get_atm_iv(self, expiry="7d") -> float:
        r = requests.get(
            f"{BASE_URL}/options/{self.symbol}/atm_iv",
            params={"expiry": expiry}, headers=HEADERS
        )
        return r.json()["iv"]

    def vol_signal(self) -> dict:
        prices = self.fetch_hourly_closes()
        rv = self.realized_vol(prices)
        iv = self.get_atm_iv()
        spread = iv - rv
        self.spread_history.append(spread)
        if len(self.spread_history) < 5:
            return {"signal": "INSUFFICIENT_DATA"}
        mu = np.mean(self.spread_history)
        sigma = np.std(self.spread_history)
        z = (spread - mu) / sigma if sigma > 0 else 0
        signal = ("SELL_VOL" if z > self.z_threshold else
                  "BUY_VOL"  if z < -self.z_threshold else "NEUTRAL")
        return {"iv": iv, "rv": rv, "spread": spread, "z": z, "signal": signal}

    def run(self, interval=3600):  # check hourly
        while True:
            sig = self.vol_signal()
            print(f"[VEGA-ARB] IV={sig.get('iv', 0):.1%} RV={sig.get('rv', 0):.1%} "
                  f"spread={sig.get('spread', 0):.1%} z={sig.get('z', 0):.2f} → {sig['signal']}")
            time.sleep(interval)
Volatility Regime Awareness

Crypto volatility is highly regime-dependent. In trending bull markets, realized vol exceeds IV more frequently (momentum creates outsized moves). In ranging markets, IV typically trades rich. Agents should maintain a rolling 30-day IV/RV spread tracker and weight their premium-selling vs. gamma-buying bias by regime.

Full Python Agent: Greeks Monitor

The following is a production-ready Greek tracking agent that continuously monitors a multi-leg options portfolio, computes all five Greeks, checks against configured limits, and auto-hedges when thresholds are breached. Designed to run as a standalone process under PM2 or systemd.

greeks_monitor.py Python
"""
Purple Flea — Greeks Monitor Agent
Tracks delta, gamma, theta, vega for a multi-leg options portfolio.
Auto-hedges via the Purple Flea perpetual API when limits are breached.
"""
import math, time, logging
import requests
from scipy.stats import norm
from dataclasses import dataclass
from typing import List

logging.basicConfig(level=logging.INFO, format='%(asctime)s [%(levelname)s] %(message)s')
log = logging.getLogger("greeks-monitor")

BASE_URL = "https://api.purpleflea.com/v1"
API_KEY  = "pf_live_your_key_here"
HEADERS  = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}

@dataclass
class Greeks:
    delta: float = 0.0
    gamma: float = 0.0
    theta: float = 0.0
    vega:  float = 0.0
    rho:   float = 0.0

    def __add__(self, other):
        return Greeks(self.delta+other.delta, self.gamma+other.gamma,
                      self.theta+other.theta, self.vega+other.vega, self.rho+other.rho)

    def __repr__(self):
        return f"D={self.delta:+.4f} G={self.gamma:.6f} Th={self.theta:+.2f}/d V={self.vega:.2f}/1% R={self.rho:.4f}"

@dataclass
class GreekLimits:
    max_delta: float = 0.20    # net delta before auto-hedge
    min_theta: float = -500    # max daily theta bleed (USD)
    max_vega:  float = 2000    # max vega per 1% IV move (USD)

@dataclass
class OptionPosition:
    strike:      float
    expiry_days: float
    option_type: str    # 'call' or 'put'
    size:        float  # positive=long, negative=short
    iv:          float

def compute_greeks(S, K, T, iv, size, otype) -> Greeks:
    if T <= 0: return Greeks()
    d1_v = (math.log(S/K) + 0.5*iv**2*T) / (iv*math.sqrt(T))
    d2_v = d1_v - iv*math.sqrt(T)
    Npd1 = norm.pdf(d1_v); Ncd1 = norm.cdf(d1_v); Ncd2 = norm.cdf(d2_v)
    delta_v = Ncd1 if otype == "call" else Ncd1 - 1
    gamma_v = Npd1 / (S * iv * math.sqrt(T))
    theta_v = (-(S * Npd1 * iv) / (2 * math.sqrt(T))) / 365
    vega_v  = S * Npd1 * math.sqrt(T) / 100
    rho_v   = K * T * (Ncd2 if otype == "call" else (Ncd2-1)) / 100
    return Greeks(delta_v*size, gamma_v*size, theta_v*size, vega_v*size, rho_v*size)

class GreeksMonitor:
    def __init__(self, positions: List[OptionPosition], limits: GreekLimits):
        self.positions  = positions
        self.limits     = limits
        self.hedge_count = 0

    def fetch_price(self, symbol="BTC-USD") -> float:
        r = requests.get(f"{BASE_URL}/markets/{symbol}/ticker", headers=HEADERS, timeout=5)
        return r.json()["mark_price"]

    def portfolio_greeks(self, S: float) -> Greeks:
        total = Greeks()
        for p in self.positions:
            total = total + compute_greeks(S, p.strike, p.expiry_days/365, p.iv, p.size, p.option_type)
        return total

    def hedge_delta(self, g: Greeks, S: float):
        size = abs(g.delta) / S
        side = "buy" if g.delta < 0 else "sell"
        payload = {"symbol": "BTC-USD-PERP", "side": side, "size": f"{size:.6f}", "type": "market"}
        r = requests.post(f"{BASE_URL}/orders", json=payload, headers=HEADERS)
        log.info(f"DELTA_HEDGE: {side} {size:.4f} BTC-PERP → {r.status_code}")
        self.hedge_count += 1

    def run(self, interval=60):
        log.info(f"Greeks Monitor: {len(self.positions)} positions")
        while True:
            try:
                S = self.fetch_price()
                g = self.portfolio_greeks(S)
                log.info(f"S={S:.0f} | {g}")
                if abs(g.delta) > self.limits.max_delta: self.hedge_delta(g, S)
                if g.theta  < self.limits.min_theta:   log.warning(f"THETA ALERT: {g.theta:.2f}")
                if abs(g.vega) > self.limits.max_vega:  log.warning(f"VEGA ALERT:  {g.vega:.2f}")
            except Exception as e:
                log.error(f"Loop error: {e}")
            time.sleep(interval)

if __name__ == "__main__":
    positions = [
        OptionPosition(65000, 7, "call", +5, 0.80),  # long 5 ATM calls
        OptionPosition(65000, 7, "put",  +5, 0.80),  # long 5 ATM puts (straddle)
        OptionPosition(70000, 7, "call", -3, 0.72),  # short 3 OTM calls (wing)
    ]
    limits  = GreekLimits(max_delta=0.15, max_vega=1500, min_theta=-400)
    monitor = GreeksMonitor(positions, limits)
    monitor.run(interval=30)

Greek Exposure Limits and Auto-Hedging Triggers

Defining Greek limits is both a science and an art. Too tight and the agent churns fees constantly. Too loose and a single event wipes the portfolio. The following framework provides a starting point for a $50,000 options portfolio on BTC:

Greek Soft Limit (Alert) Hard Limit (Auto-Hedge) Hedge Action
Delta ±0.10 ±0.20 Market order perp to neutralize
Gamma Short > 0.0005 Short > 0.001 Buy ATM options to reduce short gamma
Theta < −$300/day < −$500/day Roll long-dated options or reduce position
Vega > $1,500/1% > $2,500/1% Sell OTM options to reduce net vega
Rho Monitor only N/A Adjust funding hedge if extreme

Cascading Hedge Priority

Apply hedges in priority order: delta first (cheapest, most liquid), then gamma (requires buying options), then vega (sell OTM options). Never hedge gamma and vega simultaneously in opposite directions — this creates internal conflicts that amplify rather than reduce risk. The agent should solve: minimize hedge cost subject to bringing all Greeks within limits simultaneously.

Emergency Circuit Breaker

Every Greek monitor must implement an emergency halt: if portfolio delta exceeds ±0.50 or vega exceeds $5,000 per 1% move, immediately flatten all positions (market orders) and alert operators. In crypto, extreme moves during low-liquidity windows can create exponential Greek exposures faster than a 30-second polling loop can respond.

Multi-Leg Strategies: Straddles, Iron Condors, Butterflies

Multi-leg options strategies are combinations of calls and puts at different strikes and/or expiries, each designed to target a specific Greek profile. Understanding the aggregate Greek signature of each strategy tells an agent what it is actually betting on.

Long Straddle

Buy ATM call + ATM put at the same strike and expiry. Profits from large moves in either direction.

Delta ~0 +Gamma −Theta +Vega

Short Strangle

Sell OTM call + OTM put. Profits if price stays between strikes through expiry.

Delta ~0 −Gamma +Theta −Vega

Iron Condor

Sell OTM call spread + OTM put spread. Defined risk, defined reward theta strategy.

Delta ~0 −Gamma (capped) +Theta −Vega (capped)

Long Butterfly

Buy 1 ITM call, sell 2 ATM calls, buy 1 OTM call. Profits near the center strike at expiry.

Delta ~0 −Gamma (center) +Theta Low Vega

Calendar Spread

Sell near-dated ATM option, buy far-dated ATM option. Captures theta differential and IV term structure.

Delta ~0 +Gamma (far) +Theta (net) +Vega (far > near)

Risk Reversal

Buy OTM call, sell OTM put (or reverse). Directional bet with reduced premium cost.

+Delta Gamma ~0 Theta (varies) Vega (skew play)
multi_leg_greeks.py Python
def iron_condor_greeks(S, K_pl, K_ps, K_cs, K_cl, T, iv, size=1) -> Greeks:
    """
    Iron condor:
      +1 put  at K_pl  (lower wing — long)
      -1 put  at K_ps  (upper put short — income)
      -1 call at K_cs  (lower call short — income)
      +1 call at K_cl  (upper wing — long)
    """
    legs = [
        ("put",  K_pl, +size), ("put",  K_ps, -size),
        ("call", K_cs, -size), ("call", K_cl, +size),
    ]
    total = Greeks()
    for otype, K, qty in legs:
        total = total + compute_greeks(S, K, T, iv, qty, otype)
    return total

def butterfly_greeks(S, K_low, K_mid, K_high, T, iv, size=1) -> Greeks:
    """Long call butterfly: +1 ITM, -2 ATM, +1 OTM"""
    legs = [
        ("call", K_low,  +size),
        ("call", K_mid,  -2*size),
        ("call", K_high, +size),
    ]
    total = Greeks()
    for otype, K, qty in legs:
        total = total + compute_greeks(S, K, T, iv, qty, otype)
    return total

# Example: BTC Iron Condor at 65k, $3k wide wings
S = 65000
condor = iron_condor_greeks(S, 59000, 62000, 68000, 71000, 7/365, 0.75, size=2)
print(f"Iron Condor: {condor}")
# Expected: delta ~0, negative gamma, positive theta, negative vega

fly = butterfly_greeks(S, 62000, 65000, 68000, 7/365, 0.75, size=3)
print(f"Butterfly:   {fly}")

Backtesting Greeks Strategies

Backtesting a Greeks-based strategy requires historical options data (or simulation from historical spot prices and IV surfaces), realistic transaction costs, and proper fill assumptions. The following framework simulates weekly straddle-selling over historical BTC data fetched from Purple Flea's OHLCV endpoint.

backtest_theta.py Python
import pandas as pd
import numpy as np

def fetch_daily_closes(symbol, days=365) -> pd.Series:
    r = requests.get(
        f"{BASE_URL}/candles/{symbol}-PERP",
        params={"interval": "1d", "limit": days},
        headers=HEADERS
    )
    df = pd.DataFrame(r.json()["candles"])
    df["ts"] = pd.to_datetime(df["timestamp"], unit="ms")
    return df.set_index("ts")["close"].astype(float)

def proxy_iv(prices: pd.Series, window=30) -> pd.Series:
    log_ret = np.log(prices / prices.shift(1))
    rv = log_ret.rolling(window).std() * np.sqrt(365)
    return rv * 1.15  # IV typically trades ~15% above RV in crypto

def bs_straddle_price(S, K, T, iv):
    """Call + put at same strike (straddle mid price)"""
    d1_v = (math.log(S/K) + 0.5*iv**2*T) / (iv*math.sqrt(T))
    d2_v = d1_v - iv*math.sqrt(T)
    call = S*norm.cdf(d1_v) - K*norm.cdf(d2_v)
    put  = call - S + K
    return call + put

def backtest_weekly_straddle_sell(symbol="BTC-USD", fee_rate=0.0005):
    prices = fetch_daily_closes(symbol, days=365)
    ivs    = proxy_iv(prices)
    results = []
    idx = prices.index

    for i in range(35, len(idx)-7, 7):
        S_entry = prices.iloc[i]
        S_exit  = prices.iloc[i+5]
        iv = ivs.iloc[i]
        if pd.isna(iv) or iv < 0.40: continue
        premium_in  = bs_straddle_price(S_entry, S_entry, 7/365, iv)
        premium_out = bs_straddle_price(S_exit,  S_entry, 2/365, iv*1.05)
        raw = premium_in - premium_out
        fees = (premium_in + premium_out) * fee_rate * 2
        results.append({
            "date": idx[i], "S_entry": S_entry, "S_exit": S_exit,
            "iv": iv, "pnl": raw - fees, "win": raw > fees
        })

    df = pd.DataFrame(results)
    df["cumulative"] = df["pnl"].cumsum()
    sharpe = df["pnl"].mean() / df["pnl"].std() * np.sqrt(52)
    print(f"Weeks tested:   {len(df)}")
    print(f"Win rate:       {df['win'].mean():.1%}")
    print(f"Avg weekly PnL: ${df['pnl'].mean():.2f}")
    print(f"Cumulative PnL: ${df['cumulative'].iloc[-1]:.2f}")
    print(f"Sharpe ratio:   {sharpe:.2f}")
    return df

Key Backtesting Lessons

  • IV premium bias: Historically, BTC implied vol has exceeded realized vol approximately 60–65% of the time, providing a structural edge for premium sellers.
  • Event clustering: Losses cluster around macro events (FOMC, ETF approvals, exchange incidents). A regime filter that pauses premium selling during high-uncertainty windows significantly improves drawdown profiles.
  • Fee compounding: At 0.05% per side on Purple Flea, aggressive rebalancing can consume 3–4% of portfolio in fees per week. Calibrate bandwidth carefully.
  • Dynamic Greeks: Always re-compute Greeks at each simulation time step, not just at entry. Delta on a 7-day option changes dramatically from Monday to Friday.
  • Slippage: For large positions in smaller markets, model 0.1–0.5% slippage on market orders. Low-liquidity windows can gap against you significantly.

Purple Flea Trading API — Integration Guide

Purple Flea provides the perpetual infrastructure that underpins all the hedging strategies in this guide. With 275 perpetual markets, up to 50x leverage, and a real-time REST plus WebSocket API, it is purpose-built for automated Greek hedging agents.

Why Perpetuals for Greek Hedging?

Perpetual swaps are the ideal instrument for options Greeks because they have no expiry, no contango, and near-zero basis in liquid markets. An agent can hold a short perp indefinitely to neutralize long-delta options exposure without rolling costs. Register at purpleflea.com/register to get your API key and start hedging.

Quick Start: Register and Place a Hedge Order

import requests

# Step 1: Register your agent (one-time setup)
r = requests.post("https://api.purpleflea.com/v1/agents/register", json={
    "name":     "greeks-monitor-v1",
    "type":     "options-hedger",
    "strategy": "delta-neutral"
})
api_key = r.json()["api_key"]
HEADERS = {"Authorization": f"Bearer {api_key}"}

# Step 2: Browse available markets (275 perpetuals)
markets = requests.get("https://api.purpleflea.com/v1/markets", headers=HEADERS).json()
btc = next(m for m in markets if m["symbol"] == "BTC-USD-PERP")
print(f"BTC-PERP mark price: ${btc['mark_price']:,.2f}")
print(f"Max leverage: {btc['max_leverage']}x")

# Step 3: Place a delta hedge order
order = requests.post("https://api.purpleflea.com/v1/orders", headers=HEADERS, json={
    "symbol": "BTC-USD-PERP", "side": "sell",
    "size": "0.1", "type": "market"
}).json()
print(f"Order: {order['order_id']} | status: {order['status']}")

# Step 4: Monitor positions
positions = requests.get("https://api.purpleflea.com/v1/positions", headers=HEADERS).json()
for p in positions.get("positions", []):
    print(f"{p['symbol']}: size={p['size']} entry={p['entry_price']} unrealizedPnL=${p['unrealized_pnl']:.2f}")

WebSocket for Sub-Second Greek Monitoring

import asyncio, websockets, json

async def realtime_greek_monitor(api_key, monitor):
    """
    Subscribe to live price ticks via WebSocket.
    Re-compute and check Greeks on every price update.
    Significantly faster than polling — essential for gamma scalping agents.
    """
    uri = "wss://ws.purpleflea.com/v1/markets/BTC-USD-PERP/ticker"
    extra = {"Authorization": f"Bearer {api_key}"}
    async with websockets.connect(uri, extra_headers=extra) as ws:
        await ws.send(json.dumps({"op": "subscribe", "channel": "ticker"}))
        async for raw in ws:
            tick = json.loads(raw)
            S = tick.get("mark_price")
            if not S: continue
            g = monitor.portfolio_greeks(S)
            if abs(g.delta) > 0.20:
                print(f"[WS] DELTA BREACH: {g.delta:+.4f} @ S={S:.0f} — hedging")
                monitor.hedge_delta(g, S)

asyncio.run(realtime_greek_monitor("pf_live_your_key_here", monitor))
Ready to Deploy Your Greek Agent?

Start with a free account registration to receive your API key. Review the full endpoint reference in the Trading API docs. New agents can claim a small starting balance from the Agent Faucet to test strategies at zero risk before deploying capital.

Summary: Greek Management Principles for AI Agents

Options Greeks are the language that converts raw options positions into quantified, actionable risk signals. Mastering Greek computation and automated hedging gives an AI agent a decisive edge in any options strategy:

  • Delta — Always know your directional exposure; hedge with perps when it drifts beyond tolerance.
  • Gamma — Buy gamma (long straddles) when realized vol exceeds IV; sell gamma (iron condors) when IV is rich.
  • Theta — Time decay favors short-option agents; close at 70% of expiry to avoid gamma danger.
  • Vega — The dominant risk in crypto; track IV/RV spread continuously and avoid large net vega around major events.
  • Rho — Monitor perpetual funding rates as a crypto-native rho proxy; relevant for large deep-ITM positions.

With Purple Flea's 275 perpetual markets providing the hedging backbone, AI agents can implement institutional-grade Greek management at a fraction of traditional infrastructure cost — running autonomously, 24/7, across the full crypto options universe.