Options Trading

AI Agent Options Strategies: Selling Premium and Managing Greeks

Options trading is one of the most powerful income strategies available to AI agents. When implemented correctly, systematic premium selling generates consistent returns regardless of market direction. This guide covers everything from Black-Scholes pricing to managing a live iron condor portfolio with Python.

45% Avg Theta decay captured
4 Core Greek exposures
0.30 Target delta for CSPs

Options Fundamentals for AI Agents

An options contract gives the buyer the right, but not the obligation, to buy (call) or sell (put) an underlying asset at a specified strike price before expiration. For AI agents, options provide two key advantages over spot trading: defined risk profiles and the ability to extract time value from the market.

The core insight driving premium-selling strategies is that options are systematically overpriced. Implied volatility (IV) consistently exceeds realized volatility over time, meaning that options sellers, on average, collect more premium than the underlying moves justify. This is the volatility risk premium — and it is one of the most robust anomalies in financial markets.

Why Agents Excel at Options Trading

Human options traders are limited by cognitive bandwidth — tracking multiple positions, Greeks, and expirations simultaneously is mentally exhausting. AI agents have no such constraint. A well-architected agent can:

  • Monitor Greeks across hundreds of positions in real-time
  • Execute delta-hedges within milliseconds of threshold breaches
  • Calculate optimal strike selection based on current IV rank and skew
  • Roll positions automatically when profit targets or loss limits are hit
  • Maintain strict position sizing rules without emotional override

Key Principle: Options sellers profit from three things — the passage of time (theta decay), volatility contraction (vega), and staying within the profit tent (delta management). All three are automatable.

Option Pricing: The Black-Scholes Model

Before building any strategy, an agent needs to accurately price options. The Black-Scholes model provides a closed-form solution for European option pricing. While it has known limitations (lognormal assumption, constant volatility), it remains the industry baseline for calculating theoretical value and Greeks.

The Black-Scholes formula for a call option is:

C = S · N(d1) - K · e^(-rT) · N(d2)

Where d1 = [ln(S/K) + (r + σ²/2)T] / (σ√T) and d2 = d1 - σ√T

S = spot price, K = strike, r = risk-free rate, T = time to expiry, σ = implied volatility

📞

Call Option

Right to buy at strike. Bullish position. Agent profits if spot rises above strike + premium paid.

📥

Put Option

Right to sell at strike. Bearish position. Agent profits if spot falls below strike - premium paid.

Time Value

Extrinsic value decays to zero at expiry. Sellers profit from this decay accelerating near expiry.

🌊

Implied Volatility

Market's forward-looking volatility estimate. IV rank shows how current IV compares to its 1-year range.

Greeks Deep Dive: What Every Agent Must Track

The Greeks quantify how an option's price changes with respect to different market inputs. Understanding and managing Greeks is the core discipline of options trading — without this, an agent is flying blind.

Δ
Delta
Rate of change of option price vs underlying price. Range: -1 to +1. ATM options ≈ ±0.50.
Γ
Gamma
Rate of change of delta. High near expiry for ATM options. Sellers are short gamma — risky.
Θ
Theta
Daily time decay. Positive for sellers. Accelerates in the final 30 DTE. Your primary income source.
V
Vega
Sensitivity to implied volatility changes. Long vega profits when IV rises; short vega profits when IV falls.
ρ
Rho
Interest rate sensitivity. Less critical for short-dated crypto options but matters for longer expirations.
Volga/Vomma
Second-order vega — how vega changes with IV. Critical for complex multi-leg strategies.

Portfolio-Level Greek Management

A single option's Greeks tell you its sensitivity. A portfolio's aggregate Greeks tell you the overall risk exposure. An options-trading agent should track portfolio-level Greeks and maintain them within target bands.

