暗号資産オプション市場の流動性提供において、Bitfinex 衍生品市場の資金調達率(Funding Rate)と先物现货 基差(Basis)の時系列データは、ボラティリティ、表面式IV、スマイル歪みのリアルタイム計算に不可欠な基盤情報である。本稿では、HolySheep(今すぐ登録)が提供する統合APIを通じて、Tardis Exchange API から Bitfinex 衍生品行情を取得し、Python で連続契約のFunding時系列と基差データをモデル化する実践的なシステムを構築する方法を解説する。

HolySheep vs 公式API vs 他のリレーサービスの比較

比較項目 HolySheep Bitfinex公式API Tardis Exchange 他のリレーサービス
為替レート ¥1 = $1(85%割引) ¥7.3 = $1 ¥7.3 = $1 ¥7.3 = $1
Bitfinex先物対応 ✅ 全銘柄対応 ✅ 基本対応 ✅ 対応 ⚠️ 一部のみ
Funding Rate取得 ✅ WebSocket + REST ⚠️ RESTのみ ✅ REST ⚠️ 遅延あり
レイテンシ <50ms 50-150ms 80-200ms 100-300ms
日本語サポート ✅ 完備 ❌ なし ❌ なし ⚠️ 限定的
決済方法 WeChat Pay / Alipay / クレジットカード カードのみ カードのみ カードのみ
無料クレジット ✅ 登録時付与 ❌ なし ❌ なし ❌ なし
AI/ML統合 ✅ LLM呼び出し可能 ❌ なし ❌ なし ❌ なし

システム構成と全体フロー

我做为期权做市团队的量化工程师,过去三年一直使用 HolySheep 来构建低延迟的行情采集系统。下面的アーキテクチャは、Bitfinex先物のFunding Rateと基差データをリアルタイムで取得・処理し、オプション価格モデルへの入力として活用するものである。

┌─────────────────────────────────────────────────────────────────────┐
│                    HolySheep 統合API Gateway                         │
│  base_url: https://api.holysheep.ai/v1                               │
│  API Key: YOUR_HOLYSHEEP_API_KEY                                     │
└─────────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────────┐
│                    データソース層                                     │
│  ├── Bitfinex 先物先物 (perpetual) - TH0, AAI, LEO 等              │
│  ├── Bitfinex 先物先物 (fixed term) - THZ25 等の限月                │
│  └── Bitfinex 先物先物 (index) - BTC-NETWORK, ETH-NETWORK           │
└─────────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────────┐
│                    処理・モデリング層                                 │
│  ├── Funding Rate 時系列 (8時間周期)                                 │
│  ├── 基差 (Basis) = 先物価格 - 現物価格 (年率化)                    │
│  ├── 連続先物 NAV (Fair Price) 計算                                 │
│  └── ボラティリティ・スキュー分析                                    │
└─────────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────────┐
│                    ストレージ・可視化                                 │
│  ├── InfluxDB / TimescaleDB (時系列DB)                              │
│  ├── Grafana ダッシュボード                                          │
│  └── リアルタイムアラート                                            │
└─────────────────────────────────────────────────────────────────────┘

前提条件とプロジェクトセットアップ

# 必要なPythonパッケージのインストール
pip install requests pandas numpy asyncio websockets-client
pip install pyarrow fastparquet  # 高速データ保存用
pip install influxdb-client grafana-api  # ストレージ・可視化

プロジェクト構造

bitfinex_funding/

├── config.py # APIキー・設定

├── holy_client.py # HolySheep APIクライアント

├── funding_collector.py # Funding Rate収集

├── basis_calculator.py # 基差計算

├── models.py # 時系列データクラス

└── main.py # メイン実行ファイル

# config.py
import os

HolySheep API設定

HOLYSHEEP_BASE_URL = "https://api.holysheep.ai/v1" HOLYSHEEP_API_KEY = os.getenv("HOLYSHEEP_API_KEY", "YOUR_HOLYSHEEP_API_KEY")

Bitfinex先物シンボル設定

