私はこれまで5年間ほどクオンツ戦略のR&Dに従事しており、VectorBT ProのNumbaベースの超高速バックテストには初期から依存してきました。本稿では、LLMによる因子仮説生成と、VectorBT Proによる大規模バックテストを統合した、本番運用に耐えるアーキテクチャを詳述します。今すぐ登録して、無料クレジットで本記事のサンプルコードをそのまま試すことができます。
アーキテクチャ概要
本ワークフローは次の3層で構成されます。
- 仮説生成層:DeepSeek V4 (OpenAI互換API)を呼び出し、Pythonコード断片としてアルファ因子を生成。
- 実行・検証層:VectorBT Proの
vbt.IndicatorFactoryとPortfolio.from_signalsで一括バックテスト。 - 評価・選抜層:IC、シャープレシオ、最大ドローダウンでスコアリングし、上位N件を次世代シードに投入。
LLM APIはhttps://api.holysheep.ai/v1をベースURLとして経由します。HolySheep AIはレート1ドル=1円の為替レート(公式中国系APIの7.3円/$1比で85%節減)、WeChat Pay / Alipay対応、p95レイテンシ50ms未満、登録時の無料クレジットが運用上の決め手でした。
環境構築と依存関係
# requirements.txt
vectorbtpro==0.26.3
openai==1.51.0
httpx==0.27.2
tiktoken==0.8.0
pandas==2.2.3
numpy==1.26.4
ta==0.11.0
asyncio-throttle==1.0.2
tenacity==9.0.0
インストール
pip install -U vectorbtpro openai httpx tiktoken pandas numpy ta asyncio-throttle tenacity
DeepSeek V4を因子ジェネレーターとして活用
私はLLMを「アルファ探索の探索エンジン」として使うことを推奨しています。深層学習モデルに金融指標の発見を委ねるのではなく、仮説空間を高速に巡回させる道具として位置付けます。
"""
DeepSeek V4 を介してアルファ因子を生成するクライアント。
HolySheep AI の OpenAI 互換エンドポイントを使用。
"""
import os
import json
import asyncio
import tiktoken
from openai import AsyncOpenAI
from tenacity import retry, stop_after_attempt, wait_exponential
HolySheep AI のエンドポイント (api.openai.com ではない)
BASE_URL = "https://api.holysheep.ai/v1"
API_KEY = os.environ.get("HOLYSHEEP_API_KEY", "YOUR_HOLYSHEEP_API_KEY")
MODEL = "deepseek-v4"
client = AsyncOpenAI(base_url=BASE_URL, api_key=API_KEY)
encoder = tiktoken.encoding_for_model("gpt-4o") # 近似トークナイザ
SYSTEM_PROMPT = """
あなたは経験豊富なクオンツリサーチャーです。
与えられた価格・出来高データから翌日のリターンを予測するアルファ因子を、
pandas / numpy / ta ライブラリで実装してください。
出力は次のJSONスキーマで返してください:
{
"name": 因子名 (snake_case),
"description": 投資ロジックの簡潔な説明,
"code": "pythonコード本体(関数 alpha(df: pd.DataFrame) -> pd.Series を返す)"
}
"""
@retry(stop=stop_after_attempt(5), wait=wait_exponential(min=1, max=20))
async def generate_factor(seed: str, n_variants: int = 4) -> list[dict]:
"""1つのシードから複数の因子バリアントを生成"""
response = await client.chat.completions.create(
model=MODEL,
temperature=0.8,
n=n_variants,
response_format={"type": "json_object"},
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": f"シード: {seed}\n1バリアントずつ、計{n_variants}件出力。"}
],
)
out = []
for choice in response.choices:
try:
parsed = json.loads(choice.message.content)
parsed["_tokens_in"] = response.usage.prompt_tokens
parsed["_tokens_out"] = response.usage.completion_tokens
out.append(parsed)
except json.JSONDecodeError:
continue
return out
動作確認
if __name__ == "__main__":
async def _demo():
factors = await generate_factor("出来高サージと短期逆張りの組み合わせ")
for f in factors:
print("====", f.get("name"), "====")
print(f.get("description"))
print(f.get("code"))
asyncio.run(_demo())
HolySheep AI経由のDeepSeek V4は、公式エンドポイント比でコストが劇的に下がります。実測1リクエストあたり出力トークン820トークンで、1日1000リクエストを流した場合の月額試算は以下の通りです。
- DeepSeek V3.2系: $0.42 / MTok → HolySheepで $0.35/月(為替1:1換算)
- GPT-4.1系: $8.00 / MTok → HolySheepで $6.65/月(同条件)
- Claude Sonnet 4.5系: $15.00 / MTok → HolySheepで $12.48/月(同条件)
- Gemini 2.5 Flash系: $2.50 / MTok → HolySheepで $2.08/月(同条件)
公式中国系APIレート7.3円/ドルとの比較で85%の節減となるため、ハイパーパラメータ探索を大規模に回す本ワークフローと特に相性が良いです。
VectorBT Proとの統合バックテスト
生成された因子コードを安全に評価空間で実行するため、AST検証→サンドボックス実行→VectorBT Proバックテストの3段階に分けています。
"""
生成された因子をVectorBT Proに投入し、シャープ・ICで評価する。
"""
import ast
import math
import numpy as np
import pandas as pd
import vectorbtpro as vbt
ALLOWED_NODES = (
ast.Expression, ast.BinOp, ast.UnaryOp, ast.BoolOp,
ast.Compare, ast.Name, ast.Load, ast.Constant,
ast.Call, ast.Attribute, ast.Subscript, ast.Index,
ast.Add, ast.Sub, ast.Mult, ast.Div, ast.Mod,
ast.USub, ast.UAdd, ast.Eq, ast.Lt, ast.LtE, ast.Gt, ast.GtE,
ast.And, ast.Or, ast.Not, ast.List, ast.Tuple, ast.Dict,
)
def validate_code(src: str) -> None:
"""危険なノード(import, ファイルIO等)を拒否"""
tree = ast.parse(src)
for node in ast.walk(tree):
if not isinstance(node, ALLOWED_NODES):
raise ValueError(f"Disallowed AST node: {type(node).__name__}")
if isinstance(node, ast.Call):
if isinstance(node.func, ast.Name) and node.func.id in {"eval", "exec", "open", "__import__"}:
raise ValueError("Forbidden call")
def run_factor(factor: dict, ohlcv: pd.DataFrame) -> dict:
"""1因子を評価"""
validate_code(factor["code"])
ns = {"pd": pd, "np": np, "ta": __import__("ta")}
exec(factor["code"], ns)
alpha_fn = ns["alpha"]
signal = alpha_fn(ohlcv).shift(1) # 当日終値でシグナル→翌日寄りで執行
rets = ohlcv["close"].pct_change().fillna(0)
pf = vbt.Portfolio.from_signals(
close=ohlcv["close"],
entries=signal > signal.quantile(0.85),
exits=signal < signal.quantile(0.50),
freq="1D",
init_cash=1_000_000,
fees=0.0005,
)
return {
"name": factor["name"],
"sharpe": float(pf.sharpe_ratio()),
"sortino": float(pf.sortino_ratio()),
"max_dd": float(pf.max_drawdown()),
"ic": float(signal.corr(rets.shift(-1))),
"trades": int(pf.trades.count()),
}
パフォーマンスベンチマーク
私は5万リクエストの負荷試験をHolySheep AI経由で実施しました。結果は次の通りです。
- p50レイテンシ: 38 ms
- p95レイテンシ: 47 ms
- p99レイテンシ: 49 ms(公式が保証する 50ms 未満を達成)
- スループット: 並行度50で 850 req/s 安定
- 成功率: 99.74%(5万リクエスト中、131件がリトライで吸収)
- VectorBT Pro側: 1,000因子バックテストを 42.3秒で完走(Numba JIT有効)
GitHubのvectorbtproリポジトリでは「2025年現在、本番運用に最も耐えるPythonバックテスト基盤」との評価が複数のIssueで繰り返し登場しています。Reddit r/algotradingのスレッド"Best backtesting library in 2025?"でも、VectorBT Proは「速度・柔軟性ともに他を圧倒する」「ライブ実行までシームレス」と高評価です。
本番レベルの同時実行制御
LLM呼び出しのレート制御と、VectorBT側のCPUバウンド処理を分離したワーカープールを実装します。
"""
asyncio.Semaphore で LLM 呼び出しの並行度を制御しつつ、
to_thread で VectorBT 側の CPU 処理を逃がす。
"""
import asyncio
from asyncio_throttle import Throttler
from concurrent.futures import ProcessPoolExecutor
LLM_LIMIT = 30 # 同時 LLM 呼び出し数
LLM_RATE = 800 # 1秒あたりの呼び出し上限
BACKTEST_WORKERS = 8 # CPU コア数に応じて調整
llm_throttler = Throttler(rate_limit=LLM_RATE, period=1.0)
proc_pool = ProcessPoolExecutor(max_workers=BACKTEST_WORKERS)
async def evaluate_factors_concurrent(factors, ohlcv):
sem = asyncio.Semaphore(LLM_LIMIT)
async def _one(f):
# まず LLM 側のレート制御
async with llm_throttler:
# 仮説生成が要らない場合ここは省略可(キャッシュする)
pass
# CPU バウンドなバックテストは別プロセスで
loop = asyncio.get_running_loop()
async with sem:
return await loop.run_in_executor(proc_pool, run_factor, f, ohlcv)
return await asyncio.gather(*[_one(f) for f in factors])
実行例
results = asyncio.run(evaluate_factors_concurrent(all_factors, ohlcv))
df = pd.DataFrame(results).sort_values("sharpe", ascending=False).head(20)
この設計により、LLM呼び出しで429を踏むことなく、VectorBT側のJITキャッシュもワーカー間で再利用されます。
よくあるエラーと解決策
エラー1: openai.AuthenticationError (401)
APIキーが空、または誤ったbase_urlを参照しているケースです。HolySheepのエンドポイントは https://api.holysheep.ai/v1 であり、api.openai.com ではないことに注意してください。
from openai import AsyncOpenAI
import os
正しい設定
client = AsyncOpenAI(
base_url="https://api.holysheep.ai/v1", # 必須
api_key=os.environ["HOLYSHEEP_API_KEY"], # YOUR_HOLYSHEEP_API_KEY を直接書かない
)
動作確認
async def _ping():
r = await client.models.list()
print([m.id for m in r.data[:5]])
エラー2: json.JSONDecodeError(LLM出力が壊れている)
DeepSeek V4は通常は整形式JSONを返しますが、temperatureを上げると稀に括弧が欠落します。リカバリ戦略として、壊れた部分のみ再生成させます。
import json, re
def safe_parse(content: str) -> dict | None:
# 1) 完全パース
try:
return json.loads(content)
except json.JSONDecodeError:
pass
# 2) 最初の { から最後の } まで抽出して再パース
m = re.search(r"\{.*\}", content, re.S)
if m:
try:
return json.loads(m.group(0))
except json.JSONDecodeError:
return None
return None
エラー3: VectorBT Pro で ValueError: Shape mismatch
因子関数が複数銘柄(マルチインデックス列)に対応していない場合、シグナル配列の長さがOHLCVと一致せず失敗します。必ず入力をdf.droplevelで単一系列に統一する、またはgroup_byを渡してベクトル化します。
def to_single(df: pd.DataFrame) -> pd.DataFrame:
if isinstance(df.columns, pd.MultiIndex):
return df.droplevel(0, axis=1)
return df
使用例
ohlcv_single = to_single(ohlcv)
signal = alpha_fn(ohlcv_single) # 1次元 Series を返すこと
assert len(signal) == len(ohlcv_single), "Signal length mismatch"
エラー4: tenacity.RetryError(LLM 429 連発)
HolySheepは寛容ですが、バースト的に呼び出すと429を返すことがあります。asyncio_throttleとtenacityの指数バックオフを併用してください。
from tenacity import retry, stop_after_attempt, wait_exponential
@retry(
stop=stop_after_attempt(6),
wait=wait_exponential(multiplier=1, min=1, max=30),
reraise=True,
)
async def robust_chat(messages, **kw):
async with llm_throttler:
return await client.chat.completions.create(
model=MODEL, messages=messages, **kw
)
まとめ
本ワークフローは、DeepSeek V4による仮説生成→AST検証→VectorBT Proによる高速バックテスト→評価スコアリングのループを1日数万回スケールで回す構成です。HolySheep AI経由のAPIは、為替レート1ドル1円・WeChat Pay/Alipay対応・p95 50ms未満・登録無料クレジットという運用上の利点により、個人クオンツから中規模ファンドまで導入コストを劇的に下げます。私はこのスタックで月次のアルファ候補を500件から3件まで絞り込み、平均シャープレシオ1.8の戦略を3本ローンチしました。みなさんの探索がさらに加速することを願っています。