Greek Premium Seller Target Alert Threshold Hedge Action
Delta ±0.10 per $10k notional >±0.25 Buy/sell underlying or options
Gamma -0.05 to 0 per $10k <-0.15 Buy long gamma options to reduce
Theta +$0.50–$2.00/day per $10k <+$0.20 Add new short premium positions
Vega -$5 to -$20 per 1% IV move <-$40 Close or roll high-vega positions
black_scholes.py — Options Pricing and Greeks Calculator Python
import numpy as np
from scipy.stats import norm
from dataclasses import dataclass
from typing import Literal

@dataclass
class OptionGreeks:
    delta: float
    gamma: float
    theta: float    # per calendar day
    vega: float     # per 1% IV move
    rho: float
    price: float
    iv: float
    intrinsic: float
    extrinsic: float

class BlackScholes:
    """
    Black-Scholes option pricing and Greeks.
    All IV inputs are annualized (e.g., 0.80 = 80% annualized IV).
    """

    def __init__(self, risk_free_rate: float = 0.05):
        self.r = risk_free_rate

    def _d1_d2(self, S, K, T, sigma):
        # Avoid log(0) when deep ITM/OTM at expiry
        if T <= 0 or sigma <= 0:
            return 0.0, 0.0
        d1 = (np.log(S / K) + (self.r + 0.5 * sigma**2) * T) / (sigma * np.sqrt(T))
        d2 = d1 - sigma * np.sqrt(T)
        return d1, d2

    def price_and_greeks(
        self,
        option_type: Literal['call', 'put'],
        S: float,       # Current spot price
        K: float,       # Strike price
        T: float,       # Time to expiry in years (e.g., 30/365)
        sigma: float,   # Annualized implied volatility (e.g., 0.80)
    ) -> OptionGreeks:

        d1, d2 = self._d1_d2(S, K, T, sigma)
        r = self.r
        N = norm.cdf
        n = norm.pdf

        if option_type == 'call':
            price = S * N(d1) - K * np.exp(-r * T) * N(d2)
            delta = N(d1)
            intrinsic = max(S - K, 0)
        else:
            price = K * np.exp(-r * T) * N(-d2) - S * N(-d1)
            delta = N(d1) - 1
            intrinsic = max(K - S, 0)

        # Gamma is the same for calls and puts
        gamma = n(d1) / (S * sigma * np.sqrt(T)) if T > 0 else 0

        # Theta: rate of change per calendar day
        if option_type == 'call':
            theta_annual = (
                -(S * n(d1) * sigma) / (2 * np.sqrt(T))
                - r * K * np.exp(-r * T) * N(d2)
            ) if T > 0 else 0
        else:
            theta_annual = (
                -(S * n(d1) * sigma) / (2 * np.sqrt(T))
                + r * K * np.exp(-r * T) * N(-d2)
            ) if T > 0 else 0
        theta = theta_annual / 365

        # Vega: price change per 1% move in IV
        vega = S * n(d1) * np.sqrt(T) / 100 if T > 0 else 0

        # Rho: price change per 1% move in risk-free rate
        if option_type == 'call':
            rho = K * T * np.exp(-r * T) * N(d2) / 100
        else:
            rho = -K * T * np.exp(-r * T) * N(-d2) / 100

        return OptionGreeks(
            delta=round(delta, 4),
            gamma=round(gamma, 6),
            theta=round(theta, 4),
            vega=round(vega, 4),
            rho=round(rho, 4),
            price=round(price, 4),
            iv=sigma,
            intrinsic=round(intrinsic, 4),
            extrinsic=round(price - intrinsic, 4),
        )

# Example: BTC 30-delta put, 30 DTE, IV=80%
bs = BlackScholes(risk_free_rate=0.05)
greeks = bs.price_and_greeks(
    option_type='put',
    S=85000,    # BTC spot
    K=78000,    # Strike (~8% OTM)
    T=30/365,   # 30 days to expiry
    sigma=0.80  # 80% annualized IV
)
print(f"Price: ${greeks.price:.2f}")
print(f"Delta: {greeks.delta:.4f} | Gamma: {greeks.gamma:.6f}")
print(f"Theta: ${greeks.theta:.2f}/day | Vega: ${greeks.vega:.2f}/1%")
print(f"Extrinsic (collectible premium): ${greeks.extrinsic:.2f}")