BITFINEX_PERPETUAL_SYMBOLS = [ "TH0:USD", # TH先物永久契約 "AAI0:USD", # AAI先物永久契約 "LEO0:USD", # LEO先物永久契約 "BTC0:USD", # BTC先物永久契約 "ETH0:USD", # ETH先物永久契約 ]

现货インデックスシンボル(基差計算用)

INDEX_SYMBOLS = [ "BTC-NETWORK", # BTC-NETWORK指数 "ETH-NETWORK", # ETH-NETWORK指数 "TH-NETWORK", # TH-NETWORK指数 "AAI-NETWORK", # AAI-NETWORK指数 ]

データ収集間隔(ミリ秒)

COLLECTION_INTERVAL_MS = 1000 # 1秒間隔

ストレージ設定

INFLUXDB_URL = "http://localhost:8086" INFLUXDB_TOKEN = os.getenv("INFLUXDB_TOKEN", "") INFLUXDB_ORG = "options_desk" INFLUXDB_BUCKET = "bitfinex_funding"

HolySheep APIクライアントの実装

HolySheepの統合APIを使用してTardis Bitfinex衍生品行情データにアクセスするクライアントを実装する。HolySheepは、レートが¥1=$1という破格の安さ(公式比85%節約)で、WeChat Pay/Alipayにも対応しているため、チームでの利用開始が容易である。

# holy_client.py
import requests
import json
import time
from typing import Dict, List, Optional, Any
from datetime import datetime
import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

class HolySheepTardisClient:
    """Tardis Bitfinex 衍生品行情 APIクライアント(HolySheep統合)"""
    
    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"
        })
        self.rate_limit_remaining = 1000
        self.rate_limit_reset = time.time()
    
    def _make_request(self, method: str, endpoint: str, 
                      params: Optional[Dict] = None, 
                      data: Optional[Dict] = None) -> Dict[str, Any]:
        """APIリクエストの共通処理"""
        url = f"{self.BASE_URL}{endpoint}"
        
        # レート制限チェック
        if self.rate_limit_remaining <= 0:
            wait_time = self.rate_limit_reset - time.time()
            if wait_time > 0:
                logger.info(f"Rate limit reached, waiting {wait_time:.2f}s")
                time.sleep(wait_time)
        
        try:
            response = self.session.request(
                method=method,
                url=url,
                params=params,
                json=data,
                timeout=10
            )
            
            # レート制限ヘッダー更新
            if 'X-RateLimit-Remaining' in response.headers:
                self.rate_limit_remaining = int(response.headers['X-RateLimit-Remaining'])
            if 'X-RateLimit-Reset' in response.headers:
                self.rate_limit_reset = int(response.headers['X-RateLimit-Reset'])
            
            response.raise_for_status()
            return response.json()
            
        except requests.exceptions.HTTPError as e:
            logger.error(f"HTTP Error {e.response.status_code}: {e.response.text}")
            raise
        except requests.exceptions.Timeout:
            logger.error("Request timeout")
            raise
    
    def get_tardis_markets(self) -> List[Dict]:
        """利用可能なTardis市場一覧を取得"""
        result = self._make_request("GET", "/tardis/markets")
        return result.get("markets", [])
    
    def get_bitfinex_funding_history(self, symbol: str, 
                                      start_time: Optional[int] = None,
                                      end_time: Optional[int] = None,
                                      limit: int = 1000) -> List[Dict]:
        """Bitfinex先物 Funding Rate履歴を取得
        
        Args:
            symbol: 先物シンボル(例: "TH0:USD")
            start_time: 開始タイムスタンプ(Unix秒)
            end_time: 終了タイムスタンプ(Unix秒)
            limit: 取得件数上限
        
        Returns:
            Funding Rate 時系列データリスト
        """
        params = {
            "exchange": "bitfinex",
            "symbol": symbol,
            "type": "funding",
            "limit": limit
        }
        
        if start_time:
            params["start"] = start_time
        if end_time:
            params["end"] = end_time
        
        result = self._make_request("GET", "/tardis/historical", params=params)
        
        return result.get("data", [])
    
    def get_bitfinex_ticker(self, symbol: str) -> Dict:
        """Bitfinex先物のティッカー情報をリアルタイム取得
        
        Returns:
            現在の価格、数量、Funding Rate等の情報
        """
        params = {
            "exchange": "bitfinex",
            "symbol": symbol
        }
        
        result = self._make_request("GET", "/tardis/ticker", params=params)
        return result
    
    def get_bitfinex_index(self, index_name: str) -> Dict:
        """Bitfinex先物先物指数を取得(基差計算用)"""
        params = {
            "exchange": "bitfinex",
            "index": index_name
        }
        
        result = self._make_request("GET", "/tardis/index", params=params)
        return result
    
    def stream_bitfinex_funding(self, symbols: List[str], 
                                 callback: callable):
        """Bitfinex先物 Funding Rateのリアルタイムストリーミング
        
        Args:
            symbols: ストリーミングするシンボルリスト
            callback: データを受信時に呼び出されるコールバック関数
        """
        data = {
            "exchange": "bitfinex",
            "symbols": symbols,
            "channels": ["funding", "ticker"]
        }
        
        # WebSocket接続によるリアルタイムストリーミング
        ws_endpoint = "/ws/tardis/stream"
        
        def on_message(ws, message):
            try:
                payload = json.loads(message)
                if payload.get("type") == "funding" or payload.get("type") == "ticker":
                    callback(payload)
            except json.JSONDecodeError:
                logger.warning(f"Invalid JSON message: {message}")
        
        # 実際のWebSocket実装はwebsocketsライブラリを使用
        import websockets
        
        async def connect():
            async with websockets.connect(
                f"wss://api.holysheep.ai/v1{ws_endpoint}",
                extra_headers={"Authorization": f"Bearer {self.api_key}"}
            ) as ws:
                await ws.send(json.dumps(data))
                async for message in ws:
                    on_message(ws, message)
        
        import asyncio
        asyncio.get_event_loop().run_until_complete(connect())


