เมื่อเดือนมีนาคมที่ผ่านมา ผมได้รับเชิญจากทีม Alpha Quant Lab ซึ่งเป็นสตาร์ทอัพด้านการเทรดเชิงปริมาณในกรุงเทพฯ ให้ช่วยตรวจสอบปัญหาคอขวดในไปป์ไลน์การสร้างโมเดลพื้นผิวความผันผวนโดยนัย (Implied Volatility Surface) สำหรับออปชัน ETH ทีมใช้ข้อมูลโซ่ออปชันย้อนหลังจาก Deribit เป็นแกนหลัก แต่กลับพบว่าต้นทุน LLM สำหรับการสร้างรายงานความเสี่ยงอัตโนมัติพุ่งสูงถึง 4,200 ดอลลาร์ต่อเดือน ขณะที่ค่าหน่วงเฉลี่ยอยู่ที่ 420 มิลลิวินาที หลังจากย้ายมาใช้ HolySheep AI เป็นเวลา 30 วัน ตัวเลขกลับลดลงเหลือ 180 มิลลิวินาที และบิลรายเดือนเหลือเพียง 680 ดอลลาร์ บทความนี้จะแชร์ทั้งบทเรียนทางเทคนิคในการสร้าง IV Surface และเส้นทางการย้ายระบบอย่างละเอียด
ทำไมโมเดลพื้นผิว IV ของ ETH ถึงสำคัญ
พื้นผิว IV คือโครงสร้างสามมิติที่แสดงความสัมพันธ์ระหว่างราคาใช้สิทธิ์ (Strike) เวลาคงเหลือ (Time to Maturity) และความผันผวนโดยนัย สำหรับทีม Alpha Quant Lab พื้นผิวนี้ถูกใช้เพื่อ:
- คำนวณกรีก (Greeks) สำหรับกลยุทธ์เฮดจ์แบบ Delta-Neutral และ Gamma-Scalping
- ตรวจจับความผิดปกติของตลาด เช่น Skew Inversion หรือ Term Structure ผิดเพี้ยน
- ป้อนเข้าโมเดล Monte Carlo สำหรับประเมินมูลค่าผลิตภัณฑ์ที่ซับซ้อน เช่น Exotic Options
- สร้างรายงานเชิงพรรณนาสำหรับลูกค้าและผู้บริหารกองทุน
ข้อมูลจาก Deribit มีจุดแข็งคือความลึกของสภาพคล่อง แต่มีจุดอ่อนคือ API สาธารณะมีการจำกัดอัตรา (Rate Limit) ที่ 20 requests ต่อวินาที และข้อมูลโซ่ออปชันบางชุดมี Strike ที่สภาพคล่องต่ำซึ่งต้องกรองออกก่อนการ interpolate
ขั้นตอนที่ 1: ดึงข้อมูลโซ่ออปชันย้อนหลังจาก Deribit
Deribit มี endpoint public/get_book_summary_by_currency ที่คืนค่า mark price, underlying price และ IV ของทุก Strike ทุกวันหมดอายุ เราจะดึงข้อมูลย้อนหลัง 90 วันเพื่อสร้าง Time Series ของพื้นผิว
import requests
import pandas as pd
import numpy as np
from datetime import datetime, timezone
from scipy.interpolate import RectBivariateSpline
from scipy.optimize import minimize
def fetch_eth_options_snapshot():
url = "https://www.deribit.com/api/v2/public/get_book_summary_by_currency"
params = {"currency": "ETH", "kind": "option"}
r = requests.get(url, params=params, timeout=10).json()["result"]
df = pd.DataFrame(r)
# แปลง timestamp จาก milliseconds เป็น datetime
df["expiry_dt"] = pd.to_datetime(df["expiration_timestamp"], unit="ms", utc=True)
# คำนวณ time-to-maturity เป็นปี (ใช้ 365.25 วัน)
now = pd.Timestamp.now(tz="UTC")
df["ttm"] = (df["expiry_dt"] - now).dt.total_seconds() / (365.25 * 24 * 3600)
df["ttm"] = df["ttm"].clip(lower=1/365.25) # ห้ามต่ำกว่า 1 วัน
return df
def clean_chain(df, min_oi=10, max_spread_pct=0.15):
"""กรอง Strike ที่สภาพคล่องต่ำออก"""
df = df.copy()
df["mid"] = (df["best_bid_price"] + df["best_ask_price"]) / 2
df["spread_pct"] = (df["best_ask_price"] - df["best_bid_price"]) / df["mid"]
# เก็บเฉพาะ OI >= 10 และ spread ไม่เกิน 15%
mask = (df["open_interest"] >= min_oi) & (df["spread_pct"] <= max_spread_pct)
df = df[mask & df["mark_iv"].notna()].reset_index(drop=True)
return df
ตัวอย่างการใช้งาน
raw = fetch_eth_options_snapshot()
clean = clean_chain(raw)
print(f"ดึงข้อมูลสำเร็จ {len(raw)} rows เหลือหลังกรอง {len(clean)} rows")
print(clean[["instrument_name", "strike", "ttm", "mark_iv"]].head())
ขั้นตอนที่ 2: สร้างและ Interpolate พื้นผิว IV ด้วยโมเดล SVI
หลังจากได้ตาราง (Strike, TTM, IV) แล้ว เราจะใช้โมเดล Stochastic Volatility Inspired (SVI) ในการ interpolate เพราะให้ความยืดหยุ่นสูงและไม่ก่อให้เกิด Arbitrage โดยง่าย
def svi_total_variance(k, params):
"""คำนวณ Total Variance จากพารามิเตอร์ SVI
k = log(K/F), params = (a, b, rho, m, sigma)
"""
a, b, rho, m, sigma = params
return a + b * (rho * (k - m) + np.sqrt((k - m)**2 + sigma**2))
def fit_svi_slice(strikes, forwards, ivs, ttm):
"""Fit SVI ให้กับ 1 slice ของ TTM"""
k = np.log(strikes / forwards)
w = ivs**2 * ttm # total variance
# พารามิเตอร์เริ่มต้น
x0 = [0.04, 0.4, -0.3, 0.0, 0.1]
bounds = [(-0.1, 1.0), (0.01, 5.0), (-0.999, 0.999), (-2.0, 2.0), (0.001, 2.0)]
def loss(p):
return np.mean((svi_total_variance(k, p) - w)**2)
res = minimize(loss, x0, method="L-BFGS-B", bounds=bounds)
return res.x
def build_iv_surface(clean_df, spot_price):
"""สร้าง Surface แบบ slice-by-slice"""
surface = []
for ttm, group in clean_df.groupby("ttm"):
if len(group) < 5:
continue
strikes = group["strike"].values
ivs = group["mark_iv"].values / 100.0 # Deribit คืนเป็น %
params = fit_svi_slice(strikes, spot_price, ivs, ttm)
surface.append({"ttm": ttm, "params": params, "strikes": strikes})
return pd.DataFrame(surface)
สมมติ spot = 3500 USD
surface = build_iv_surface(clean, spot_price=3500)
print(f"Fit สำเร็จ {len(surface)} slices ของ TTM")
ขั้นตอนที่ 3: สร้างรายงานความเสี่ยงอัตโนมัติด้วย HolySheep AI
หลังจากได้พื้นผิว IV แล้ว ทีม Alpha Quant Lab ต้องการให้ LLM อ่านค่า Skew และ Term Structure แล้วสร้างคอมเมนทารี่ภาษาไทยสำหรับรายงานประจำวัน เนื่องจากต้องเรียกหลายร้อยครั้งต่อวัน พวกเขาจึงเลือกใช้ DeepSeek V3.2 ผ่าน HolySheep ซึ่งคิดราคาเพียง 0.42 ดอลลาร์ต่อล้านโทเคน
import openai
client = openai.OpenAI(
base_url="https://api.holysheep.ai/v1",
api_key="YOUR_HOLYSHEEP_API_KEY"
)
def generate_iv_report(skew_25d, term_slope, atm_iv, recent_events):
"""สร้างคอมเมนทารี่จากตัวเลข IV Surface"""
prompt = f"""วิเคราะห์โครงสร้างความผันผวนของ ETH วันนี้:
- ATM IV (30 วัน): {atm_iv:.2%}
- 25-delta Skew: {skew_25d:+.2%}
- Term Slope (1M vs 3M): {term_slope:+.2%}
- เหตุการณ์ล่าสุด: {recent_events}
เขียนคอมเมนทารี่ 3-4 ประโยคภาษาไทยสำหรับรายงานประจำวัน"""
resp = client.chat.completions.create(
model="deepseek-v3.2",
messages=[
{"role": "system", "content": "คุณเป็นนักวิเคราะห์ความผันผวนมืออาชีพ เขียนกระชับ ใช้ศัพท์ทางการเงินที่ถูกต้อง"},
{"role": "user", "content": prompt}
],
temperature=0.3,
max_tokens=400
)
return resp.choices[0].message.content
ตัวอย่าง
report = generate_iv_report(
skew_25d=-0.045,
term_slope=0.012,
atm_iv=0.62,
recent_events="ETH spot ETF inflow 50M USD เมื่อวาน"
)
print(report)