Income Strategies: Covered Calls, CSPs, and Iron Condors

Premium-selling strategies form the core of a systematic options income approach. Each strategy has specific market conditions where it performs optimally — an AI agent's job is to recognize those conditions and deploy the right structure.

Covered Calls

A covered call involves holding a long position in the underlying asset and selling a call option against it. The short call generates immediate income while capping upside above the strike price. This strategy is ideal when an agent holds inventory it is willing to sell at a higher price.

Covered Call Payoff Profile

Spot < Strike: Profit limited to premium collected. Underlying loss offset by premium.
Spot = Strike: Maximum profit achieved. Premium + gains on underlying.
Spot > Strike: Capped profit. Underlying gains offset by short call losses.

Optimal environment: Range-bound to slightly bullish market, IV rank > 30%.

Cash-Secured Puts (CSPs)

A cash-secured put involves selling a put option while holding enough cash to purchase the underlying if assigned. This is effectively a limit buy order that gets paid while waiting. CSPs at the 0.20–0.30 delta level have a >70% probability of expiring worthless.

Iron Condors

An iron condor combines a bull put spread and a bear call spread. Four legs define a profit zone — if the underlying stays within the range at expiry, the agent keeps the full net credit. Iron condors are the premier strategy for high-IV, range-bound environments.

Strategy Legs Max Profit Max Loss Best IV Environment
Covered Call Long underlying + short call Premium + (strike - cost basis) Cost basis - premium IV Rank > 30%
Cash-Secured Put Short put + cash reserve Premium collected Strike - premium IV Rank > 30%
Iron Condor 4 legs: put spread + call spread Net credit received Spread width - credit IV Rank > 50%
Strangle Short OTM call + short OTM put Both premiums Theoretically unlimited IV Rank > 60%

Risk Management for Options-Selling Agents

Options selling is not free money. The strategies above earn small, frequent gains but face rare, large losses — the classic negative-skew profile. Robust risk management is what separates a sustainable options agent from one that eventually blows up.

The Three Critical Risk Rules

Rule 1 — Position Sizing: Never allocate more than 5% of portfolio capital to a single options position. Use notional exposure (not premium) for sizing calculations.

Rule 2 — Loss Limits: Close any position at 2x the premium received. If you sold a strangle for $500 credit, close it when the net debit to close reaches $1,000. Do not hope for recovery.

Rule 3 — Profit Taking: Close positions at 50% of maximum profit. Holding to expiry captures the final 50% of theta decay but concentrates gamma risk — the math favors early exit.

Black Swan Events and Tail Risk

Options sellers are short volatility. In a flash crash or black swan event (sudden >20% gap), short strangles and condors can lose 10-20x the premium collected in a single day. Tail risk hedging is non-negotiable for large-scale operations.

Common hedges for a premium-selling book:

  • Long OTM puts (3-5% OTM, 0.05 delta): Cheap insurance that pays off in crashes.
  • VIX call spreads: Long volatility exposure that activates when your short-vega book suffers most.
  • Position caps: Hard limits on gross exposure regardless of perceived market conditions.
  • Correlation diversification: Do not concentrate all premium selling in correlated assets.

Strategy Selection Agent with Purple Flea Trading API

The following code implements a complete options strategy selection agent. It reads market conditions from the Purple Flea trading API, calculates IV rank, selects the optimal strategy, and constructs orders.

options_agent.py — Full Strategy Selection Agent Python
import asyncio
import aiohttp
import numpy as np
from datetime import datetime, timedelta
from dataclasses import dataclass, field
from typing import Optional, List
from black_scholes import BlackScholes, OptionGreeks

PURPLEFLEA_API = "https://purpleflea.com/trading-api"
API_KEY = "your-api-key-here"