使用例

if __name__ == "__main__": client = HolySheepTardisClient(api_key="YOUR_HOLYSHEEP_API_KEY") # Funding Rate履歴取得テスト funding_data = client.get_bitfinex_funding_history( symbol="TH0:USD", limit=100 ) print(f"取得件数: {len(funding_data)}") for item in funding_data[:5]: print(f"Time: {datetime.fromtimestamp(item['timestamp']/1000)}, " f"Funding Rate: {item.get('funding_rate', 0) * 100:.6f}%")

Funding Rate 時系列データ収集システム

Bitfinex先物先物のFunding Rateは8時間ごとに更新され、永久契約の価値を現物インデックスに同期させる役割を持つ。オプション做市では、このFunding Rateの期待値をボラティリティ_surface構築のコスト要因として活用する。

# funding_collector.py
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
from typing import Dict, List, Optional
from dataclasses import dataclass, field
import asyncio
from holy_client import HolySheepTardisClient

@dataclass
class FundingRecord:
    """Funding Rate レコード"""
    timestamp: datetime
    symbol: str
    funding_rate: float          # 8時間利率(小数)
    funding_rate_annualized: float  # 年率化利率
    next_funding_time: datetime
    mark_price: float
    index_price: float
    
    def to_dict(self) -> Dict:
        return {
            "timestamp": self.timestamp,
            "symbol": self.symbol,
            "funding_rate": self.funding_rate,
            "funding_rate_annualized": self.funding_rate_annualized,
            "next_funding_time": self.next_funding_time,
            "mark_price": self.mark_price,
            "index_price": self.index_price
        }


