Crypto Bots

Crypto Options Trading Bot: How to Automate Covered Calls and Cash-Secured Puts

Crypto options markets on Deribit and Lyra Finance generate premium income whether markets go up, down, or sideways. Learn to build bots that automatically sell covered calls and cash-secured puts for passive income.

A
AI Agents Hubยท2026-03-17ยท5 min readยท870 words

Builder of AI agents, crypto trading bots, and open-source automation tools. Sharing practical guides on how to build, deploy, and profit from AI and DeFi technology.

Why Options Are Underrated for Bots

Most crypto traders focus on directional speculation. Options traders focus on probability and premium:

  • Selling covered calls: Own BTC, sell the right to buy it at a higher price. Earn premium regardless of outcome.
  • Selling cash-secured puts: Hold USDC, sell the right to buy BTC at a lower price. Earn premium; worst case = you buy BTC at a discount.
  • Iron condors: Collect premium by betting price stays in a range.

The beauty for bots: options strategies are mechanical. Same rules every week, every cycle, no emotion.

Where to Trade Crypto Options

Deribit (Best CEX for Options)

  • Largest crypto options market (~85% of BTC/ETH options volume)
  • Bitcoin and Ethereum options
  • REST + WebSocket API
  • Requires KYC

Lyra Finance (Best DeFi Options)

  • On-chain options on Arbitrum and Base
  • No KYC, non-custodial
  • Automated market maker (no order book)
  • USDC-denominated premiums

Deribit API Bot: Weekly Covered Call Seller

import deribit_apiv2client as deribit
import datetime

# Connect to Deribit
config = deribit.Configuration(
    host="https://www.deribit.com/api/v2",
    api_key={'ApiKeyAuth': DERIBIT_CLIENT_ID},
    api_key_prefix={'ApiKeyAuth': DERIBIT_CLIENT_SECRET},
)

client = deribit.ApiClient(config)
public_api = deribit.PublicApi(client)
private_api = deribit.PrivateApi(client)

def get_account_summary(currency: str = "BTC") -> dict:
    """Get account info including BTC balance"""
    result = private_api.get_account_summary(currency=currency, extended=True)
    return result['result']

def get_options_chain(currency: str = "BTC", expiry_days: int = 7) -> list:
    """Get available options expiring in approximately N days"""
    
    # Get all BTC instruments
    result = public_api.get_instruments(
        currency=currency, 
        kind="option",
        expired=False
    )
    
    instruments = result['result']
    
    # Filter to target expiry
    today = datetime.date.today()
    target_expiry = today + datetime.timedelta(days=expiry_days)
    
    # Find closest available expiry
    expiry_dates = set()
    for inst in instruments:
        exp_ts = inst['expiration_timestamp'] / 1000
        exp_date = datetime.date.fromtimestamp(exp_ts)
        expiry_dates.add(exp_date)
    
    closest_expiry = min(expiry_dates, key=lambda d: abs((d - target_expiry).days))
    
    # Filter instruments for closest expiry
    return [
        inst for inst in instruments 
        if datetime.date.fromtimestamp(inst['expiration_timestamp']/1000) == closest_expiry
    ]

def find_optimal_call_to_sell(
    instruments: list, 
    current_price: float,
    target_delta: float = 0.2  # 0.2 delta = 20% chance of assignment
) -> dict:
    """Find the best covered call strike to sell"""
    
    calls = [i for i in instruments if i['option_type'] == 'call']
    
    best_option = None
    best_premium_annualized = 0
    
    for inst in calls:
        # Get current market data
        try:
            ticker = public_api.ticker(instrument_name=inst['instrument_name'])['result']
            
            if not ticker.get('bid'):
                continue
            
            bid_price = ticker['bid']  # We sell at bid
            bid_in_usd = bid_price * current_price
            delta = abs(ticker.get('greeks', {}).get('delta', 1.0))
            
            # Target ~0.2 delta: out-of-the-money but not too far
            if 0.10 <= delta <= 0.30:
                # Calculate annualized premium yield
                days_to_expiry = (inst['expiration_timestamp']/1000 - datetime.datetime.now().timestamp()) / 86400
                annual_premium = (bid_in_usd / current_price) * (365 / days_to_expiry)
                
                if annual_premium > best_premium_annualized:
                    best_premium_annualized = annual_premium
                    best_option = {
                        'instrument': inst['instrument_name'],
                        'strike': inst['strike'],
                        'bid': bid_price,
                        'bid_usd': bid_in_usd,
                        'delta': delta,
                        'days_to_expiry': days_to_expiry,
                        'annualized_yield': annual_premium * 100,
                    }
        
        except Exception:
            continue
    
    return best_option

