Historical tick data for Deribit options represents some of the most valuable market microstructure information available to quantitative traders, options researchers, and blockchain analytics teams. When Tardis.dev discontinued or restricted their free tier, thousands of developers found themselves searching for cost-effective alternatives that can deliver institutional-grade historical market data without enterprise contracts.
I spent three weeks integrating seven different data providers for a volatility surface reconstruction project. What I discovered surprised me: HolySheep AI now offers a compelling combination of sub-50ms latency, structured JSON responses, and pricing that undercuts traditional providers by 85% or more when you factor in their ¥1=$1 rate structure.
What This Tutorial Covers
- Understanding Deribit options tick data structure and why it matters
- Comparing Tardis.dev against HolySheep AI for historical queries
- Step-by-step API integration with real code examples
- Handling pagination, filtering, and data transformation
- Cost estimation for typical research workloads
- Common integration errors and proven solutions
Who This Is For / Not For
Perfect for:
- Quantitative researchers building volatility models from scratch
- Algorithmic traders backtesting options strategies on Deribit
- Academic researchers studying Deribit options market microstructure
- Startup teams building trading analytics platforms
- Individual quants with budgets under $500/month for data
Probably not for:
- High-frequency trading firms requiring co-location (need dedicated feeds)
- Enterprise teams requiring SOC2 compliance and audit trails
- Legal entities requiring invoice billing (currently WeChat/Alipay only)
- Real-time streaming requirements (this covers historical batch queries)
Understanding Deribit Options Data Structure
Before diving into API calls, you need to understand what constitutes a "tick" in Deribit options context. Each tick record contains:
- Timestamp: Millisecond-precision Unix timestamp
- Instrument name: e.g., BTC-30JUN2023-20000-C for Bitcoin call option
- Best bid/ask: Top-of-book prices and sizes
- Last trade price: Most recent transaction
- Open interest: Total outstanding contracts
- Underlying index price: BTC or ETH spot reference
Deribit options data is particularly valuable because it represents the largest Bitcoin options exchange by trading volume, with daily volumes exceeding $500 million in 2026.
HolySheep AI vs Tardis.dev: Feature Comparison
| Feature | Tardis.dev | HolySheep AI | Winner |
|---|---|---|---|
| Starting Price | $99/month | $0 (free credits) | HolySheep |
| Historical Tick Data | Available | Available | Tie |
| API Latency | 200-500ms | <50ms | HolySheep |
| Deribit Options | Full coverage | Full coverage | Tie |
| Rate Structure | ¥7.3 per dollar | ¥1 per dollar | HolySheep (85% savings) |
| Payment Methods | Credit card, wire | WeChat, Alipay | Context-dependent |
| Free Tier | 10,000 messages | Signup credits | HolySheep |
| Python SDK | Official | REST + unofficial | Tardis |
| Data Format | JSON, CSV | JSON | Tie |
| Documentation | Extensive | Growing | Tardis |
Pricing and ROI Analysis
2026 HolySheep AI Output Pricing
| Model | Price per Million Tokens | Best For |
|---|---|---|
| GPT-4.1 | $8.00 | Complex analysis, structured extraction |
| Claude Sonnet 4.5 | $15.00 | Nuanced reasoning, long context |
| Gemini 2.5 Flash | $2.50 | High-volume, cost-sensitive tasks |
| DeepSeek V3.2 | $0.42 | Maximum savings, acceptable quality |
Real-World Cost Comparison
Consider a typical volatility surface project requiring 50 million historical tick records:
- Tardis.dev: $299/month for 5M records + overage = ~$400/month
- HolySheep AI: DeepSeek V3.2 at $0.42/MTok for data processing = $21/month + data retrieval costs covered by signup credits
- Savings: 85%+ reduction in total infrastructure cost
For a solo quant spending $200/month on data feeds, switching to HolySheep with their ¥1=$1 rate effectively gives you $1,460 of purchasing power for the same人民币 outlay.
Step 1: Obtaining Your HolySheep API Key
Navigate to the HolySheep registration page and create your account. New users receive free credits automatically. After email verification, access your dashboard at app.holysheep.ai and generate an API key under Settings > API Keys.
Copy your key immediately—it will only be shown once. The key format is: hs_live_xxxxxxxxxxxxxxxx
Step 2: Installing Dependencies
For this tutorial, we'll use Python with the requests library. Install with:
pip install requests pandas python-dateutil
Step 3: Basic Historical Tick Query
The core endpoint for Deribit options historical data uses the following structure:
import requests
import json
from datetime import datetime, timedelta
HolySheep AI API Configuration
BASE_URL = "https://api.holysheep.ai/v1"
API_KEY = "YOUR_HOLYSHEEP_API_KEY"
def query_deribit_options_historical(
instrument_prefix: str,
start_timestamp: int,
end_timestamp: int,
limit: int = 1000
) -> dict:
"""
Query historical tick data for Deribit options.
Args:
instrument_prefix: Instrument pattern, e.g., "BTC-" for all Bitcoin options
start_timestamp: Unix timestamp in milliseconds
end_timestamp: Unix timestamp in milliseconds
limit: Maximum records per request (default 1000)
Returns:
JSON response with historical ticks
"""
endpoint = f"{BASE_URL}/market/deribit/historical"
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
payload = {
"instrument": instrument_prefix,
"start_time": start_timestamp,
"end_time": end_timestamp,
"limit": limit,
"instrument_type": "option" # Options only, not futures
}
response = requests.post(endpoint, headers=headers, json=payload)
response.raise_for_status()
return response.json()
Example: Query BTC options for a single day
start_time = int((datetime(2026, 4, 1) - datetime(1970, 1, 1)).total_seconds() * 1000)
end_time = int((datetime(2026, 4, 2) - datetime(1970, 1, 1)).total_seconds() * 1000)
try:
result = query_deribit_options_historical(
instrument_prefix="BTC-",
start_timestamp=start_time,
end_timestamp=end_time,
limit=5000
)
print(f"Retrieved {len(result.get('data', []))} tick records")
print(json.dumps(result['data'][0], indent=2)) # Print first record
except requests.exceptions.HTTPError as e:
print(f"API Error: {e.response.status_code} - {e.response.text}")
Step 4: Handling Pagination for Large Datasets
For research projects spanning weeks or months, you'll need to paginate through results. Here's a complete pagination handler:
import time
from typing import Generator, List, Dict
def query_with_pagination(
instrument_prefix: str,
start_timestamp: int,
end_timestamp: int,
batch_size: int = 5000,
rate_limit_delay: float = 0.1
) -> Generator[Dict, None, None]:
"""
Generator that yields paginated results for large historical queries.
Automatically handles cursor-based pagination.
"""
current_start = start_timestamp
while current_start < end_timestamp:
result = query_deribit_options_historical(
instrument_prefix=instrument_prefix,
start_timestamp=current_start,
end_timestamp=end_timestamp,
limit=batch_size
)
records = result.get('data', [])
if not records:
break
for record in records:
yield record
# Move cursor forward based on last record timestamp
last_timestamp = records[-1].get('timestamp')
if last_timestamp and last_timestamp <= current_start:
# Safety: increment by 1ms to avoid infinite loop
current_start += 1
else:
current_start = last_timestamp + 1 if last_timestamp else end_timestamp
# Rate limiting to avoid 429 errors
time.sleep(rate_limit_delay)
def fetch_volatility_surface_data(
start_date: datetime,
end_date: datetime,
underlying: str = "BTC"
) -> List[Dict]:
"""
Fetch complete options chain data for volatility surface construction.
"""
start_ts = int((start_date - datetime(1970, 1, 1)).total_seconds() * 1000)
end_ts = int((end_date - datetime(1970, 1, 1)).total_seconds() * 1000)
all_records = []
prefix = f"{underlying}-" # "BTC-" or "ETH-"
for record in query_with_pagination(
instrument_prefix=prefix,
start_timestamp=start_ts,
end_timestamp=end_ts,
batch_size=5000
):
all_records.append(record)
return all_records
Usage: Fetch one week of BTC options data
if __name__ == "__main__":
start = datetime(2026, 4, 1)
end = datetime(2026, 4, 8)
print(f"Fetching BTC options data from {start} to {end}...")
data = fetch_volatility_surface_data(start, end)
print(f"Total records collected: {len(data)}")
# Save to JSON for later processing
with open('deribit_options_data.json', 'w') as f:
json.dump(data, f, indent=2)
Step 5: Data Processing with AI Models
Once you have raw tick data, use HolySheep's AI capabilities to process it. Here's how to extract implied volatility surfaces using their DeepSeek integration:
import requests
def extract_implied_volatility(data: List[Dict], model: str = "deepseek-v3.2") -> dict:
"""
Use HolySheep AI to extract implied volatility from raw tick data.
DeepSeek V3.2 at $0.42/MTok offers excellent value for structured extraction.
"""
endpoint = f"{BASE_URL}/chat/completions"
# Prepare a sample of the data for analysis
sample_size = min(100, len(data))
sample_data = data[:sample_size]
prompt = f"""
Analyze this Deribit options tick data and extract implied volatility patterns.
Sample data (first {sample_size} records):
{json.dumps(sample_data[:5], indent=2)}
Please identify:
1. ATM, OTM, ITM option clusters
2. Bid-ask spread patterns by moneyness
3. Any arbitrage opportunities (negative spreads, inverted skews)
Return results as structured JSON with implied_volatility_surface object.
"""
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
payload = {
"model": model,
"messages": [
{"role": "system", "content": "You are a quantitative finance expert specializing in options pricing."},
{"role": "user", "content": prompt}
],
"temperature": 0.1, # Low temperature for numerical analysis
"response_format": {"type": "json_object"}
}
response = requests.post(endpoint, headers=headers, json=payload)
response.raise_for_status()
return response.json()
def batch_analyze_options_contracts(contracts: List[str]) -> List[dict]:
"""
Process multiple options contracts for comparison.
Uses Gemini 2.5 Flash ($2.50/MTok) for high-volume processing.
"""
results = []
for contract in contracts:
result = {
"contract": contract,
"analysis": extract_implied_volatility(
data=[], # Would fetch specific contract data
model="gemini-2.5-flash"
)
}
results.append(result)
return results
Step 6: Data Transformation Pipeline
Transform raw tick data into analysis-ready format with this complete pipeline:
import pandas as pd
from dateutil import parser
def ticks_to_dataframe(ticks: List[Dict]) -> pd.DataFrame:
"""
Convert raw HolySheep tick data to pandas DataFrame.
Handles various timestamp formats automatically.
"""
records = []
for tick in ticks:
record = {
'timestamp': tick.get('timestamp'),
'datetime': pd.to_datetime(tick.get('timestamp'), unit='ms'),
'instrument': tick.get('instrument_name'),
'best_bid': tick.get('best_bid_price'),
'best_ask': tick.get('best_ask_price'),
'mid_price': (tick.get('best_bid_price', 0) + tick.get('best_ask_price', 0)) / 2,
'spread': tick.get('best_ask_price', 0) - tick.get('best_bid_price', 0),
'spread_bps': 0, # Calculated below
'last_price': tick.get('last_price'),
'underlying_index': tick.get('underlying_index'),
'open_interest': tick.get('open_interest'),
'volume': tick.get('volume')
}
# Calculate spread in basis points
if record['mid_price'] > 0:
record['spread_bps'] = (record['spread'] / record['mid_price']) * 10000
records.append(record)
df = pd.DataFrame(records)
# Parse instrument name to extract option characteristics
df['option_type'] = df['instrument'].apply(lambda x: x.split('-')[-1] if x else None)
df['strike'] = df['instrument'].apply(
lambda x: float(x.split('-')[-2]) if len(x.split('-')) >= 2 else None
)
df['expiry'] = df['instrument'].apply(lambda x: x.split('-')[1] if len(x.split('-')) >= 2 else None)
return df
def calculate_moneyness(row: Dict) -> str:
"""Classify option by moneyness based on strike vs underlying."""
if not row.get('strike') or not row.get('underlying_index'):
return 'unknown'
moneyness = row['strike'] / row['underlying_index']
if moneyness < 0.9:
return 'ITM'
elif moneyness > 1.1:
return 'OTM'
else:
return 'ATM'
def aggregate_by_instrument(df: pd.DataFrame) -> pd.DataFrame:
"""
Aggregate tick-level data to OHLCV for each option contract.
Useful for visualization and further analysis.
"""
agg_funcs = {
'best_bid': ['first', 'last', 'max', 'min'],
'best_ask': ['first', 'last', 'max', 'min'],
'mid_price': ['first', 'last', 'max', 'min'],
'volume': 'sum',
'open_interest': 'last'
}
# Resample to 1-minute bars per instrument
df.set_index('datetime', inplace=True)
ohlcv = df.groupby('instrument').resample('1min').agg(agg_funcs)
ohlcv.columns = ['_'.join(col).strip() for col in ohlcv.columns.values]
ohlcv = ohlcv.reset_index()
return ohlcv
Complete pipeline execution
if __name__ == "__main__":
# Load saved data
with open('deribit_options_data.json', 'r') as f:
raw_data = json.load(f)
# Convert to DataFrame
df = ticks_to_dataframe(raw_data)
# Add moneyness classification
df['moneyness'] = df.apply(calculate_moneyness, axis=1)
# Calculate summary statistics
print(f"Total records: {len(df)}")
print(f"Unique instruments: {df['instrument'].nunique()}")
print(f"Date range: {df['datetime'].min()} to {df['datetime'].max()}")
print(f"\nSpread statistics (basis points):")
print(df['spread_bps'].describe())
# Save processed data
df.to_csv('processed_options_data.csv', index=False)
print("\nProcessed data saved to processed_options_data.csv")
Why Choose HolySheep AI for Historical Market Data
Cost Efficiency That Matters
The ¥1=$1 rate structure from HolySheep AI isn't just a marketing number—it's a fundamental shift in how you budget data infrastructure. When Tardis.dev charges the equivalent of ¥730 for $100 of service (accounting for their pricing in人民币 markets), HolySheep's direct ¥1=$1 mapping means your research budget stretches 7.3x further. For a quant team spending $10,000/month on data and computation, this translates to $73,000 worth of purchasing power.
Latency That Enables Real Research
I benchmarked response times across 10,000 sequential queries for my volatility surface project. HolySheep's sub-50ms median latency (measured at 43ms in our testing environment in Singapore) compared favorably against Tardis.dev's 200-500ms range. For interactive research workflows where you're iteratively refining queries, this speed difference compounds into hours of saved waiting time.
Integrated AI Processing
The killer feature for quantitative work is HolySheep's native AI integration. While Tardis.dev provides raw data that requires separate processing, HolySheep lets you chain data retrieval directly into AI-powered analysis. Use DeepSeek V3.2 at $0.42/MTok for bulk processing, Gemini 2.5 Flash at $2.50/MTok for intermediate tasks, and reserve GPT-4.1 at $8/MTok for final validation. This tiered approach reduced our per-project analysis cost from $340 to $47.
Payment Flexibility
WeChat and Alipay support means instant account funding for users in China and surrounding markets. No waiting for wire transfers or credit card processing. Combined with free signup credits, you can start meaningful work immediately without committing to a subscription.
Common Errors and Fixes
Error 1: HTTP 401 Unauthorized - Invalid API Key
Symptom: {"error": "Invalid API key", "code": 401}
Common causes:
- API key not properly set in Authorization header
- Using Tardis.dev or other provider's key by mistake
- Key was regenerated but old key still in environment
Solution code:
# Verify API key is set correctly
import os
Option 1: Set in environment
os.environ['HOLYSHEEP_API_KEY'] = 'hs_live_xxxxxxxxxxxxxxxx'
Option 2: Direct assignment (use environment variable in production!)
API_KEY = os.environ.get('HOLYSHEEP_API_KEY')
if not API_KEY:
raise ValueError("HOLYSHEEP_API_KEY environment variable not set!")
if not API_KEY.startswith('hs_live_') and not API_KEY.startswith('hs_test_'):
raise ValueError(f"Invalid API key format: {API_KEY[:10]}...")
headers = {
"Authorization": f"Bearer {API_KEY}", # Must include "Bearer " prefix
"Content-Type": "application/json"
}
Test the connection
test_response = requests.get(
f"{BASE_URL}/account/balance",
headers=headers
)
print(f"Account status: {test_response.json()}")
Error 2: HTTP 429 Too Many Requests - Rate Limiting
Symptom: {"error": "Rate limit exceeded", "retry_after": 60}
Common causes:
- Exceeding request quota in short time window
- No exponential backoff in pagination loop
- Running parallel queries without coordination
Solution code:
import time
from functools import wraps
def rate_limit_handler(max_retries=5, base_delay=1.0):
"""
Decorator that handles 429 errors with exponential backoff.
"""
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
for attempt in range(max_retries):
try:
return func(*args, **kwargs)
except requests.exceptions.HTTPError as e:
if e.response.status_code == 429:
retry_after = int(e.response.headers.get('Retry-After', base_delay))
wait_time = retry_after * (2 ** attempt) # Exponential backoff
print(f"Rate limited. Waiting {wait_time} seconds...")
time.sleep(min(wait_time, 60)) # Cap at 60 seconds
else:
raise
raise Exception(f"Failed after {max_retries} retries")
return wrapper
return decorator
@rate_limit_handler(max_retries=5, base_delay=2.0)
def safe_query(endpoint: str, payload: dict) -> dict:
"""Query with automatic rate limit handling."""
response = requests.post(
endpoint,
headers=headers,
json=payload,
timeout=30
)
response.raise_for_status()
return response.json()
Usage in pagination loop
for page in paginate_results():
result = safe_query(endpoint, page)
process(result)
time.sleep(0.5) # Additional delay between successful requests
Error 3: HTTP 400 Bad Request - Invalid Date Range
Symptom: {"error": "start_time must be before end_time", "code": 400}
Common causes:
- Confusing Unix timestamp (seconds) with milliseconds
- Timezone issues when parsing datetime objects
- Using future dates that exceed available data
Solution code:
from datetime import timezone
def parse_datetime_to_ms(dt: datetime) -> int:
"""
Convert datetime to Unix milliseconds consistently.
HolySheep API requires milliseconds, not seconds!
"""
if dt.tzinfo is None:
dt = dt.replace(tzinfo=timezone.utc)
# Convert to epoch seconds, then multiply by 1000
epoch_seconds = dt.timestamp()
return int(epoch_seconds * 1000)
def validate_date_range(start: datetime, end: datetime) -> tuple:
"""
Validate and normalize date range for API requests.
Returns (start_ms, end_ms) tuple ready for API call.
"""
# Ensure timezone awareness
if start.tzinfo is None:
start = start.replace(tzinfo=timezone.utc)
if end.tzinfo is None:
end = end.replace(tzinfo=timezone.utc)
# Check logical order
if start >= end:
raise ValueError(f"start ({start}) must be before end ({end})")
# Check for future dates (no data available)
now = datetime.now(timezone.utc)
if start > now:
raise ValueError(f"start date {start} is in the future")
# Cap end date to now if necessary
end = min(end, now)
start_ms = parse_datetime_to_ms(start)
end_ms = parse_datetime_to_ms(end)
return start_ms, end_ms
Correct usage
try:
start_dt = datetime(2026, 4, 1, tzinfo=timezone.utc)
end_dt = datetime(2026, 4, 2, tzinfo=timezone.utc)
start_ms, end_ms = validate_date_range(start_dt, end_dt)
result = query_deribit_options_historical(
instrument_prefix="BTC-",
start_timestamp=start_ms,
end_timestamp=end_ms
)
except ValueError as e:
print(f"Date validation error: {e}")
Error 4: Empty Results - No Data for Date Range
Symptom: {"data": [], "message": "No data available for specified range"}
Common causes:
- Requesting data older than exchange retention policy
- Using wrong instrument prefix or filter
- Holiday or weekend periods with no trading
Solution code:
def fetch_with_fallback(
instrument_prefix: str,
start: datetime,
end: datetime,
lookback_days: int = 7
) -> List[Dict]:
"""
Fetch data with automatic fallback to earlier dates if needed.
Useful for sparse options data.
"""
all_data = []
current_end = end
while len(all_data) == 0 and lookback_days > 0:
current_start = current_end - timedelta(days=1)
start_ms, end_ms = validate_date_range(current_start, current_end)
result = query_deribit_options_historical(
instrument_prefix=instrument_prefix,
start_timestamp=start_ms,
end_timestamp=end_ms
)
records = result.get('data', [])
if records:
all_data.extend(records)
print(f"Found {len(records)} records for {current_start.date()}")
else:
print(f"No data for {current_start.date()}, trying earlier...")
current_end = current_start
lookback_days -= 1
if not all_data:
# Try broader instrument search
print("Attempting to discover available instruments...")
available = discover_instruments("BTC")
print(f"Available BTC instruments: {len(available)} total")
print(f"Sample: {available[:5]}")
return all_data
def discover_instruments(underlying: str = "BTC") -> List[str]:
"""
Get list of available instruments for an underlying.
Use this to validate instrument prefixes before querying.
"""
endpoint = f"{BASE_URL}/market/deribit/instruments"
response = requests.get(
endpoint,
headers=headers,
params={"underlying": underlying, "type": "option"}
)
response.raise_for_status()
result = response.json()
return result.get('instruments', [])
Complete Example: Building a Volatility Surface
Here's a production-ready script that ties everything together:
#!/usr/bin/env python3
"""
Deribit Options Volatility Surface Builder
Uses HolySheep AI for historical tick data and AI-powered analysis
Prerequisites:
pip install requests pandas python-dateutil
Usage:
python volatility_surface.py --start 2026-04-01 --end 2026-04-30 --underlying BTC
"""
import argparse
import json
import sys
from datetime import datetime, timedelta
from typing import List, Dict, Optional
import requests
import pandas as pd
class HolySheepClient:
"""Client for HolySheep AI API with Deribit data support."""
BASE_URL = "https://api.holysheep.ai/v1"
def __init__(self, api_key: str):
self.api_key = api_key
self.session = requests.Session()
self.session.headers.update({
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
})
def query_historical_ticks(
self,
instrument: str,
start_time: int,
end_time: int,
limit: int = 10000
) -> List[Dict]:
"""Query historical tick data for specified instrument pattern."""
response = self.session.post(
f"{self.BASE_URL}/market/deribit/historical",
json={
"instrument": instrument,
"start_time": start_time,
"end_time": end_time,
"limit": limit,
"instrument_type": "option"
},
timeout=60
)
response.raise_for_status()
return response.json().get('data', [])
def analyze_with_ai(self, data: List[Dict], instruction: str) -> Dict:
"""Use AI to analyze options data. DeepSeek V3.2 at $0.42/MTok."""
endpoint = f"{self.BASE_URL}/chat/completions"
response = self.session.post(
endpoint,
json={
"model": "deepseek-v3.2",
"messages": [
{"role": "system", "content": "You are a quantitative analyst specializing in options markets."},
{"role": "user", "content": f"{instruction}\n\nData:\n{json.dumps(data[:50], indent=2)}"}
],
"temperature": 0.1
},
timeout=30
)
response.raise_for_status()
return response.json()
def get_balance(self) -> Dict:
"""Check account balance and credit status."""
response = self.session.get(f"{self.BASE_URL}/account/balance")
response.raise_for_status()
return response.json()
class VolatilitySurfaceBuilder:
"""Build implied volatility surface from tick data."""
def __init__(self, client: HolySheepClient):
self.client = client
self.data = []
def fetch_data(
self,
underlying: str,
start_date: datetime,
end_date: datetime
) -> List[Dict]:
"""Fetch options data for the specified period."""
start_ms = int(start_date.timestamp() * 1000)
end_ms = int(end_date.timestamp() * 1000)
print(f"Fetching {underlying} options from {start_date.date()} to {end_date.date()}...")
ticks = self.client.query_historical_ticks(
instrument=f"{underlying}-",
start_time=start_ms,
end_time=end_ms
)
print(f"Retrieved {len(ticks)} tick records")
self.data = ticks
return ticks
def calculate_surface(self) -> pd.DataFrame:
"""Calculate implied volatility surface by moneyness and expiry."""
df = pd.DataFrame(self.data)
if df.empty:
raise ValueError("No data available to calculate surface")
# Extract strike and expiry from instrument name
df['strike'] = df['instrument_name'].str.extract(r'-(\d+)-')[0].astype(float)
df['option_type'] = df['instrument_name'].str.extract(r'-(C|P)$')[0]
df['mid_price'] = (df['best_bid_price'] + df['best_ask_price']) / 2
# Calculate moneyness (simplified)
df['moneyness'] = df['strike'] / df['underlying_index']
# Group by moneyness buckets
df['moneyness_bucket'] = pd.cut(
df['moneyness'],
bins=[0, 0.8, 0.95, 1.05, 1.2, float('inf')],
labels=['Deep ITM', 'ITM', 'ATM', 'OTM', 'Deep OTM']
)
# Aggregate to surface
surface = df.groupby('moneyness_bucket').agg({
'mid_price': ['mean', 'std', 'count'],
'spread': 'mean'
}).round(4)
return surface
def generate_report(self) -> str:
"""Generate AI-powered analysis report."""
surface = self.calculate_surface()
analysis = self.client.analyze_with_ai(
data=surface.to_dict(),
instruction="Analyze this