class FundingCollector:
    """Funding Rate 時系列データ収集クラス"""
    
    # Funding周期(Bitfinexは8時間 = 1日3回)
    FUNDING_INTERVAL_HOURS = 8
    FUNDING_PERIOD_PER_YEAR = 365 * 3  # 年間Funding回数
    
    def __init__(self, api_client: HolySheepTardisClient):
        self.client = api_client
        self.history: Dict[str, pd.DataFrame] = {}
    
    def fetch_historical_funding(self, symbol: str, 
                                  days: int = 30) -> List[FundingRecord]:
        """過去N日分のFunding Rate履歴を取得
        
        Args:
            symbol: 先物シンボル
            days: 取得日数
        """
        end_time = int(datetime.now().timestamp())
        start_time = int((datetime.now() - timedelta(days=days)).timestamp())
        
        raw_data = self.client.get_bitfinex_funding_history(
            symbol=symbol,
            start_time=start_time,
            end_time=end_time,
            limit=5000
        )
        
        records = []
        for item in raw_data:
            funding_rate = item.get("funding_rate", 0)
            
            record = FundingRecord(
                timestamp=datetime.fromtimestamp(item["timestamp"] / 1000),
                symbol=symbol,
                funding_rate=funding_rate,
                funding_rate_annualized=funding_rate * self.FUNDING_PERIOD_PER_YEAR,
                next_funding_time=datetime.fromtimestamp(
                    item.get("next_funding_time", item["timestamp"]) / 1000
                ),
                mark_price=item.get("mark_price", 0),
                index_price=item.get("index_price", 0)
            )
            records.append(record)
        
        return records
    
    def calculate_funding_statistics(self, records: List[FundingRecord]) -> Dict:
        """Funding Rateの統計量を計算"""
        if not records:
            return {}
        
        df = pd.DataFrame([r.to_dict() for r in records])
        
        stats = {
            "mean_funding": df["funding_rate"].mean(),
            "mean_funding_annualized": df["funding_rate_annualized"].mean(),
            "std_funding": df["funding_rate"].std(),
            "max_funding": df["funding_rate"].max(),
            "min_funding": df["funding_rate"].min(),
            "current_funding": df["funding_rate"].iloc[-1],
            "funding_count": len(df),
            "data_period": {
                "start": df["timestamp"].min(),
                "end": df["timestamp"].max()
            }
        }
        
        # 移動平均の計算
        df = df.sort_values("timestamp")
        df["funding_ma_7d"] = df["funding_rate"].rolling(window=21).mean()  # 約7日分
        df["funding_ma_30d"] = df["funding_rate"].rolling(window=90).mean()  # 約30日分
        
        stats["ma_7d"] = df["funding_ma_7d"].iloc[-1] if len(df) >= 21 else None
        stats["ma_30d"] = df["funding_ma_30d"].iloc[-1] if len(df) >= 90 else None
        
        # Funding方向(月次期待値)
        positive_rate = (df["funding_rate"] > 0).mean()
        stats["positive_funding_ratio"] = positive_rate
        
        return stats
    
    def build_funding_time_series(self, symbols: List[str], 
                                   days: int = 30) -> pd.DataFrame:
        """複数シンボルのFunding Rate時系列を構築"""
        all_records = []
        
        for symbol in symbols:
            records = self.fetch_historical_funding(symbol, days)
            all_records.extend(records)
            print(f"{symbol}: {len(records)}件のFundingデータを取得")
        
        if not all_records:
            return pd.DataFrame()
        
        df = pd.DataFrame([r.to_dict() for r in all_records])
        df = df.sort_values(["symbol", "timestamp"])
        
        # シンボル別の時系列を横展開
        pivot_df = df.pivot_table(
            index="timestamp",
            columns="symbol",
            values="funding_rate_annualized",
            aggfunc="first"
        )
        
        return pivot_df


使用例

if __name__ == "__main__": client = HolySheepTardisClient(api_key="YOUR_HOLYSHEEP_API_KEY") collector = FundingCollector(client) # TH先物永久契約のFundingデータ取得 th_funding = collector.fetch_historical_funding("TH0:USD", days=30) stats = collector.calculate_funding_statistics(th_funding) print(f"TH0:USD Funding統計:") print(f" 平均年率Funding: {stats['mean_funding_annualized']*100:.4f}%") print(f" 標準偏差: {stats['std_funding']*100:.6f}%") print(f" 最大値: {stats['max_funding']*100:.6f}%") print(f" 最小値: {stats['min_funding']*100:.6f}%") print(f" 7日移動平均: {stats['ma_7d']*100:.6f}%") print(f" Funding正転比率: {stats['positive_funding_ratio']*100:.2f}%")