def sell_covered_call(instrument_name: str, amount: float = 0.1) -> dict:
    """Sell a covered call on Deribit"""
    
    # Get current bid
    ticker = public_api.ticker(instrument_name=instrument_name)['result']
    bid = ticker['bid']
    
    order = private_api.sell(
        instrument_name=instrument_name,
        amount=amount,      # Size in BTC (0.1 = 1 contract)
        type='limit',
        price=bid,          # Sell at bid
        post_only=True,     # Ensure maker (avoid taker fees)
    )
    
    return order['result']

class WeeklyCoveredCallBot:
    """
    Sells weekly covered calls on BTC every Monday.
    Target: collect 0.5-2% weekly premium income on BTC holdings.
    """
    
    def run_weekly_strategy(self):
        summary = get_account_summary('BTC')
        btc_balance = summary.get('available_funds', 0)
        current_price = self.get_btc_price()
        
        print(f"BTC Balance: {btc_balance:.4f} BTC (${btc_balance * current_price:,.2f})")
        
        if btc_balance < 0.1:
            print("Need at least 0.1 BTC to sell covered calls")
            return
        
        # Get weekly options chain
        instruments = get_options_chain('BTC', expiry_days=7)
        
        # Find optimal call to sell
        best_call = find_optimal_call_to_sell(instruments, current_price)
        
        if not best_call:
            print("No suitable calls found this week")
            return
        
        print(f"\n๐Ÿ“Š Selling covered call:")
        print(f"   Strike: ${best_call['strike']:,.0f}")
        print(f"   Premium: ${best_call['bid_usd']:.2f} per BTC")
        print(f"   Delta: {best_call['delta']:.2f}")
        print(f"   Annualized yield: {best_call['annualized_yield']:.1f}%")
        
        # Sell call against 50% of BTC holdings
        sell_amount = round(btc_balance * 0.5, 1)
        result = sell_covered_call(best_call['instrument'], sell_amount)
        
        print(f"โœ… Order placed: {result.get('order_id')}")
    
    def get_btc_price(self) -> float:
        ticker = public_api.ticker(instrument_name='BTC-PERPETUAL')['result']
        return ticker['last_price']

Expected Returns

A consistently-executed weekly covered call strategy on BTC:

  • Average weekly premium: 0.5-1.5%
  • Annualized: 26-78%
  • Downside: If BTC moons past your strike, you miss the upside
  • Upside: You earn premium even when BTC is flat or declining slightly

For a pure income strategy on existing BTC holdings, it's one of the most consistent yield sources available โ€” no leverage, no liquidation risk.

Lyra Finance: Decentralized Options

For DeFi, Lyra Finance lets you sell options on-chain:

import { lyra } from '@lyrafinance/lyra-js'

const LYRA = new lyra('mainnet', 'base')

// Get available markets
const markets = await LYRA.markets()

// Get ETH options market
const ethMarket = markets.find(m => m.name === 'ETH')
const board = await ethMarket.liveBoards()  // Available expiries

// Sell a put via Lyra (liquidity provision = selling options)
// Lyra works differently: you provide liquidity to the pool
// and earn premium as trades happen against you
const quote = await ethMarket.quoteOptionWithBoard(
  board[0].boardId,
  2000,          // Strike price
  true,          // isCall
  1.0,           // Size in ETH
  false          // isBuy โ€” false = sell (be the option seller)
)

console.log(`Premium to receive: $${quote.premium.toFixed(2)}`)

Options are one of the most powerful tools for sophisticated traders. Combined with automation, they create income streams that perform in all market conditions โ€” the holy grail of trading bot design.

Related Articles