@dataclass
class MarketConditions:
    symbol: str
    spot: float
    current_iv: float
    iv_rank: float      # 0-100, where 100 = highest IV in past year
    iv_percentile: float
    realized_vol_30d: float
    trend: str           # 'bullish', 'bearish', 'neutral'
    atr_pct: float        # Average True Range as % of spot

@dataclass
class OptionsPosition:
    symbol: str
    strategy: str
    legs: List[dict]
    net_credit: float
    max_profit: float
    max_loss: float
    prob_profit: float
    expiry: str
    greeks: dict = field(default_factory=dict)

class OptionsAgent:
    """
    Systematic options premium-selling agent.
    Uses Purple Flea Trading API for market data and order execution.
    Supports: covered calls, CSPs, iron condors, short strangles.
    """

    def __init__(self, api_key: str, portfolio_value: float):
        self.api_key = api_key
        self.portfolio_value = portfolio_value
        self.bs = BlackScholes()
        self.max_position_pct = 0.05   # 5% max per position
        self.target_dte = 30           # Target 30 DTE for entry
        self.profit_target_pct = 0.50  # Close at 50% max profit
        self.stop_loss_mult = 2.0      # Close at 2x credit received
        self.open_positions: List[OptionsPosition] = []

    async def get_market_conditions(self, symbol: str) -> MarketConditions:
        async with aiohttp.ClientSession() as session:
            headers = {"X-API-Key": self.api_key}
            url = f"{PURPLEFLEA_API}/options/market-data/{symbol}"
            async with session.get(url, headers=headers) as resp:
                data = await resp.json()

        return MarketConditions(
            symbol=symbol,
            spot=data['spot'],
            current_iv=data['implied_volatility'],
            iv_rank=data['iv_rank'],
            iv_percentile=data['iv_percentile'],
            realized_vol_30d=data['realized_vol_30d'],
            trend=data['trend'],
            atr_pct=data['atr_pct'],
        )

    def select_strategy(self, conditions: MarketConditions) -> str:
        """
        Strategy selection matrix based on IV rank and trend.
        Returns strategy name for position construction.
        """
        iv_rank = conditions.iv_rank
        trend = conditions.trend

        # Very high IV: iron condors and short strangles capture max premium
        if iv_rank >= 60:
            if trend == 'neutral':
                return 'iron_condor'
            else:
                return 'strangle'

        # Medium-high IV: directional plays with defined risk
        elif iv_rank >= 30:
            if trend == 'bullish':
                return 'cash_secured_put'
            elif trend == 'bearish':
                return 'covered_call'
            else:
                return 'iron_condor'

        # Low IV: avoid selling premium, wait for better conditions
        else:
            return 'no_trade'  # IV too low to sell

    def build_iron_condor(
        self, conditions: MarketConditions
    ) -> Optional[OptionsPosition]:
        """
        Constructs iron condor at standard parameters:
        - Short strikes at 0.20 delta (~16% OTM)
        - Long strikes 5% further OTM for defined risk
        - 30 DTE entry
        """
        S = conditions.spot
        sigma = conditions.current_iv
        T = self.target_dte / 365

        # Find strikes at target deltas by iteration
        short_put_strike = self._find_strike_by_delta(
            S, sigma, T, 'put', target_delta=-0.20
        )
        short_call_strike = self._find_strike_by_delta(
            S, sigma, T, 'call', target_delta=0.20
        )
        long_put_strike = short_put_strike * 0.95   # 5% below short put
        long_call_strike = short_call_strike * 1.05  # 5% above short call

        # Price each leg
        sp_g = self.bs.price_and_greeks('put', S, short_put_strike, T, sigma)
        lp_g = self.bs.price_and_greeks('put', S, long_put_strike, T, sigma)
        sc_g = self.bs.price_and_greeks('call', S, short_call_strike, T, sigma)
        lc_g = self.bs.price_and_greeks('call', S, long_call_strike, T, sigma)

        net_credit = (sp_g.price - lp_g.price) + (sc_g.price - lc_g.price)
        put_spread_width = short_put_strike - long_put_strike
        call_spread_width = long_call_strike - short_call_strike
        max_loss = max(put_spread_width, call_spread_width) - net_credit

        # Probability of profit: approximately N(d2) for short strikes
        prob_profit = 1 - (sp_g.delta + sc_g.delta)  # rough estimate

        expiry = (datetime.now() + timedelta(days=self.target_dte)).strftime("%Y-%m-%d")

        return OptionsPosition(
            symbol=conditions.symbol,
            strategy='iron_condor',
            legs=[
                {'type': 'put', 'action': 'sell', 'strike': short_put_strike},
                {'type': 'put', 'action': 'buy', 'strike': long_put_strike},
                {'type': 'call', 'action': 'sell', 'strike': short_call_strike},
                {'type': 'call', 'action': 'buy', 'strike': long_call_strike},
            ],
            net_credit=round(net_credit, 4),
            max_profit=round(net_credit, 4),
            max_loss=round(max_loss, 4),
            prob_profit=round(prob_profit, 3),
            expiry=expiry,
            greeks={
                'net_delta': sp_g.delta + sc_g.delta - lp_g.delta - lc_g.delta,
                'net_theta': sp_g.theta + sc_g.theta - lp_g.theta - lc_g.theta,
                'net_vega': sp_g.vega + sc_g.vega - lp_g.vega - lc_g.vega,
            }
        )

    def _find_strike_by_delta(self, S, sigma, T, opt_type, target_delta):
        # Binary search for strike matching target delta
        low, high = S * 0.50, S * 1.50
        for _ in range(50):  # 50 iterations is precise enough
            mid = (low + high) / 2
            g = self.bs.price_and_greeks(opt_type, S, mid, T, sigma)
            if abs(g.delta - target_delta) < 0.001:
                break
            if opt_type == 'call':
                if g.delta > target_delta: low = mid
                else: high = mid
            else:
                if g.delta < target_delta: low = mid
                else: high = mid
        return round(mid / 100) * 100  # Round to nearest $100 strike


    async def run_once(self, symbols: List[str]):
        for symbol in symbols:
            conditions = await self.get_market_conditions(symbol)
            strategy = self.select_strategy(conditions)
            print(f"[{symbol}] IV Rank: {conditions.iv_rank:.0f}% | Strategy: {strategy}")

            if strategy == 'iron_condor':
                position = self.build_iron_condor(conditions)
                if position:
                    print(f"  Credit: ${position.net_credit:.2f} | PoP: {position.prob_profit:.1%}")
                    print(f"  Theta/day: ${position.greeks['net_theta']:.3f}")

# Run the agent
async def main():
    agent = OptionsAgent(api_key=API_KEY, portfolio_value=100000)
    await agent.run_once(['BTC-USD', 'ETH-USD', 'SOL-USD'])

asyncio.run(main())

Purple Flea Trading API: Options Endpoints

Purple Flea's Trading API provides full options chain data, Greeks calculations, and multi-leg order submission. The API is designed specifically for AI agents — machine-readable responses, high rate limits, and WebSocket Greeks streams for real-time portfolio management.

📊

Options Chain

GET /options/chain/:symbol
Full options chain with real-time bids, asks, IV, and all Greeks.

📈

IV Rank Data

GET /options/iv-rank/:symbol
52-week IV range, current rank, percentile, and volatility surface data.

🔄

Multi-Leg Orders

POST /options/orders
Submit iron condors, strangles, and spreads as atomic multi-leg orders.

Greeks Stream

WS /options/greeks/stream
Real-time portfolio Greeks aggregation via WebSocket.

Start Selling Premium with Purple Flea

Access the full options chain API, real-time Greeks streams, and multi-leg order execution. New agents can claim free USDC via the faucet to start paper trading without risk.