基差(Basis)時系列データモデリング

基差(Basis)は先物価格と現物価格の差であり、年率化することで裁定取引コストやswap価値を評価できる。HolySheepを通じて取得したTardis Bitfinexの先物・先物指数データを用いてリアルタイム基差を計算し、オプション価格モデルのインプットとして活用する。

# basis_calculator.py
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
from typing import Dict, List, Tuple, Optional
from dataclasses import dataclass
import asyncio
from holy_client import HolySheepTardisClient

@dataclass
class BasisRecord:
    """基差(Basis)レコード"""
    timestamp: datetime
    futures_symbol: str
    index_symbol: str
    futures_price: float
    index_price: float
    basis: float              # 先物価格 - 現物価格
    basis_pct: float          # 基差率(%)
    basis_annualized: float   # 年率化基差率(%)
    
    def to_dict(self) -> Dict:
        return {
            "timestamp": self.timestamp,
            "futures_symbol": self.futures_symbol,
            "index_symbol": self.index_symbol,
            "futures_price": self.futures_price,
            "index_price": self.index_price,
            "basis": self.basis,
            "basis_pct": self.basis_pct,
            "basis_annualized": self.basis_annualized
        }


class BasisCalculator:
    """基差(Basis)計算クラス"""
    
    # 年間時間(Bitfinex先物は365日計算)
    DAYS_PER_YEAR = 365
    
    def __init__(self, api_client: HolySheepTardisClient):
        self.client = api_client
        self.current_basis: Dict[str, BasisRecord] = {}
    
    def calculate_current_basis(self, futures_symbol: str, 
                                 index_symbol: str,
                                 expiry_date: Optional[datetime] = None) -> BasisRecord:
        """現在時刻の基差を計算
        
        Args:
            futures_symbol: 先物シンボル(例: "TH0:USD")
            index_symbol: 先物指数シンボル(例: "TH-NETWORK")
            expiry_date: 先物の満期日(年率化計算用)
        
        Returns:
            BasisRecord: 計算された基差データ
        """
        # 先物価格取得
        futures_data = self.client.get_bitfinex_ticker(futures_symbol)
        futures_price = futures_data.get("last_price", 0)
        
        # 先物指数価格取得
        index_data = self.client.get_bitfinex_index(index_symbol)
        index_price = index_data.get("price", 0)
        
        # 基差計算
        basis = futures_price - index_price
        basis_pct = (basis / index_price) * 100 if index_price != 0 else 0
        
        # 年率化(満期までの残存时间来計算)
        if expiry_date is None:
            # 永久契約の場合、年率化基差 = Funding期待値と同じ意味
            funding_data = self.client.get_bitfinex_funding_history(
                futures_symbol, limit=1
            )
            if funding_data:
                # Funding Rateから年率化を逆算
                funding_rate = funding_data[0].get("funding_rate", 0)
                basis_annualized = funding_rate * 3 * 365 * 100  # 8時間 → 年率
            else:
                basis_annualized = 0
        else:
            # 限月契約の場合、満期までの时间来計算
            days_to_expiry = (expiry_date - datetime.now()).days
            if days_to_expiry > 0:
                basis_annualized = basis_pct * (self.DAYS_PER_YEAR / days_to_expiry)
            else:
                basis_annualized = 0
        
        record = BasisRecord(
            timestamp=datetime.now(),
            futures_symbol=futures_symbol,
            index_symbol=index_symbol,
            futures_price=futures_price,
            index_price=index_price,
            basis=basis,
            basis_pct=basis_pct,
            basis_annualized=basis_annualized
        )
        
        self.current_basis[futures_symbol] = record
        return record
    
    def build_basis_history(self, futures_symbol: str, 
                            index_symbol: str,
                            days: int = 30) -> pd.DataFrame:
        """基差の時系列履歴を構築
        
        Args:
            futures_symbol: 先物シンボル
            index_symbol: 先物指数シンボル
            days: 取得日数
        
        Returns:
            基差時系列DataFrame
        """
        end_time = int(datetime.now().timestamp())
        start_time = int((datetime.now() - timedelta(days=days)).timestamp())
        
        # 先物Funding履歴から価格データを取得
        funding_data = self.client.get_bitfinex_funding_history(
            symbol=futures_symbol,
            start_time=start_time,
            end_time=end_time,
            limit=5000
        )
        
        records = []
        for item in funding_data:
            mark_price = item.get("mark_price", 0)
            index_price = item.get("index_price", 0)
            
            if mark_price > 0 and index_price > 0:
                basis = mark_price - index_price
                basis_pct = (basis / index_price) * 100
                
                record = BasisRecord(
                    timestamp=datetime.fromtimestamp(item["timestamp"] / 1000),
                    futures_symbol=futures_symbol,
                    index_symbol=index_symbol,
                    futures_price=mark_price,
                    index_price=index_price,
                    basis=basis,
                    basis_pct=basis_pct,
                    basis_annualized=0  # 履歴からは年率化難しい
                )
                records.append(record)
        
        if not records:
            return pd.DataFrame()
        
        df = pd.DataFrame([r.to_dict() for r in records])
        df = df.sort_values("timestamp")
        
        # 追加の特徴量生成
        df["basis_ma_7d"] = df["basis_pct"].rolling(window=21).mean()
        df["basis_ma_30d"] = df["basis_pct"].rolling(window=90).mean()
        df["basis_std_7d"] = df["basis_pct"].rolling(window=21).std()
        
        # 異常値検出(標準偏差ベース)
        if len(df) >= 21:
            df["basis_zscore"] = (
                df["basis_pct"] - df["basis_ma_7d"]
            ) / df["basis_std_7d"]
        else:
            df["basis_zscore"] = 0
        
        return df
    
    def calculate_basis_volatility(self, df: pd.DataFrame) -> Dict:
        """基差のボラティリティ指標を計算"""
        if df.empty or len(df) < 2:
            return {}
        
        returns = df["basis_pct"].pct_change().dropna()
        
        stats = {
            "mean_basis": df["basis_pct"].mean(),
            "std_basis": df["basis_pct"].std(),
            "current_basis": df["basis_pct"].iloc[-1],
            "basis_range": df["basis_pct"].max() - df["basis_pct"].min(),
            "basis_ Sharpe": (
                df["basis_pct"].mean() / df["basis_pct"].std() 
                if df["basis_pct"].std() != 0 else 0
            ),
            "volatility_basis_daily": returns.std() * 100,
            "volatility_basis_annual": returns.std() * np.sqrt(365) * 100
        }
        
        return stats
    
    def get_basis_signals(self, df: pd.DataFrame, 
                          threshold: float = 2.0) -> List[Dict]:
        """基差の売買シグナル生成
        
        標準偏差ベースの異常値検出により、基差が歷史平均から大きく乖離した
        場合に裁定取引機会としてシグナルを生成
        
        Args:
            df: 基差時系列DataFrame
            threshold: シグナル発動のz-score閾値
        
        Returns:
            シグナルリスト
        """
        if "basis_zscore" not in df.columns or df.empty:
            return []
        
        signals = []
        for _, row in df.iterrows():
            zscore = row.get("basis_zscore", 0)
            
            if pd.isna(zscore):
                continue
            
            signal_type = None
            if zscore > threshold:
                signal_type = "basis_overvalued"  # 基差高すぎ → 先物売る
            elif zscore < -threshold:
                signal_type = "basis_undervalued"  # 基差低すぎ → 先物買う
            
            if signal_type:
                signals.append({
                    "timestamp": row["timestamp"],
                    "type": signal_type,
                    "zscore": zscore,
                    "basis_pct": row["basis_pct"],
                    "futures_symbol": row["futures_symbol"],
                    "action": "SELL_FUTURES" if signal_type == "basis_overvalued" else "BUY_FUTURES"
                })
        
        return signals


