暗号資産市場のオプション取引において、波动率曲面(Volatility Surface)は原資産価格、権利行使価格、残存期間の3次元でインプライド波动率を表現する最も重要な分析手法です。本稿では、HolySheep AI の高性能APIを活用した暗号資産オプション波动率曲面の可視化システムを構築します。
波动率曲面とは
波动率曲面は、以下の3次元で構成されます:
- X軸(Strike):権利行使価格
- Y軸(Tenor):残存期間(年換算)
- Z軸(Volatility):インプライド波动率
この曲面を正確に可視化することで、德語期权市場の構造や歪み、非対称性を視覚的に把握できます。
前提条件と環境構築
# 必要なライブラリのインストール
pip install numpy pandas matplotlib scipy requests pandas-datareader
pip install mplfinance plotly kaleido # 追加の可視化ライブラリ
Pythonバージョン確認
python --version
Python 3.9 以上を推奨
# 初期設定とHolySheep API接続確認
import requests
import json
HolySheep AI API接続テスト
base_url = "https://api.holysheep.ai/v1"
api_key = "YOUR_HOLYSHEEP_API_KEY"
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
接続確認リクエスト
test_response = requests.get(
f"{base_url}/models",
headers=headers,
timeout=10
)
print(f"接続状態: {test_response.status_code}")
if test_response.status_code == 200:
print("HolySheep API接続成功")
print(f"利用可能なモデル一覧取得完了")
else:
print(f"エラー: {test_response.status_code}")
print(test_response.text)
データ収集:HolySheep AI APIからの市場データ取得
暗号資産オプションのデータ取得において、HolySheep AI APIは非常に低レイテンシ(50ms未満)で応答し、レートも¥1=$1という破格の安さです。登録するだけで無料クレジットが手に入るのも大きなメリットです。
import numpy as np
import pandas as pd
from scipy.interpolate import griddata
from scipy.stats import norm
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import warnings
warnings.filterwarnings('ignore')
暗号資産オプション価格データ(モックデータ生成)
def generate_options_data():
"""
BTCオプションの模拟データ生成
実際にはDeribit、OKEx、Bybit等のAPIから取得
"""
np.random.seed(42)
# 権利行使価格範囲(BTC価格に対するパーセンテージ)
strikes_pct = np.array([70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130])
# 残存期間(日数)
tenors = np.array([7, 14, 30, 60, 90, 180, 365]) / 365.0
# ATM(価値を少し高める)基础波动率
atm_vols = np.array([0.85, 0.78, 0.65, 0.55, 0.50, 0.45, 0.40])
# IV曲面データ生成(スマイル效应と期限構造を考慮)
data = []
spot_price = 45000 # BTC現物価格
for i, tenor in enumerate(tenors):
base_vol = atm_vols[i]
for strike_pct in strikes_pct:
strike = spot_price * (strike_pct / 100)
# スマイル効果(OTM-optionsに波动率上がり)
moneyness = np.log(spot_price / strike) / np.sqrt(tenor)
smile_effect = 0.15 * np.exp(-moneyness**2 / 2) * np.sign(moneyness)
# 短期オプションのスマイル効果大
term_structure_effect = 0.1 * (1 - tenor) * np.abs(moneyness)
iv = base_vol + smile_effect + term_structure_effect
iv = max(0.1, min(iv, 2.0)) # 波动率の範囲制限
# Black-Scholes理論価格計算
t = tenor
r = 0.05 # リスクフリーレート
q = 0.0 # 配当利回り
d1 = (np.log(spot_price / strike) + (r - q + 0.5 * iv**2) * t) / (iv * np.sqrt(t))
d2 = d1 - iv * np.sqrt(t)
call_price = spot_price * norm.cdf(d1) - strike * np.exp(-r * t) * norm.cdf(d2)
data.append({
'strike': strike,
'tenor': tenor,
'tenor_days': int(tenor * 365),
'moneyness': strike_pct,
'implied_vol': iv,
'call_price': call_price,
'delta': norm.cdf(d1)
})
return pd.DataFrame(data)
データフレーム生成
options_df = generate_options_data()
print("=" * 60)
print("暗号資産オプション波动率データ")
print("=" * 60)
print(f"総レコード数: {len(options_df)}")
print(f"\n残存期間別平均IV:")
print(options_df.groupby('tenor_days')['implied_vol'].mean().round(4))
print(f"\n権利行使価格別IV(残存30日):")
print(options_df[options_df['tenor_days'] == 30][['moneyness', 'implied_vol']].to_string(index=False))
3次元波动率曲面の作成
def create_volatility_surface_3d(df, title="BTCオプション 波动率曲面"):
"""
3次元波动率曲面のプロット
"""
fig = plt.figure(figsize=(16, 12))
ax = fig.add_subplot(111, projection='3d')
# グリッドデータの準備
strikes = df['strike'].unique()
tenors = df['tenor'].unique()
# .meshgrid でグリッド作成
Strike, Tenor = np.meshgrid(
np.linspace(min(strikes), max(strikes), 50),
np.linspace(min(tenors), max(tenors), 50)
)
# 插値による曲面補間
points = df[['strike', 'tenor']].values
values = df['implied_vol'].values
Volatility = griddata(
points,
values,
(Strike, Tenor),
method='cubic'
)
# NaN処理
Volatility = np.nan_to_num(Volatility, nan=np.nanmean(values))
# 3次元曲面プロット
surf = ax.plot_surface(
Strike / 1000, # BTC価格をkUSD単位で表示
Tenor * 365, # 日数に変換
Volatility * 100, # 百分比に変換
cmap='RdYlGn_r',
edgecolor='none',
alpha=0.85,
antialiased=True
)
# カラーバーの追加
cbar = fig.colorbar(surf, ax=ax, shrink=0.5, aspect=20, pad=0.1)
cbar.set_label('インプライド波动率 (%)', fontsize=12)
# ラベルの設定
ax.set_xlabel('権利行使価格 (kUSD)', fontsize=12, labelpad=10)
ax.set_ylabel('残存期間 (日)', fontsize=12, labelpad=10)
ax.set_zlabel('IV (%)', fontsize=12, labelpad=10)
ax.set_title(title, fontsize=16, fontweight='bold', pad=20)