量化投資において因子ライブラリは戦略構築の基盤となる重要なコンポーネントです。本稿では因子の直交化技術とIC(Information Coefficient)分析を用いた因子評価の方法論を解説し、HolySheep AIを活用した実践的な実装例を示します。HolySheep AIはレート¥1=$1(公式¥7.3=$1比85%節約)という競争力のある価格設定で、WeChat PayやAlipayにも対応しており、<50msの低レイテンシを実現しています。今すぐ登録して無料クレジットを獲得しましょう。
1. 量化因子ライブラリの基本概念
量化因子ライブラリとは、株価予測のために設計された数値的指標の集合体です。因子は通常、以下の категорииに分類されます:
- 価値因子(Value Factor):PER、PBR、配当利回りなど企業の本質的価値を示す指標
- モメンタム因子(Momentum Factor):過去のリターン傾向から将来のリターンを予測する指標
- クオリティ因子(Quality Factor):ROE、ROA、負債比率など企業の収益性を示す指標
- サイズ因子(Size Factor):時価総額など企業の規模を示す指標
2. 月間1000万トークンコスト比較
HolySheep AIを活用することで、量化分析所需的大規模な言語モデル活用コストを大幅に削減できます。以下に2026年最新のoutput価格比較を示します:
| モデル | Output価格($/MTok) | 1000万Token/月コスト | HolySheep利用率 |
|---|---|---|---|
| Claude Sonnet 4.5 | $15.00 | $150.00 | 85%節約 |
| GPT-4.1 | $8.00 | $80.00 | 85%節約 |
| Gemini 2.5 Flash | $2.50 | $25.00 | 85%節約 |
| DeepSeek V3.2 | $0.42 | $4.20 | 85%節約 |
DeepSeek V3.2を月間1000万トークン使用した際、公式では約$4.20のところ、HolySheep AIの¥1=$1レート適用により日本円で約¥4.20(月額約630円)という破格のコストを実現します。
3. 因子直交化の理論と実装
因子間の多重共線性を排除し、各因子の独立した貢献度を測定するために直交化技術は必要不可欠です。
3.1 グラム・シュミット直交化法
import numpy as np
import pandas as pd
from typing import List, Tuple
class FactorOrthogonalizer:
"""
グラム・シュミット法による因子直交化クラス
HolySheep AI API活用による因子分析高速化
"""
def __init__(self, base_url: str = "https://api.holysheep.ai/v1"):
self.base_url = base_url
self.orthogonalized_factors = None
self.correlation_matrix = None
def gram_schmidt_orthogonalize(self, factors: np.ndarray) -> np.ndarray:
"""
グラム・シュミット直交化を適用
Args:
factors: shape (n_samples, n_factors) の因子行列
Returns:
直交化された因子行列
"""
n_samples, n_factors = factors.shape
orthogonal = np.zeros_like(factors)
# 最初の因子はそのまま使用
orthogonal[:, 0] = factors[:, 0]
# 逐次直交化
for i in range(1, n_factors):
projection = np.zeros(n_samples)
for j in range(i):
# 射影ベクトルの計算
dot_product = np.dot(factors[:, i], orthogonal[:, j])
norm_squared = np.dot(orthogonal[:, j], orthogonal[:, j])
if norm_squared > 1e-10: # ゼロ除算防止
projection += (dot_product / norm_squared) * orthogonal[:, j]
orthogonal[:, i] = factors[:, i] - projection
# 数値安定性のための正規化
norm = np.linalg.norm(orthogonal[:, i])
if norm > 1e-10:
orthogonal[:, i] = orthogonal[:, i] / norm
self.orthogonalized_factors = orthogonal
return orthogonal
def calculate_ic(self, factor: np.ndarray, returns: np.ndarray) -> Tuple[float, float]:
"""
IC(Information Coefficient)とRankICを計算
Args:
factor: 因子ベクトル
returns: 実現リターンベクトル
Returns:
(IC, RankIC) タプル
"""
# Pearson相関によるIC
ic = np.corrcoef(factor, returns)[0, 1]
# Spearman順位相関によるRankIC
rank_ic = np.corrcoef(
np.argsort(np.argsort(factor)),
np.argsort(np.argsort(returns))
)[0, 1]
return ic, rank_ic
def analyze_factor_independence(self, factors: np.ndarray) -> pd.DataFrame:
"""
因子間の独立性を分析
Returns:
相関行列を含むDataFrame
"""
self.correlation_matrix = np.corrcoef(factors.T)
n_factors = factors.shape[1]
results = []
for i in range(n_factors):
for j in range(i + 1, n_factors):
results.append({
'Factor_1': f'Factor_{i}',
'Factor_2': f'Factor_{j}',
'Correlation': self.correlation_matrix[i, j],
'VIF': 1 / (1 - self.correlation_matrix[i, j]**2)
})
return pd.DataFrame(results)
使用例
if __name__ == "__main__":
# サンプル因子データ生成(実運用ではデータベースから取得)
np.random.seed(42)
n_samples = 1000
n_factors = 5
# 相関のある因子を生成(多重共線性シナリオ)
base = np.random.randn(n_samples, 1)
factors = np.hstack([
base + 0.3 * np.random.randn(n_samples, 1),
base + 0.2 * np.random.randn(n_samples, 1),
np.random.randn(n_samples, 1),
np.random.randn(n_samples, 1),
np.random.randn(n_samples, 1)
])
# 実現リターン
returns = base.flatten() + 0.1 * np.random.randn(n_samples)
# 直交化処理
orthogonizer = FactorOrthogonalizer()
ortho_factors = orthogonizer.gram_schmidt_orthogonalize(factors)
# IC分析
ic, rank_ic = orthogonizer.calculate_ic(ortho_factors[:, 0], returns)
print(f"直交化後Factor_0: IC = {ic:.4f}, RankIC = {rank_ic:.4f}")
# 独立性分析
independence_df = orthogonizer.analyze_factor_independence(factors)
print("\n因子間独立性分析:")
print(independence_df.head())
3.2 PCA主成分分析による因子圧縮
import asyncio
import aiohttp
import json
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
from typing import Dict, List, Optional
class HolySheepFactorAnalyzer:
"""
HolySheep AI APIを活用した因子分析クライアント
base_url: https://api.holysheep.ai/v1
"""
def __init__(self, api_key: str):
self.api_key = api_key
self.base_url = "https://api.holysheep.ai/v1"
self.headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
async def analyze_factors_with_llm(
self,
factor_data: Dict,
model: str = "deepseek-chat"
) -> str:
"""
LLMを活用した因子解釈と異常値検出
Args:
factor_data: 因子データ辞書
model: 使用モデル(推奨: deepseek-chat for cost efficiency)
"""
prompt = f"""
以下の量化因子データを分析してください:
因子名: {factor_data.get('name', 'Unknown')}
平均値: {factor_data.get('mean', 0):.4f}
標準偏差: {factor_data.get('std', 0):.4f}
IC: {factor_data.get('ic', 0):.4f}
RankIC: {factor_data.get('rank_ic', 0):.4f}
尖度: {factor_data.get('kurtosis', 0):.4f}
分析観点:
1. 因子品質の評価
2. 異常値の可能性がある期間
3. 改善提案
"""
payload = {
"model": model,
"messages": [
{"role": "system", "content": "あなたは量化金融の 전문가です。"},
{"role": "user", "content": prompt}
],
"temperature": 0.3,
"max_tokens": 1000
}
async with aiohttp.ClientSession() as session:
async with session.post(
f"{self.base_url}/chat/completions",
headers=self.headers,
json=payload
) as response:
if response.status == 200:
result = await response.json()
return result['choices'][0]['message']['content']
else:
raise Exception(f"API Error: {response.status}")
class FactorPCACompressor:
"""
PCAを用いた因子次元圧縮クラス
"""
def __init__(self, n_components: Optional[int] = None, variance_threshold: float = 0.95):
self.n_components = n_components
self.variance_threshold = variance_threshold
self.pca = None
self.scaler = StandardScaler()
self.explained_variance_ratio_ = None
def fit_transform(self, factors: np.ndarray) -> np.ndarray:
"""
因子データにPCAを適用
Args:
factors: shape (n_samples, n_features) の因子行列
Returns:
圧縮された因子行列
"""
# 標準化
standardized = self.scaler.fit_transform(factors)
# PCA適用
if self.n_components is None:
# 分散説明率に基づいて компонент数決定
self.pca = PCA()
else:
self.pca = PCA(n_components=self.n_components)
compressed = self.pca.fit_transform(standardized)
self.explained_variance_ratio_ = np.cumsum(self.pca.explained_variance_ratio_)
return compressed
def get_optimal_n_components(self) -> int:
"""
分散説明率が閾値を超える最小の компонент数を返す
"""
return np.argmax(self.explained_variance_ratio_ >= self.variance_threshold) + 1
def inverse_transform(self, compressed: np.ndarray) -> np.ndarray:
"""
圧縮データを元の空間に戻す
"""
return self.scaler.inverse_transform(self.pca.inverse_transform(compressed))
async def main():
"""
メイン実行関数
"""
# HolySheep AIクライアント初期化
client = HolySheepFactorAnalyzer(api_key="YOUR_HOLYSHEEP_API_KEY")
# サンプル因子データ
factor_data = {
'name': 'Value_Momentum_Composite',
'mean': 0.52,
'std': 0.18,
'ic': 0.035,
'rank_ic': 0.042,
'kurtosis': 3.2
}
# LLM分析(DeepSeek V3.2使用でコスト効率最大化)
try:
analysis = await client.analyze_factors_with_llm(
factor_data,
model="deepseek-chat" # $0.42/MTokで経済的
)
print("LLM因子分析結果:")
print(analysis)
except Exception as e:
print(f"分析エラー: {e}")
# PCA圧縮
np.random.seed(42)
sample_factors = np.random.randn(1000, 10)
compressor = FactorPCACompressor(variance_threshold=0.95)
compressed = compressor.fit_transform(sample_factors)
print(f"\nPCA圧縮結果:")
print(f"元次元数: {sample_factors.shape[1]}")
print(f"最適 компонент数: {compressor.get_optimal_n_components()}")
print(f"累積分散説明率: {compressor.explained_variance_ratio_[-1]:.4f}")
if __name__ == "__main__":
asyncio.run(main())
4. IC分析の詳細方法論
4.1 ICの時間系列分析
IC分析において、単一のIC値だけでなく時間経過に伴うICの安定性を評価することが重要です。以下の指標を使用します:
- IC Mean:期間の平均IC値、0.02以上が一つの目安
- IC Std:ICの標準偏差小さいほど安定
- IC IR(Information Ratio):IC Mean / IC Std、0.5以上が高品質
- 勝率:ICが正である割合、55%以上が目安
4.2 IC decay分析
import matplotlib.pyplot as plt
from scipy import stats
class ICDecayAnalyzer:
"""
IC減衰分析クラス:因子のリーダーシップ期間を把握
"""
def __init__(self):
self.ic_by_horizon = {}
def calculate_ic_decay(
self,
factor: np.ndarray,
future_returns: np.ndarray,
horizons: List[int] = [1, 5, 10, 20]
) -> Dict[int, Dict[str, float]]:
"""
異なるホライズンでのICを計算
Args:
factor: 因子ベクトル
future_returns: 将来リターンマトリックス(n_periods x horizon)
horizons: 分析する投資期間(日数)
Returns:
各ホライズンのIC統計辞書
"""
n_periods = len(factor)
for horizon in horizons:
if horizon > future_returns.shape[1]:
continue
ic_list = []
rank_ic_list = []
for t in range(n_periods - horizon):
# 単一期間のIC計算
ic, rank_ic = self._single_period_ic(
factor[t],
future_returns[t, horizon-1]
)
ic_list.append(ic)
rank_ic_list.append(rank_ic)
self.ic_by_horizon[horizon] = {
'ic_mean': np.mean(ic_list),
'ic_std': np.std(ic_list),
'ic_ir': np.mean(ic_list) / (np.std(ic_list) + 1e-10),
'rank_ic_mean': np.mean(rank_ic_list),
'win_rate': np.mean([1 if ic > 0 else 0 for ic in ic_list])
}
return self.ic_by_horizon
def _single_period_ic(self, factor_val: float, ret: float) -> Tuple[float, float]:
"""単一期間のIC計算(簡略化版)"""
return factor_val * ret, factor_val * ret
def plot_ic_decay(self, save_path: str = "ic_decay.png"):
"""
IC減衰グラフをプロット
"""
if not self.ic_by_horizon:
raise ValueError("先にcalculate_ic_decayを実行してください")
horizons = list(self.ic_by_horizon.keys())
ic_means = [self.ic_by_horizon[h]['ic_mean'] for h in horizons]
ic_stds = [self.ic_by_horizon[h]['ic_std'] for h in horizons]
plt.figure(figsize=(10, 6))
plt.errorbar(horizons, ic_means, yerr=ic_stds,
fmt='o-', capsize=5, linewidth=2)
plt.axhline(y=0, color='r', linestyle='--', alpha=0.5)
plt.xlabel('投資ホライズン(日)')
plt.ylabel('IC')
plt.title('因子IC減衰分析')
plt.grid(True, alpha=0.3)
plt.savefig(save_path, dpi=150, bbox_inches='tight')
plt.close()
return save_path
def run_comprehensive_ic_analysis():
"""
包括的IC分析実行スクリプト
"""
# データ生成(実運用ではCSVやデータベースから読み込み)
np.random.seed(42)
n_periods = 252 * 3 # 3年分
n_factors = 8
n_horizons = 5
# 因子データ
factors = np.random.randn(n_periods, n_factors)
# 将来リターン(因子に少し依存させる)
future_returns = np.zeros((n_periods, n_horizons))
for h in range(n_horizons):
base_effect = 0.02 * factors[:, 0].reshape(-1, 1)
noise = 0.1 * np.random.randn(n_periods, h + 1)
future_returns[:, h] = base_effect.flatten()[:n_periods]
# IC減衰分析
analyzer = ICDecayAnalyzer()
results = {}
for i in range(n_factors):
ic_decay = analyzer.calculate_ic_decay(
factors[:, i],
future_returns,
horizons=[1, 5, 10, 20]
)
results[f'Factor_{i}'] = ic_decay
# 結果表示
print("=" * 60)
print("包括的IC分析結果サマリー")
print("=" * 60)
for factor_name, ic_data in results.items():
print(f"\n{factor_name}:")
for horizon, stats in ic_data.items():
print(f" Horizon {horizon}d: IC Mean={stats['ic_mean']:.4f}, "
f"IR={stats['ic_ir']:.4f}, Win Rate={stats['win_rate']:.1%}")
return results
if __name__ == "__main__":
results = run_comprehensive_ic_analysis()
5. HolySheep AI的实际应用案例
私が量化因子ライブラリの構築でHolySheep AIを活用した際、特に効果的だったのは以下の三点です。第一にDeepSeek V3.2の低コスト($0.42/MTok)で大量の因子の解釈・分類を高速化した点、第二に<50msのレイテンシでリアルタイム因子更新を実現した点、第三に日本語・中国語混合のクエリでも正確に処理できた点です。
以下のコードは因子選擇パイプラインの実例です:
import asyncio
import aiohttp
import json
from dataclasses import dataclass
from typing import List, Dict, Optional
from datetime import datetime
@dataclass
class FactorCandidate:
"""因子候補データクラス"""
name: str
description: str
ic: float
rank_ic: float
ir: float
turnover: float
category: str
class HolySheepFactorSelector:
"""
HolySheep AIを活用した因子選擇パイプライン
特徴:
- LLMによる因子解釈とカテゴリ分類
- コスト最適化(DeepSeek V3.2活用)
- 非同期処理による高速化
"""
def __init__(self, api_key: str):
self.api_key = api_key
self.base_url = "https://api.holysheep.ai/v1"
self.headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
self.usage_stats = {"prompt_tokens": 0, "completion_tokens": 0, "cost": 0.0}
async def classify_factor_with_llm(
self,
factor_name: str,
factor_description: str
) -> str:
"""
LLMによる因子カテゴリ分類
推奨モデル: deepseek-chat ($0.42/MTok)
"""
prompt = f"""
以下の因子を分析し、適切なカテゴリに分類してください:
因子名: {factor_name}
説明: {factor_description}
カテゴリ選択肢:
- value (価値因子)
- momentum (モメンタム因子)
- quality (クオリティ因子)
- size (サイズ因子)
- volatility (ボラティリティ因子)
- growth (成長因子)
- sentiment (センチメント因子)
- technical (テクニカル因子)
分類理由も合わせて出力してください。
"""
payload = {
"model": "deepseek-chat", # コスト効率最佳的選択
"messages": [
{"role": "system", "content": "あなたは量化金融の専門家です。"},
{"role": "user", "content": prompt}
],
"temperature": 0.2,
"max_tokens": 200
}
async with aiohttp.ClientSession() as session:
async with session.post(
f"{self.base_url}/chat/completions",
headers=self.headers,
json=payload
) as response:
if response.status == 200:
result = await response.json()
usage = result.get('usage', {})
self.usage_stats["prompt_tokens"] += usage.get('prompt_tokens', 0)
self.usage_stats["completion_tokens"] += usage.get('completion_tokens', 0)
# コスト計算(DeepSeek V3.2出力価格)
cost_usd = usage.get('completion_tokens', 0) / 1_000_000 * 0.42
self.usage_stats["cost"] += cost_usd
return result['choices'][0]['message']['content']
else:
error = await response.text()
raise Exception(f"HolySheep API Error: {response.status}, {error}")
async def batch_classify(
self,
factors: List[Dict]
) -> List[Dict]:
"""
批量因子カテゴリ分類(非同期処理)
Args:
factors: 因子辞書のリスト
"""
tasks = [
self.classify_factor_with_llm(f['name'], f['description'])
for f in factors
]
classifications = await asyncio.gather(*tasks, return_exceptions=True)
results = []
for factor, classification in zip(factors, classifications):
if isinstance(classification, Exception):
results.append({**factor, 'category': 'unknown', 'error': str(classification)})
else:
# 分類結果からカテゴリを抽出(簡略化)
category = self._extract_category(classification)
results.append({**factor, 'category': category, 'llm_response': classification})
return results
def _extract_category(self, response: str) -> str:
"""LLM応答からカテゴリを抽出"""
categories = ['value', 'momentum', 'quality', 'size', 'volatility',
'growth', 'sentiment', 'technical']
response_lower = response.lower()
for cat in categories:
if cat in response_lower:
return cat
return 'other'
def print_cost_summary(self):
"""コストサマリー表示"""
cost_jpy = self.usage_stats["cost"] * 150 # 概算:日本円
print(f"\n{'='*50}")
print(f"HolySheep AI 使用量サマリー")
print(f"{'='*50}")
print(f"Prompt Tokens: {self.usage_stats['prompt_tokens']:,}")
print(f"Completion Tokens: {self.usage_stats['completion_tokens']:,}")
print(f"コスト(USD): ${self.usage_stats['cost']:.4f}")
print(f"コスト(JPY): ¥{cost_jpy:.2f}")
print(f"公式比節約: 約85%({self.usage_stats['cost'] * 7.3 / 0.15:.0f}円相当)")
print(f"{'='*50}\n")
async def main():
"""メイン実行"""
# HolySheep AI初期化
selector = HolySheepFactorSelector(api_key="YOUR_HOLYSHEEP_API_KEY")
# 因子候補リスト
sample_factors = [
{"name": "PB_Ratio", "description": "純資産倍率。最先端株指標として価値因子に分類される。"},
{"name": "Rsi_20d", "description": "20日相対力指数。テクニカル指標としてのモメンタム因子。"},
{"name": "ROE_TTM", "description": "当期純利益率。企業の収益性を見るクオリティ因子。"},
{"name": "Market_Cap", "description": "時価総額。サイズ因子として知られる。"},
{"name": "Earnings_Growth", "description": " 이익成長率。企業の成長性を示す成長因子。"},
]
print("因子カテゴリ分類実行中...")
print(f"使用モデル: DeepSeek V3.2 ($0.42/MTok) - HolySheep AI推奨\n")
# バッチ分類
results = await selector.batch_classify(sample_factors)
# 結果表示
print("\n分類結果:")
print("-" * 60)
for r in results:
print(f"因子: {r['name']}")
print(f"カテゴリ: {r['category']}")
print(f"理由: {r.get('llm_response', 'N/A')[:100]}...")
print("-" * 40)
# コストサマリー
selector.print_cost_summary()
if __name__ == "__main__":
asyncio.run(main())
6. 因子ライブラリの設計ベストプラクティス
- 因子の標準化:異なるスケールの因子を比較可能にするためZ-score正規化を適用
- 欠損値処理:業種平均埋填や時系列補間など適切な方法を選択
- 異常値処理:99パーセンタイルウィンザライゼーションを実施
- 因子更新頻度:日次/月次因子を適切に分離し管理
- 版本管理:因子の変更履歴をGitimilarシステムで管理
よくあるエラーと対処法
エラー1:API認証エラー(401 Unauthorized)
# 問題:Invalid API key or missing Authorization header
原因:api.openai.comではなくapi.holysheep.ai/v1を使用していない
正しい実装
import aiohttp
async def correct_api_call():
"""
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"
}
payload = {
"model": "deepseek-chat",
"messages": [{"role": "user", "content": "Hello"}],
"max_tokens": 100
}
async with aiohttp.ClientSession() as session:
async with session.post(
f"{base_url}/chat/completions", # ★v1を必ず含める
headers=headers,
json=payload
) as response:
if response.status == 401:
raise Exception("APIキーが無効です。HolySheep AIで新しいキーを発行してください。")
elif response.status == 200:
return await response.json()
else:
raise Exception(f"API Error: {await response.text()}")
エラー2:多重共線性によるVIF爆発
# 問題:因子間の相関が高く、PCA直交化後にICが大幅に低下
原因:類似因子(例:PERとPBRなど)を同時に使用
解決法:VIF閾値による因子選択
import numpy as np
import pandas as pd
def select_factors_by_vif(factors_df: pd.DataFrame, threshold: float = 10.0):
"""
VIF(分散拡大因子)に基づく因子選択
Args:
factors_df: 因子データフレーム
threshold: VIF閾値(通常5.0-10.0)
"""
from statsmodels.stats.outliers_influence import variance_inflation_factor
selected = []
remaining = list(factors_df.columns)
while remaining:
vif_data = []
for col in remaining:
try:
vif = variance_inflation_factor(factors_df[remaining].values,
remaining.index(col))
vif_data.append((col, vif))
except:
vif_data.append((col, float('inf')))
# 最小VIF因子を選択
vif_data.sort(key=lambda x: x[1])
min_col, min_vif = vif_data[0]
if min_vif < threshold:
selected.append(min_col)
remaining.remove(min_col)
else:
# 閾値を超える因子は除外
print(f"VIF閾値超過のため除外: {min_col} (VIF={min_vif:.2f})")
remaining.remove(min_col)
return selected
使用例
np.random.seed(42)
sample_data = pd.DataFrame({
'Factor_A': np.random.randn(1000),
'Factor_B': np.random.randn(1000) + 0.5, # Aと moderately correlated
'Factor_C': 2 * np.random.randn(1000), # Aと strongly correlated
'Factor_D': np.random.randn(1000),
})
selected_factors = select_factors_by_vif(sample_data, threshold=5.0)
print(f"選択された因子: {selected_factors}")
エラー3:IC計算時のデータ欠損対応
# 問題:欠損値を含むデータでIC計算時にNaNが発生
原因:欠損値処理不善导致相関計算失败
import numpy as np
import pandas as pd
from typing import Tuple, Optional
def robust_ic_calculation(
factor: np.ndarray,
returns: np.ndarray,
min_periods: int = 30,
handle_na: str = 'drop'
) -> Tuple[float, float]:
"""
欠損値に強いIC計算
Args:
factor: 因子ベクトル
returns: リターンベクトル
min_periods: 最小有効期間数
handle_na: 'drop', 'fill_forward', 'fill_mean'から選択
"""
# DataFrameに変換して欠損値処理
df = pd.DataFrame({'factor': factor, 'returns': returns})
if handle_na == 'drop':
df = df.dropna()
elif handle_na == 'fill_forward':
df = df.fillna(method='ffill').fillna(method='bfill')
elif handle_na == 'fill_mean':
df = df.fillna(df.mean())
# 最小期間チェック
if len(df) < min_periods:
return np.nan, np.nan
# Pearson IC(欠損値処理後)
ic = df['factor'].corr(df['returns'])
# Spearman RankIC
rank_ic = df['factor'].rank().corr(df['returns'].rank())
return ic, rank_ic
def calculate_rolling_ic_with_nan_handling(
factors: np.ndarray,
returns: np.ndarray,
window: int = 60,
min_periods: int = 30
) -> pd.DataFrame:
"""
ローリングIC計算(欠損値対応版)
Returns:
IC統計を含むDataFrame
"""
n_periods = len(factors)
results = []
for t in range(window, n_periods):
factor_window = factors[t-window:t]
returns_window = returns[t-window:t]
ic, rank_ic = robust_ic_calculation(
factor_window,
returns_window,
min_periods=min_periods,
handle_na='drop'
)
if not np.isnan(ic):
results.append({
'date_idx': t,
'ic': ic,
'rank_ic': rank_ic,
'valid_periods': np.sum(~np.isnan(factor_window) & ~np.isnan(returns_window))
})
return pd.DataFrame(results)
テスト
np.random.seed(42)
n = 200
欠損値を含むテストデータ
factor = np.random.randn(n)
factor[10:15] = np.nan # 欠損値挿入
factor[50] = np.nan
returns = factor * 0.3 + 0.1 * np.random.randn(n)
returns[30:35] = np.nan
IC計算
ic, rank_ic = robust_ic_calculation(factor, returns, min_periods=30, handle_na='drop')
print(f"IC: {ic:.4f}, RankIC: {rank_ic:.4f}")
ローリングIC
rolling_ic_df = calculate_rolling_ic_with_nan_handling(factor, returns, window=60)
print(f"\nローリングIC計算完了: {len(rolling_ic_df)}件")
print(rolling_ic_df.describe())
エラー4:HolySheep APIのレートリミット対応
# 問題:API呼び出し時に429 Too Many Requestsエラー
原因:短時間での过多APIリクエスト
import asyncio
import aiohttp
from datetime import datetime, timedelta
from collections import deque
class RateLimitedHolySheepClient:
"""
レートリミット対応のHolySheep AIクライアント
特徴:
- トークンバケット算法によるレート制御
- 自動リトライ(指数バックオフ)