使用例

if __name__ == "__main__": client = HolySheepTardisClient(api_key="YOUR_HOLYSHEEP_API_KEY") calculator = BasisCalculator(client) # TH先物の現在基差を計算 basis = calculator.calculate_current_basis( futures_symbol="TH0:USD", index_symbol="TH-NETWORK" ) print(f"TH0:USD 基差:") print(f" 先物価格: ${basis.futures_price:,.2f}") print(f" 指数価格: ${basis.index_price:,.2f}") print(f" 基差: ${basis.basis:,.2f} ({basis.basis_pct:.4f}%)") print(f" 年率化基差: {basis.basis_annualized:.4f}%") # 基差履歴の構築 history = calculator.build_basis_history( futures_symbol="TH0:USD", index_symbol="TH-NETWORK", days=30 ) if not history.empty: stats = calculator.calculate_basis_volatility(history) print(f"\nTH0:USD 基差統計:") print(f" 平均基差: {stats['mean_basis']:.4f}%") print(f" 基差ボラティリティ(日次): {stats['volatility_basis_daily']:.4f}%") print(f" 基差ボラティリティ(年次): {stats['volatility_basis_annual']:.4f}%") # シグナル検出 signals = calculator.get_basis_signals(history, threshold=2.0) print(f"\n検出されたシグナル数: {len(signals)}")

