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.
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.
Tagged in
Related Articles
Crypto Bot Risk Management: The 10 Rules That Separate Winners From Losers
7 min read
Crypto BotsHow to Build a Self-Healing Trading Bot That Fixes Its Own Errors
5 min read
Crypto BotsPump.fun and Solana Meme Coin Bots: How to Automate the Hottest Trend
5 min read
Crypto BotsHow to Build a Crypto Portfolio Auto-Rebalancing Bot
5 min read