Trong thị trường crypto derivatives, Deribit là sàn giao dịch quyền chọn (options) lớn nhất thế giới tính theo khối lượng open interest. Việc khai thác dữ liệu lịch sử của options chain để xây dựng Implied Volatility (IV) Surface (bề mặt biến động ngụy trang) là một kỹ năng quan trọng cho quản lý rủi ro, định giá quyền chọn, và xây dựng chiến lược delta-neutral.
Bài viết này sẽ hướng dẫn bạn từ cơ bản đến nâng cao: cách tải dữ liệu options chain từ Deribit, xử lý dữ liệu, và cuối cùng là tái tạo IV surface một cách chính xác.
Bảng So Sánh: HolySheep vs API Chính Thức Deribit vs Các Dịch Vụ Relay
| Tiêu chí | HolySheep AI | API Deribit Chính Thức | AmberData | CoinAPI |
|---|---|---|---|---|
| Phí hàng tháng | Từ $0 (credit miễn phí) | Miễn phí tier cơ bản | Từ $299/tháng | Từ $79/tháng |
| Độ trễ trung bình | <50ms | ~100-200ms | ~150ms | ~300ms |
| Hỗ trợ historical data | ✅ Đầy đủ | ✅ Có giới hạn | ✅ Có giới hạn | ✅ Đầy đủ |
| Streaming real-time | ✅ WebSocket | ✅ WebSocket | ✅ WebSocket | ✅ WebSocket |
| Rate limit | Kiên nhẫn (fair usage) | 60 req/s | Tùy gói | Tùy gói |
| IV surface data | ✅ API riêng | ❌ Phải tính thủ công | ✅ Có | ❌ Không |
| Thanh toán | ¥/USD, WeChat, Alipay | Chỉ crypto | Thẻ/Crypto | Thẻ/Crypto |
| Phù hợp cho | Dev cá nhân, backtesting | Production trading | Enterprise | Data aggregation |
Deribit Options Chain: Cấu Trúc Dữ Liệu
Trước khi đi vào code, chúng ta cần hiểu cấu trúc dữ liệu options chain của Deribit. Deribit sử dụng cấu trúc phân cấp theo instrument (công cụ), mỗi instrument có các thuộc tính quan trọng:
- instrument_name: VD "BTC-28MAR25-95000-C" (BTC, ngày đáo hạn 28/03/2025, strike 95000, Call)
- underlying_index: "btc_usd" hoặc "eth_usd"
- expiration_timestamp: Unix timestamp của ngày đáo hạn
- tick_size: Bước giá tối thiểu
- option_type: "call" hoặc "put"
Cài Đặt Môi Trường và Thư Viện
# Cài đặt các thư viện cần thiết
pip install requests pandas numpy scipy matplotlib py_vollove seaborn
pip install websockets-client asyncio aiohttp
Kiểm tra phiên bản
python --version # Python 3.9+ được khuyến nghị
Cài đặt thư viện Deribit chính thức (tùy chọn)
pip install deribit-websockets
Tải Dữ Liệu Options Chain Từ Deribit API
Deribit cung cấp API miễn phí với endpoint public/get_book_summary_by_currency và public/get_options_by_currency. Tuy nhiên, để tăng tốc độ và giảm thiểu rate limit, chúng ta sử dụng HolySheep AI như một proxy với độ trễ thấp hơn 50ms.
import requests
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
import time
========== CẤU HÌNH API ==========
Sử dụng HolySheep AI thay vì API trực tiếp để giảm độ trễ & tiết kiệm chi phí
HolySheep: <50ms latency, tiết kiệm 85%+ so với API chính thức
HOLYSHEEP_BASE_URL = "https://api.holysheep.ai/v1"
API_KEY = "YOUR_HOLYSHEEP_API_KEY" # Thay bằng API key của bạn
========== CLASS DERIBIT DATA FETCHER ==========
class DeribitOptionsFetcher:
"""
Fetcher dữ liệu options chain từ Deribit qua HolySheep AI proxy
Độ trễ trung bình: <50ms (so với 100-200ms qua API trực tiếp)
"""
def __init__(self, api_key: str, use_holy_sheep: bool = True):
self.api_key = api_key
self.use_holy_sheep = use_holy_sheep
self.base_url = HOLYSHEEP_BASE_URL if use_holy_sheep else "https://www.deribit.com/api/v2"
def _make_request(self, method: str, params: dict) -> dict:
"""Thực hiện request với xử lý lỗi"""
headers = {
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"
}
payload = {
"jsonrpc": "2.0",
"method": method,
"params": params,
"id": int(time.time() * 1000)
}
try:
response = requests.post(
f"{self.base_url}/public/{method.replace('public/', '')}",
json=payload,
headers=headers,
timeout=10
)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
print(f"❌ Lỗi request: {e}")
return {"result": None, "error": str(e)}
def get_all_options(self, currency: str = "BTC", kind: str = "option") -> pd.DataFrame:
"""
Lấy toàn bộ danh sách options cho một loại tiền
currency: 'BTC' hoặc 'ETH'
"""
print(f"📡 Đang tải options chain cho {currency}...")
# Gọi API lấy tất cả instruments
result = self._make_request(
"public/get_all_instruments",
{"currency": currency, "kind": kind, "expired": False}
)
if "result" in result and result["result"]:
df = pd.DataFrame(result["result"])
print(f"✅ Đã tải {len(df)} instruments")
return df
return pd.DataFrame()
def get_option_details(self, instrument_name: str) -> dict:
"""Lấy chi tiết của một option cụ thể"""
result = self._make_request(
"public/get_instrument",
{"instrument_name": instrument_name}
)
return result.get("result", {})
def get_orderbook(self, instrument_name: str, depth: int = 10) -> dict:
"""
Lấy orderbook của một option
Bao gồm: best_bid, best_ask, implied_volatility
"""
result = self._make_request(
"public/get_order_book",
{"instrument_name": instrument_name, "depth": depth}
)
return result.get("result", {})
def get_historical_volatility(self, currency: str, period: int = 30) -> pd.DataFrame:
"""
Lấy historical volatility của underlying asset
period: số ngày tính HV (30, 60, 90, ...365)
"""
result = self._make_request(
"public/get_historical_volatility",
{"currency": currency}
)
if "result" in result and result["result"]:
df = pd.DataFrame(result["result"])
df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')
return df
return pd.DataFrame()
========== SỬ DỤNG ==========
Khởi tạo fetcher với HolySheep AI
fetcher = DeribitOptionsFetcher(api_key=API_KEY, use_holy_sheep=True)
Lấy danh sách tất cả options
options_df = fetcher.get_all_options(currency="BTC")
Lấy orderbook cho một option cụ thể
sample_option = "BTC-28MAR25-95000-C"
orderbook = fetcher.get_orderbook(sample_option)
print(f"📊 Orderbook cho {sample_option}:")
print(f" Best Bid: {orderbook.get('best_bid_price')}")
print(f" Best Ask: {orderbook.get('best_ask_price')}")
print(f" IV Bid: {orderbook.get('best_bid_iv')}")
print(f" IV Ask: {orderbook.get('best_ask_iv')}")
Xây Dựng IV Surface Từ Dữ Liệu Deribit
Sau khi đã có dữ liệu orderbook cho tất cả các strikes và expirations, bước tiếp theo là xây dựng Implied Volatility Surface. IV surface là một ma trận 3 chiều: Strike Price (X) × Time to Expiration (Y) × Implied Volatility (Z).
import numpy as np
import pandas as pd
from scipy.interpolate import griddata, RBFInterpolator
from scipy.stats import norm
from scipy.optimize import brentq
import warnings
warnings.filterwarnings('ignore')
========== BLACK-SCHOLES IMPLIED VOLATILITY CALCULATOR ==========
def black_scholes_price(S, K, T, r, sigma, option_type='call'):
"""
Tính giá lý thuyết Black-Scholes
S: Giá underlying
K: Strike price
T: Thời gian đến đáo hạn (năm)
r: Lãi suất risk-free
sigma: Độ biến động
option_type: 'call' hoặc 'put'
"""
if T <= 0 or sigma <= 0:
return 0
d1 = (np.log(S / K) + (r + 0.5 * sigma ** 2) * T) / (sigma * np.sqrt(T))
d2 = d1 - sigma * np.sqrt(T)
if option_type == 'call':
price = S * norm.cdf(d1) - K * np.exp(-r * T) * norm.cdf(d2)
else:
price = K * np.exp(-r * T) * norm.cdf(-d2) - S * norm.cdf(-d1)
return price
def implied_volatility(market_price, S, K, T, r, option_type='call',
sigma_low=0.001, sigma_high=5.0):
"""
Tính Implied Volatility bằng phương pháp Brent
market_price: Giá thị trường thực tế
Sử dụng Brent q method cho tốc độ và độ chính xác cao
"""
if T <= 0:
return np.nan
# Kiểm tra intrinsic value
if option_type == 'call':
intrinsic = max(S - K * np.exp(-r * T), 0)
else:
intrinsic = max(K * np.exp(-r * T) - S, 0)
if market_price <= intrinsic:
return np.nan
def objective(sigma):
return black_scholes_price(S, K, T, r, sigma, option_type) - market_price
try:
# Sử dụng Brent method - hội tụ nhanh và ổn định
iv = brentq(objective, sigma_low, sigma_high, maxiter=100)
return iv
except ValueError:
# Nếu không hội tụ, thử các phương pháp khác
return np.nan
========== IV SURFACE RECONSTRUCTOR ==========
class IVSurfaceReconstructor:
"""
Tái tạo Implied Volatility Surface từ dữ liệu options chain
Sử dụng RBF (Radial Basis Function) interpolation cho surface mượt mà
"""
def __init__(self, risk_free_rate: float = 0.05):
self.r = risk_free_rate # Lãi suất risk-free (5% annual)
self.iv_data = None
self.S = None # Underlying price
self.surface_model = None
def load_from_orderbooks(self, orderbooks: list, underlying_price: float):
"""
Load dữ liệu IV từ danh sách orderbooks
orderbooks: list of dict với cấu trúc:
{
'instrument_name': 'BTC-28MAR25-95000-C',
'bid_price': 0.05,
'ask_price': 0.06,
'expiration': '2025-03-28',
'strike': 95000,
'option_type': 'call'
}
underlying_price: Giá spot hiện tại của underlying
"""
self.S = underlying_price
iv_list = []
for ob in orderbooks:
# Tính mid price
mid_price = (ob['bid_price'] + ob['ask_price']) / 2
# Tính IV từ mid price
T = self._time_to_expiration(ob['expiration'])
K = ob['strike']
iv = implied_volatility(
market_price=mid_price,
S=self.S,
K=K,
T=T,
r=self.r,
option_type=ob['option_type']
)
if not np.isnan(iv):
iv_list.append({
'strike': K,
'time_to_expiry': T,
'iv': iv,
'moneyness': K / self.S,
'option_type': ob['option_type']
})
self.iv_data = pd.DataFrame(iv_list)
print(f"📊 Đã load {len(self.iv_data)} điểm dữ liệu IV")
def _time_to_expiration(self, expiration_str: str) -> float:
"""Chuyển đổi chuỗi ngày thành thời gian đến đáo hạn (năm)"""
try:
exp_date = pd.to_datetime(expiration_str)
T = (exp_date - pd.Timestamp.now()).days / 365.0
return max(T, 1/365) # Tối thiểu 1 ngày
except:
return np.nan
def build_surface(self, method='rbf'):
"""
Xây dựng IV surface từ dữ liệu
method: 'rbf' (Radial Basis Function) hoặc 'spline' (Cubic Spline)
RBF cho surface mượt mà hơn, xử lý tốt dữ liệu thưa
"""
if self.iv_data is None or len(self.iv_data) == 0:
raise ValueError("Không có dữ liệu IV. Vui lòng load dữ liệu trước.")
# Chuẩn bị dữ liệu
X = self.iv_data[['moneyness', 'time_to_expiry']].values
y = self.iv_data['iv'].values
if method == 'rbf':
# RBF interpolation - tốt cho surface phức tạp
self.surface_model = RBFInterpolator(X, y, kernel='thin_plate_spline', smoothing=0.1)
print("✅ Đã xây dựng IV surface bằng RBF (Thin Plate Spline)")
else:
# Grid-based interpolation
from scipy.interpolate import CloughTocher2DInterpolator
self.surface_model = CloughTocher2DInterpolator(X, y)
print("✅ Đã xây dựng IV surface bằng Cubic Spline")
return self
def get_iv_at(self, moneyness: float, time_to_expiry: float) -> float:
"""Lấy giá trị IV tại một điểm cụ thể (moneyness, TTE)"""
if self.surface_model is None:
raise ValueError("Surface chưa được xây dựng. Gọi build_surface() trước.")
point = np.array([[moneyness, time_to_expiry]])
return float(self.surface_model(point)[0])
def generate_surface_grid(self, moneyness_range=(0.7, 1.3),
tte_range=(0.02, 1.0),
resolution=50):
"""
Tạo grid cho việc visualize IV surface
Returns: tuple of (M, T, IV) arrays cho plotting
"""
moneyness_grid = np.linspace(moneyness_range[0], moneyness_range[1], resolution)
tte_grid = np.linspace(tte_range[0], tte_range[1], resolution)
M, T = np.meshgrid(moneyness_grid, tte_grid)
points = np.column_stack([M.ravel(), T.ravel()])
IV = self.surface_model(points).reshape(M.shape)
return M, T, IV
========== VÍ DỤ SỬ DỤNG ==========
Tạo dữ liệu mẫu (thay bằng dữ liệu thực từ Deribit)
np.random.seed(42)
S = 95000 # BTC price
Tạo sample orderbooks cho các strikes và expirations
expirations = ['2025-03-28', '2025-04-25', '2025-05-30', '2025-06-27', '2025-09-26']
strikes = np.linspace(80000, 110000, 31)
sample_orderbooks = []
for exp in expirations:
for strike in strikes:
# Tạo giá bid-ask giả lập với IV thay đổi theo strike (smile effect)
moneyness = strike / S
T = (pd.to_datetime(exp) - pd.Timestamp.now()).days / 365.0
# IV có smile: cao hơn ở OTM options
base_iv = 0.6 + 0.1 * abs(moneyness - 1.0)
iv = base_iv + np.random.normal(0, 0.02)
# Tính giá từ IV
K = strike
call_price = black_scholes_price(S, K, T, 0.05, iv, 'call')
sample_orderbooks.append({
'instrument_name': f'BTC-{exp.replace("-","")}-{int(strike)}-C',
'bid_price': call_price * 0.98,
'ask_price': call_price * 1.02,
'expiration': exp,
'strike': strike,
'option_type': 'call'
})
Xây dựng IV surface
reconstructor = IVSurfaceReconstructor(risk_free_rate=0.05)
reconstructor.load_from_orderbooks(sample_orderbooks, underlying_price=S)
reconstructor.build_surface(method='rbf')
Lấy IV tại một số điểm
print("\n📈 IV tại một số điểm mẫu:")
test_cases = [
(0.9, 0.1), # ITM 10%, 1 tháng
(1.0, 0.1), # ATM, 1 tháng
(1.1, 0.1), # OTM 10%, 1 tháng
(1.0, 0.5), # ATM, 6 tháng
(1.0, 1.0), # ATM, 1 năm
]
for m, t in test_cases:
iv = reconstructor.get_iv_at(m, t)
print(f" Moneyness={m:.2f}, TTE={t:.2f}y → IV={iv:.2%}")
Visualize IV Surface
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import seaborn as sns
def plot_iv_surface(reconstructor: IVSurfaceReconstructor, save_path: str = None):
"""
Visualize IV Surface dưới dạng 3D surface plot và heatmap
"""
# Tạo grid cho surface
M, T, IV = reconstructor.generate_surface_grid(
moneyness_range=(0.75, 1.25),
tte_range=(0.02, 0.9),
resolution=60
)
fig = plt.figure(figsize=(16, 6))
# ========== 3D Surface Plot ==========
ax1 = fig.add_subplot(121, projection='3d')
surf = ax1.plot_surface(M, T, IV, cmap='viridis',
linewidth=0, antialiased=True, alpha=0.9)
ax1.set_xlabel('Moneyness (K/S)', fontsize=10)
ax1.set_ylabel('Time to Expiry (years)', fontsize=10)
ax1.set_zlabel('Implied Volatility', fontsize=10)
ax1.set_title('IV Surface - 3D View', fontsize=12, fontweight='bold')
ax1.view_init(elev=25, azim=45)
fig.colorbar(surf, ax=ax1, shrink=0.5, aspect=10, label='IV')
# ========== Heatmap (Strike × TTE) ==========
ax2 = fig.add_subplot(122)
# Chuyển đổi moneyness về strike price để dễ hiểu
strikes = M * reconstructor.S
sns.heatmap(IV, cmap='RdYlGn_r', ax=ax2,
xticklabels=10, yticklabels=10,
cbar_kws={'label': 'Implied Volatility'})
ax2.set_xlabel('Strike Price', fontsize=10)
ax2.set_ylabel('Time to Expiry', fontsize=10)
ax2.set_title('IV Surface - Heatmap', fontsize=12, fontweight='bold')
# Đặt tick labels
ax2.set_xticklabels([f'{int(strikes[0, i]):,}₽' for i in range(0, len(M[0]), 10)])
ax2.set_yticklabels([f'{T[i, 0]:.2f}' for i in range(0, len(T), 10)])
plt.tight_layout()
if save_path:
plt.savefig(save_path, dpi=150, bbox_inches='tight')
print(f"✅ Đã lưu chart vào {save_path}")
plt.show()
Vẽ IV surface
plot_iv_surface(reconstructor, save_path='iv_surface.png')
========== Vẽ IV Smile theo thời gian ==========
def plot_iv_smile_by_expiry(iv_data: pd.DataFrame, reconstructor: IVSurfaceReconstructor):
"""Vẽ IV smile cho các expiration khác nhau"""
fig, ax = plt.subplots(figsize=(12, 6))
expirations = iv_data['time_to_expiry'].unique()
expirations = np.sort(expirations)[::2] # Lấy mỗi expiration thứ 2
colors = plt.cm.viridis(np.linspace(0, 1, len(expirations)))
for i, tte in enumerate(expirations[:5]): # Giới hạn 5 đường
# Filter data cho TTE này
mask = iv_data['time_to_expiry'] == tte
df_subset = iv_data[mask].sort_values('strike')
ax.plot(df_subset['moneyness'], df_subset['iv'],
'o-', color=colors[i],
label=f'TTE = {tte:.2f}y',
markersize=4, linewidth=1.5, alpha=0.8)
ax.set_xlabel('Moneyness (K/S)', fontsize=11)
ax.set_ylabel('Implied Volatility', fontsize=11)
ax.set_title('IV Smile - Biến động theo Strike và Thời gian', fontsize=13, fontweight='bold')
ax.legend(title='Thời gian đáo hạn')
ax.grid(True, alpha=0.3)
ax.axvline(x=1.0, color='red', linestyle='--', alpha=0.5, label='ATM')
plt.tight_layout()
plt.show()
plot_iv_smile_by_expiry(reconstructor.iv_data, reconstructor)
HolySheep AI Cho Các Tác Vụ Quan Trọng
Trong pipeline xây dựng IV surface, có nhiều bước phù hợp để sử dụng HolySheep AI như một công cụ hỗ trợ:
import requests
import json
HOLYSHEEP_API_KEY = "YOUR_HOLYSHEEP_API_KEY"
HOLYSHEEP_URL = "https://api.holysheep.ai/v1/chat/completions"
def analyze_iv_surface_with_ai(iv_data_summary: str, market_context: str) -> str:
"""
Sử dụng AI để phân tích IV surface và đưa ra insights
iv_data_summary: Tóm tắt dữ liệu IV (ví dụ: min, max, mean IV theo TTE)
market_context: Bối cảnh thị trường hiện tại
Chi phí ước tính (2026 pricing):
- DeepSeek V3.2: $0.42/MTok (tiết kiệm 85%+)
- Gemini 2.5 Flash: $2.50/MTok
"""
prompt = f"""Bạn là chuyên gia phân tích derivatives và quản lý rủi ro.
Dữ liệu IV Surface:
{iv_data_summary}
Bối cảnh thị trường:
{market_context}
Hãy phân tích:
1. Đặc điểm của IV surface hiện tại (smile/skew, term structure)
2. Các cơ hội arbitrage tiềm năng
3. Khuyến nghị delta hedging
4. Rủi ro và cảnh báo"""
payload = {
"model": "deepseek-chat", # Sử dụng DeepSeek V3.2 - chi phí thấp nhất
"messages": [
{"role": "system", "content": "Bạn là chuyên gia phân tích derivatives."},
{"role": "user", "content": prompt}
],
"temperature": 0.3,
"max_tokens": 1000
}
headers = {
"Authorization": f"Bearer {HOLYSHEEP_API_KEY}",
"Content-Type": "application/json"
}
try:
response = requests.post(HOLYSHEEP_URL, json=payload, headers=headers, timeout=30)
result = response.json()
if 'choices' in result:
return result['choices'][0]['message']['content']
else:
return f"Lỗi: {result}"
except Exception as e:
return f"Lỗi khi gọi API: {str(e)}"
def generate_backtest_report(iv_data: pd.DataFrame, pnl_series: pd.Series) -> str:
"""
Tạo báo cáo backtest chi tiết với AI
Chi phí: ~$0.01-0.05 cho mỗi báo cáo (DeepSeek V3.2)
"""
stats = {
'total_trades': len(pnl_series),
'win_rate': (pnl_series > 0).mean(),
'avg_pnl': pnl_series.mean(),
'sharpe_ratio': pnl_series.mean() / pnl_series.std() * np.sqrt(252) if pnl_series.std() > 0 else 0,
'max_drawdown': (pnl_series.cumsum() / pnl_series.cumsum().cummax() - 1).min(),
'iv_data_points': len(iv_data)
}
prompt = f"""Tạo báo cáo backtest chi tiết cho chiến lược delta-neutral sử dụng IV surface:
Thống kê:
- Số lệnh: {stats['total_trades']}
- Win rate: {stats['win_rate']:.2%}
- PnL trung bình: ${stats['avg_pnl']:.2f}
- Sharpe Ratio: {stats['sharpe_ratio']:.2f}
- Max Drawdown: {stats['max_drawdown']:.2%}
Hãy đưa ra:
1. Đánh giá hiệu suất chiến lược
2. Phân tích rủi ro
3. Khuyến nghị cải thiện"""
payload = {
"model": "deepseek-chat",
"messages": [
{"role": "system", "content": "Bạn là chuyên gia quantitative trading."},
{"role": "user", "content": prompt}
],
"temperature": 0.2,
"max_tokens": 800
}
headers = {
"Authorization": f"Bearer {HOLYSHEEP_API_KEY}",
"Content-Type": "application/json"
}
response = requests.post(HOLYSHEEP_URL, json=payload, headers=headers, timeout=30)
return response.json().get('choices', [{}])[0].get('message', {}).get('content', '')
========== VÍ DỤ SỬ DỤNG ==========
Tóm