InfluxDBへのリアルタイム保存

# storage.py
from influxdb_client import InfluxDBClient, Point, WriteOptions
from influxdb_client.client.write_api import SYNCHRONOUS
import pandas as pd
from datetime import datetime
from typing import List, Dict
from funding_collector import FundingRecord, FundingCollector
from basis_calculator import BasisRecord, BasisCalculator

class TimeSeriesStorage:
    """InfluxDB 時系列ストレージ"""
    
    def __init__(self, url: str, token: str, org: str, bucket: str):
        self.client = InfluxDBClient(url=url, token=token, org=org)
        self.write_api = self.client.write_api(
            write_options=WriteOptions(
                batch_size=500,
                flush_interval=1000,
                jitter_interval=200
            )
        )
        self.query_api = self.client.query_api()
        self.org = org
        self.bucket = bucket
    
    def write_funding_record(self, record: FundingRecord):
        """Funding RateレコードをInfluxDBに保存"""
        point = Point("funding_rate") \
            .tag("symbol", record.symbol) \
            .field("rate", record.funding_rate) \
            .field("rate_annualized", record.funding_rate_annualized) \
            .field("mark_price", record.mark_price) \
            .field("index_price", record.index_price) \
            .time(record.timestamp)
        
        self.write_api.write(bucket=self.bucket, org=self.org, record=point)
    
    def write_funding_batch(self, records: List[FundingRecord]):
        """Funding Rateレコードのバッチ保存"""
        points = []
        for record in records:
            point = Point("funding_rate") \
                .tag("symbol", record.symbol) \
                .field("rate", record.funding_rate) \
                .field("rate_annualized", record.funding_rate_annualized) \
                .field("mark_price", record.mark_price) \
                .field("index_price", record.index_price) \
                .time(record.timestamp)
            points.append(point)
        
        self.write_api.write(bucket=self.bucket, org=self.org, record=points)
    
    def write_basis_record(self, record: BasisRecord):
        """基差レコードをInfluxDBに保存"""
        point = Point("basis") \
            .tag("futures_symbol", record.futures_symbol) \
            .tag("index_symbol", record.index_symbol) \
            .field("futures_price", record.futures_price) \
            .field("index_price", record.index_price) \
            .field("basis", record.basis) \
            .field("basis_pct", record.basis_pct) \
            .field("basis_annualized", record.basis_annualized) \
            .time(record.timestamp)
        
        self.write_api.write(bucket=self.bucket, org=self.org, record=point)
    
    def query_funding_history(self, symbol: str, 
                               start: datetime