結論:首先说结论 — 暗号資産トレーディングにおいて複数取引所のOrder Bookをリアルタイムで統合分析したいなら、HolySheep AIの強みを活かした「Tardis + HolySheep」アーキテクチャが最適です。公式API比85%のコスト削減、¥1=$1の固定レート、<50msのレイテンシで、本番環境でも安心して運用できます。
本記事の目的と対象読者
本ガイドでは、暗号資産取引所の_tick data_を提供するTardisとHolySheep AIを組み合わせ、多取引所のTimestamp归一化とOrder Bookマージを実装する方法を実践的に解説します。
- Quant系トレーダー(自作bot開発者)
- 暗号資産ヘッジファンドのクオンツ�
- ブロックチェーン解析スタートアップの技術者
- 高頻度取引システムの構築を検討中の事業者
向いている人・向いていない人
✅ 向いている人
- 複数取引所の板情報を使って裁定取引やArbitrage機会を探したい人
- 低コストで高いレイテンシ性能が必要な人
- WeChat Pay / Alipayでスムーズに決済したい人
- 日本語サポート接受的で日本語ドキュメントを求める人
- 自作botや分析システムにAPI統合したい人
❌ 向いていない人
- Tardisの生的ストリームデータのみを必要とし、追加処理が不要な人
- $10,000/月以上の予算がありDedicatedインフラを求める大企業
- 非暗号資産的传统金融データ分析のみを必要とする人
- API経由ではなく直接的市场データを 요구するブローカー
価格とROI
| Provider | 価格モデル | 1BTC約$70,000時 月間コスト試算 | TTM(Thumb-to-Market) | 対応通貨 | 決済手段 |
|---|---|---|---|---|---|
| HolySheep AI | ¥1=$1(公式¥7.3比85%節約) | GPT-4.1: $8/MTok、Claude Sonnet 4.5: $15/MTok、Gemini 2.5 Flash: $2.50/MTok、DeepSeek V3.2: $0.42/MTok | <50ms | WeChat Pay、Alipay、USDT、他 | 多通貨対応・日本語対応 |
| 公式 OpenAI API | GPT-4o: $5/MTok(入力)、$15/MTok(出力) | 同上基準で計算 | 100-300ms | USDのみ | クレジットカード |
| 公式 Anthropic API | Claude 3.5 Sonnet: $3/MTok(入力)、$15/MTok(出力) | 同上基準で計算 | 80-200ms | USDのみ | クレジットカード |
| Tardis(Market Data専用) | €99/月〜(Basic)、€499/月〜(Pro) | 約$107〜$539/月 | <10ms(原生) | EUR | クレジットカード、Wire |
HolySheep ROI 分析
- 月次コスト削減: 公式API比最大85%OFF(¥1=$1レート適用時)
- 初期費用: 登録で無料クレジット付与(今すぐ登録)
- 開発速度: <50msレイテンシでProduction-readyなbot開発が可能
Tardisとは?多取引所データ取得の課題
Tardis(https://tardis.dev)は、板情報(Order Book)、約定履歴(Trade)、狼狽売(Settlement)などのMarket Dataを複数の暗号資産取引所から提供するSaaSです。
Tardisの主要機能
- リアルタイムストリーミング: WebSocket経由で複数の取引所からLIVEデータを受信
- ヒストリカルデータ: 過去データのアーカイブにアクセス可能
- 対応取引所: Binance, Bybit, OKX, Bitget, Deribit, Bybit, Gate.io, Huobi, Kraken, Coinbase等
多取引所データ統合の3大課題
- タイムスタンプの不整合: 各取引所がUTC、Unix timestamp、JSTなど異なる時刻系を使用
- Order Book構造の多様性: 取引所に依存するPrice Level、Bid/Askの順序違い
- ネットワークレイテンシ: 分散されたサーバーからのデータ到着順序の保証なし
HolySheep AIを選ぶ理由
HolySheep AI(HolySheep AI)は、上記の課題を解決するために最適化されたLLM API統合プラットフォームです。
| 機能 | HolySheep AI | 競合サービス |
|---|---|---|
| レート | ¥1=$1(公式比85%節約) | 公式APIR比高价 |
| レイテンシ | <50ms | 100-300ms |
| 決済 | WeChat Pay / Alipay / USDT対応 | クレジットカードのみ |
| 対応モデル | GPT-4.1、Claude Sonnet 4.5、Gemini 2.5 Flash、DeepSeek V3.2 | 单一或有限 |
| 日本語対応 | 完全対応 | 限定或不対応 |
| Free Credits | 登録時付与 | なし |
実践編:Tardis + HolySheepで跨所Order Book統合
全体アーキテクチャ
┌─────────────────────────────────────────────────────────────────┐
│ システム全体構成 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ WebSocket ┌──────────────────────────┐ │
│ │ Tardis │ ──────────────► │ Data Normalizer │ │
│ │ (Market) │ raw stream │ - Timestamp归一化 │ │
│ └──────────────┘ │ - Order Book構造统一 │ │
│ └───────────┬──────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────┐ │
│ │ HolySheep AI LLM │ │
│ │ - Arbitrage機会検知 │ │
│ │ - 異常値検知 │ │
│ │ - トレンド分析 │ │
│ └───────────┬──────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────┐ │
│ │ Trading Bot / Alert │ │
│ │ - 自動执行 │ │
│ │ - LINE/Slack通知 │ │
│ └──────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
Step 1: Tardisからのリアルタイムデータ取得
"""
Tardis WebSocketリアルタイムストリームからOrder Bookデータを取得
https://docs.tardis.dev/docs/websocket
"""
import asyncio
import json
from datetime import datetime, timezone
from typing import Dict, List, Optional
import websockets
from dataclasses import dataclass, field
from sortedcontainers import SortedDict
@dataclass
class NormalizedOrderBook:
"""归一化後のOrder Book"""
exchange: str
symbol: str
timestamp: datetime
bids: List[tuple[float, float]] # (price, size)
asks: List[tuple[float, float]]
best_bid: float = 0.0
best_ask: float = 0.0
spread: float = 0.0
spread_pct: float = 0.0
@dataclass
class RawTardisMessage:
"""Tardisからの生メッセージ"""
type: str
exchange: str
data: dict
timestamp: float = field(default_factory=lambda: datetime.now(timezone.utc).timestamp())
class TardisOrderBookFetcher:
"""TardisからリアルタイムOrder Bookデータを取得"""
EXCHANGES = ['binance', 'bybit', 'okx', 'bitget']
SYMBOLS = ['BTC-USDT', 'ETH-USDT']
def __init__(self, api_key: str):
self.api_key = api_key
self.order_books: Dict[str, Dict[str, SortedDict]] = {}
self.last_messages: Dict[str, dict] = {}
async def connect(self, exchanges: List[str] = None, symbols: List[str] = None):
"""Tardis WebSocketに接続"""
exchanges = exchanges or self.EXCHANGES
symbols = symbols or self.SYMBOLS
# Tardis WebSocket URL構築
channels = []
for symbol in symbols:
for exchange in exchanges:
channels.append(f"{exchange}:{symbol.replace('-', '')}")
ws_url = f"wss://stream.tardis.dev/v1/ws?channels={','.join(channels)}&key={self.api_key}"
print(f"[Tardis] Connecting to: {ws_url[:80]}...")
async with websockets.connect(ws_url) as ws:
print(f"[Tardis] Connected to {len(channels)} channels")
# 初期订阅確認メッセージ
subscribe_msg = {
"type": "subscribe",
"channels": channels
}
await ws.send(json.dumps(subscribe_msg))
async for message in ws:
await self._process_message(message)
async def _process_message(self, raw_message: str):
"""メッセージの処理と正規化"""
try:
msg = json.loads(raw_message)
msg_type = msg.get('type', '')
if msg_type == 'book':
await self._handle_orderbook_snapshot(msg)
elif msg_type == 'book_update':
await self._handle_orderbook_update(msg)
elif msg_type == 'trade':
await self._handle_trade(msg)
except json.JSONDecodeError as e:
print(f"[Error] JSON decode failed: {e}")
except Exception as e:
print(f"[Error] Message processing failed: {e}")
async def _handle_orderbook_snapshot(self, msg: dict):
"""板情報のスナップショット処理"""
exchange = msg.get('exchange', '')
symbol = msg.get('symbol', '')
data = msg.get('data', {})
# Timestamp归一化:すべてUTCに変換
ts_ms = data.get('timestamp', 0) or data.get('ts', 0)
normalized_ts = datetime.fromtimestamp(
ts_ms / 1000 if ts_ms > 1e10 else ts_ms,
tz=timezone.utc
)
bids = SortedDict(lambda x: -x) # 降順
asks = SortedDict() # 昇順
for bid in data.get('bids', []):
price, size = float(bid[0]), float(bid[1])
if size > 0:
bids[price] = size
for ask in data.get('asks', []):
price, size = float(ask[0]), float(ask[1])
if size > 0:
asks[price] = size
key = f"{exchange}:{symbol}"
self.order_books[key] = {'bids': bids, 'asks': asks}
self.last_messages[key] = {'timestamp': normalized_ts, 'type': 'snapshot'}
async def _handle_orderbook_update(self, msg: dict):
"""板情報の差分更新処理"""
exchange = msg.get('exchange', '')
symbol = msg.get('symbol', '')
data = msg.get('data', {})
key = f"{exchange}:{symbol}"
if key not in self.order_books:
return
bids = self.order_books[key]['bids']
asks = self.order_books[key]['asks']
# Bid更新
for bid in data.get('bids', []):
price, size = float(bid[0]), float(bid[1])
if size == 0:
bids.pop(price, None)
else:
bids[price] = size
# Ask更新
for ask in data.get('asks', []):
price, size = float(ask[0]), float(ask[1])
if size == 0:
asks.pop(price, None)
else:
asks[price] = size
# Timestamp更新
ts_ms = data.get('timestamp', 0) or data.get('ts', 0)
normalized_ts = datetime.fromtimestamp(
ts_ms / 1000 if ts_ms > 1e10 else ts_ms,
tz=timezone.utc
)
self.last_messages[key] = {'timestamp': normalized_ts, 'type': 'update'}
def get_normalized_book(self, exchange: str, symbol: str) -> Optional[NormalizedOrderBook]:
""" 정규화된Order Bookを取得 """
key = f"{exchange}:{symbol}"
if key not in self.order_books:
return None
book_data = self.order_books[key]
msg_data = self.last_messages.get(key, {})
bids = book_data['bids']
asks = book_data['asks']
best_bid = bids.keys()[0] if len(bids) > 0 else 0.0
best_ask = asks.keys()[0] if len(asks) > 0 else 0.0
spread = best_ask - best_bid
spread_pct = (spread / best_ask * 100) if best_ask > 0 else 0.0
return NormalizedOrderBook(
exchange=exchange,
symbol=symbol,
timestamp=msg_data.get('timestamp', datetime.now(timezone.utc)),
bids=[(p, bids[p]) for p in list(bids.keys())[:20]],
asks=[(p, asks[p]) for p in list(asks.keys())[:20]],
best_bid=best_bid,
best_ask=best_ask,
spread=spread,
spread_pct=spread_pct
)
使用例
async def main():
fetcher = TardisOrderBookFetcher(api_key="YOUR_TARDIS_API_KEY")
await fetcher.connect(
exchanges=['binance', 'bybit'],
symbols=['BTC-USDT']
)
if __name__ == "__main__":
asyncio.run(main())
Step 2: HolySheep AIでArbitrage機会を分析
"""
HolySheep AI APIを使用して跨所Arbitrage機会を分析
Base URL: https://api.holysheep.ai/v1
"""
import asyncio
import json
import os
from typing import List, Dict, Optional
from dataclasses import dataclass
from datetime import datetime, timezone
import aiohttp
from tenacity import retry, stop_after_attempt, wait_exponential
HolySheep API設定
HOLYSHEEP_BASE_URL = "https://api.holysheep.ai/v1"
HOLYSHEEP_API_KEY = os.getenv("HOLYSHEEP_API_KEY", "YOUR_HOLYSHEEP_API_KEY")
@dataclass
class ArbitrageOpportunity:
"""裁定取引機会"""
buy_exchange: str
sell_exchange: str
symbol: str
buy_price: float
sell_price: float
profit_pct: float
potential_volume: float
estimated_profit_usdt: float
timestamp: datetime
confidence: float # 信頼度 0-1
@dataclass
class HolySheepResponse:
"""HolySheep API応答"""
content: str
usage: dict
latency_ms: float
class HolySheepLLMClient:
"""HolySheep AI LLM APIクライアント"""
def __init__(self, api_key: str):
self.api_key = api_key
self.base_url = HOLYSHEEP_BASE_URL
@retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=1, max=10))
async def analyze_arbitrage(
self,
order_books: List[dict],
symbol: str
) -> HolySheepResponse:
"""
HolySheep AI APIでArbitrage機会を分析
Args:
order_books: 正規化されたOrder Bookデータリスト
symbol: 取引ペア(例:BTC-USDT)
Returns:
Arbitrage分析結果
"""
headers = {
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"
}
# プロンプト構築
system_prompt = """あなたは暗号資産取引所の裁定取引(Arbitrage)分析 전문가입니다。
以下の複数取引所のOrder Bookデータを分析し、Arbitrage機会を提案してください。
分析項目:
1. 最高買値(Best Bid)と最高売値(Best Ask)の取引所特定
2. 裁定取引可能額を計算
3. 取引手数料を差し引いた純利益を算出
4. リスク要因(流動性、板の厚み)を評価
必ず以下のJSON形式で返答してください:
{
"opportunities": [
{
"buy_exchange": "購入先取引所",
"sell_exchange": "売却先取引所",
"buy_price": 数値,
"sell_price": 数値,
"profit_pct": 数値,
"potential_volume": 推奨取引量,
"estimated_profit_usdt": 推定利益,
"confidence": 0.0-1.0,
"risk_factors": ["リスク1", "リスク2"]
}
],
"market_summary": "市場概要"
}"""
user_prompt = f"以下の{symbol} Order Bookデータを分析してください:\n\n"
for book in order_books:
user_prompt += f"""
=== {book['exchange'].upper()} ===
Best Bid: ${book['best_bid']:.2f} (size: {book.get('bid_size', 'N/A')})
Best Ask: ${book['best_ask']:.2f} (size: {book.get('ask_size', 'N/A')})
Spread: {book.get('spread_pct', 0):.4f}%
Timestamp: {book.get('timestamp', 'N/A')}
"""
payload = {
"model": "gpt-4.1", # $8/MTok - HolySheep価格
"messages": [
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_prompt}
],
"temperature": 0.3,
"response_format": {"type": "json_object"}
}
start_time = asyncio.get_event_loop().time()
async with aiohttp.ClientSession() as session:
async with session.post(
f"{self.base_url}/chat/completions",
headers=headers,
json=payload,
timeout=aiohttp.ClientTimeout(total=10)
) as response:
if response.status != 200:
error_text = await response.text()
raise Exception(f"HolySheep API Error: {response.status} - {error_text}")
data = await response.json()
latency_ms = (asyncio.get_event_loop().time() - start_time) * 1000
content = data['choices'][0]['message']['content']
usage = data.get('usage', {})
return HolySheepResponse(
content=content,
usage=usage,
latency_ms=latency_ms
)
async def analyze_with_deepseek(
self,
order_books: List[dict],
symbol: str
) -> HolySheepResponse:
"""
DeepSeek V3.2モデルを使用($0.42/MTok - 最も安価)
"""
headers = {
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"
}
user_prompt = f"Analyze {symbol} for arbitrage opportunities from these order books:\n"
for book in order_books:
user_prompt += f"- {book['exchange']}: Bid {book['best_bid']}, Ask {book['best_ask']}\n"
payload = {
"model": "deepseek-v3.2", # $0.42/MTok
"messages": [
{"role": "user", "content": user_prompt}
],
"temperature": 0.2
}
start_time = asyncio.get_event_loop().time()
async with aiohttp.ClientSession() as session:
async with session.post(
f"{self.base_url}/chat/completions",
headers=headers,
json=payload,
timeout=aiohttp.ClientTimeout(total=10)
) as response:
data = await response.json()
latency_ms = (asyncio.get_event_loop().time() - start_time) * 1000
return HolySheepResponse(
content=data['choices'][0]['message']['content'],
usage=data.get('usage', {}),
latency_ms=latency_ms
)
class CrossExchangeArbitrageAnalyzer:
"""跨所裁定取引アナライザー"""
def __init__(self, holy_sheep_client: HolySheepLLMClient):
self.client = holy_sheep_client
self.opportunities: List[ArbitrageOpportunity] = []
async def analyze_opportunities(
self,
normalized_books: List[dict]
) -> List[ArbitrageOpportunity]:
"""
全取引所のOrder BookからArbitrage機会を分析
Args:
normalized_books: NormalizedOrderBookの辞書リスト
Returns:
検出された裁定取引機会リスト
"""
if len(normalized_books) < 2:
return []
symbol = normalized_books[0]['symbol']
# HolySheep AIで分析
response = await self.client.analyze_arbitrage(normalized_books, symbol)
print(f"[HolySheep] Response received in {response.latency_ms:.2f}ms")
print(f"[HolySheep] Usage: {response.usage}")
# 応答をパース
try:
result = json.loads(response.content)
opportunities = []
for opp in result.get('opportunities', []):
arp = ArbitrageOpportunity(
buy_exchange=opp['buy_exchange'],
sell_exchange=opp['sell_exchange'],
symbol=symbol,
buy_price=opp['buy_price'],
sell_price=opp['sell_price'],
profit_pct=opp['profit_pct'],
potential_volume=opp['potential_volume'],
estimated_profit_usdt=opp['estimated_profit_usdt'],
timestamp=datetime.now(timezone.utc),
confidence=opp['confidence']
)
opportunities.append(arp)
self.opportunities = opportunities
return opportunities
except json.JSONDecodeError as e:
print(f"[Error] Failed to parse HolySheep response: {e}")
return []
def find_best_arbitrage(
self,
min_profit_pct: float = 0.1,
min_confidence: float = 0.7
) -> Optional[ArbitrageOpportunity]:
"""最高利益の機会を返す"""
valid = [
opp for opp in self.opportunities
if opp.profit_pct >= min_profit_pct
and opp.confidence >= min_confidence
]
if not valid:
return None
return max(valid, key=lambda x: x.estimated_profit_usdt)
async def main():
# HolySheepクライアント初期化
client = HolySheepLLMClient(api_key=HOLYSHEEP_API_KEY)
analyzer = CrossExchangeArbitrageAnalyzer(client)
# サンプルOrder Bookデータ
sample_books = [
{
"exchange": "binance",
"symbol": "BTC-USDT",
"best_bid": 67450.00,
"best_ask": 67455.00,
"bid_size": 2.5,
"ask_size": 1.8,
"spread_pct": 0.0074,
"timestamp": datetime.now(timezone.utc).isoformat()
},
{
"exchange": "bybit",
"symbol": "BTC-USDT",
"best_bid": 67458.00,
"best_ask": 67462.00,
"bid_size": 1.2,
"ask_size": 0.9,
"spread_pct": 0.0059,
"timestamp": datetime.now(timezone.utc).isoformat()
},
{
"exchange": "okx",
"symbol": "BTC-USDT",
"best_bid": 67448.00,
"best_ask": 67452.00,
"bid_size": 3.0,
"ask_size": 2.2,
"spread_pct": 0.0059,
"timestamp": datetime.now(timezone.utc).isoformat()
}
]
# Arbitrage分析実行
opportunities = await analyzer.analyze_opportunities(sample_books)
print(f"\n=== Detected {len(opportunities)} Arbitrage Opportunities ===")
for opp in opportunities:
print(f"""
{opp.buy_exchange} → {opp.sell_exchange}
Profit: {opp.profit_pct:.4f}%
Volume: {opp.potential_volume} BTC
Est. Profit: {opp.estimated_profit_usdt:.2f} USDT
Confidence: {opp.confidence:.0%}
""")
if __name__ == "__main__":
asyncio.run(main())
Step 3: Order Book統合クラス(最終版)
"""
完全版:Tardis + HolySheep 跨所Order Book統合システム
"""
import asyncio
from dataclasses import dataclass, field
from datetime import datetime, timezone
from typing import Dict, List, Optional, Tuple
from sortedcontainers import SortedDict
import json
@dataclass
class MergedOrderBook:
"""統合Order Book"""
symbol: str
timestamp: datetime
source_exchanges: List[str]
merged_bids: List[Dict] # [{exchange, price, size}]
merged_asks: List[Dict]
arbitrage_windows: List[Dict] # 裁定可能窗口
def to_json(self) -> dict:
return {
"symbol": self.symbol,
"timestamp": self.timestamp.isoformat(),
"source_exchanges": self.source_exchanges,
"merged_bids": self.merged_bids[:10],
"merged_asks": self.merged_asks[:10],
"arbitrage_windows": self.arbitrage_windows
}
class OrderBookMerger:
"""
複数取引所のOrder Bookを統合
裁定取引可能な価格帯を検出
"""
# 取引手数料(例:Binance: 0.1%, Bybit: 0.1%)
EXCHANGE_FEES = {
'binance': 0.001,
'bybit': 0.001,
'okx': 0.0015,
'bitget': 0.001,
'gateio': 0.002,
}
def __init__(self, symbol: str, exchanges: List[str]):
self.symbol = symbol
self.exchanges = exchanges
self.order_books: Dict[str, dict] = {}
self.last_update: Dict[str, datetime] = {}
def update_book(self, exchange: str, book_data: dict):
"""各取引所のOrder Bookを更新"""
self.order_books[exchange] = book_data
self.last_update[exchange] = datetime.now(timezone.utc)
def merge(self, depth: int = 20) -> MergedOrderBook:
"""
全取引所のOrder Bookを板の深さで統合
統合戦略:
1. 全取引所のBid/Askを集約
2. 取引所別にソート
3. 裁定取引可能窗口を計算
"""
all_bids = [] # [(exchange, price, size)]
all_asks = [] # [(exchange, price, size)]
for exchange, book in self.order_books.items():
fee = self.EXCHANGE_FEES.get(exchange, 0.001)
# Bid追加(板の厚みを考虑)
for price, size in book.get('bids', [])[:depth]:
all_bids.append({
'exchange': exchange,
'price': price,
'size': size,
'fee': fee
})
# Ask追加
for price, size in book.get('asks', [])[:depth]:
all_asks.append({
'exchange': exchange,
'price': price,
'size': size,
'fee': fee
})
# 価格でソート
all_bids.sort(key=lambda x: x['price'], reverse=True)
all_asks.sort(key=lambda x: x['price'])
# 裁定取引窗口を検出
arbitrage_windows = self._find_arbitrage_windows(all_bids, all_asks)
return MergedOrderBook(
symbol=self.symbol,
timestamp=datetime.now(timezone.utc),
source_exchanges=list(self.order_books.keys()),
merged_bids=all_bids[:depth],
merged_asks=all_asks[:depth],
arbitrage_windows=arbitrage_windows
)
def _find_arbitrage_windows(
self,
bids: List[dict],
asks: List[dict]
) -> List[dict]:
"""
裁定取引可能な窗口を検出
Buy Low, Sell High戦略:
- ある取引所のAsk < 別の取引所のBid なら裁定可能
- 手数料を差し引いて純利益を計算
"""
windows = []
for bid in bids:
for ask in asks:
# 同じ取引所は無視
if bid['exchange'] == ask['exchange']:
continue
# 裁定可能条件:Bid > Ask
gross_profit = (bid['price'] - ask['price']) / ask['price'] * 100
# 手数料計算
total_fees = (bid['fee'] + ask['fee']) * 100
# 純利益
net_profit = gross_profit - total_fees
if net_profit > 0:
# 取引可能量を計算
max_volume = min(bid['size'], ask['size'])
estimated_profit = max_volume * (bid['price'] - ask['price'])
windows.append({
'buy_exchange': ask['exchange'],
'buy_price': ask['price'],
'sell_exchange': bid['exchange'],
'sell_price': bid['price'],
'gross_profit_pct': round(gross_profit, 4),
'total_fees_pct': round(total_fees, 4),
'net_profit_pct': round(net_profit, 4),
'max_volume': round(max_volume, 6),
'estimated_profit_usdt': round(estimated_profit, 2),
'detected_at': datetime.now(timezone.utc).isoformat()
})
# 利益率でソート
windows.sort(key=lambda x: x['net_profit_pct'], reverse=True)
return windows[:10] # Top 10
def get_cross_exchange_spread(self) -> Dict:
"""跨所スプレッドを取得"""
all_best_bids = []
all_best_asks = []
for exchange, book in self.order_books.items():
bids = book.get('bids', [])
asks = book.get('asks', [])
if bids:
all_best_bids.append((exchange, bids[0][0], bids[0][1]))
if asks:
all_best_asks.append((exchange, asks[0][0], asks[0][1]))
if not all_best_bids or not all_best_asks:
return {}
# 最高Bid vs 最低Ask
best_bid = max(all_best_bids, key=lambda x: x[1])
best_ask = min(all_best_asks, key=lambda x: x[1])
spread = best_bid[1] - best_ask[1]
spread_pct = spread / best_ask[1] * 100
return {
'best_bid': {
'exchange': best_bid[0],
'price': best_bid[1],
'size': best_bid[2]
},
'best_ask': {
'exchange': best_ask[0],
'price': best_ask[1],
'size': best_ask[2]
},
'spread': round(spread, 2),
'spread_pct': round(spread_pct, 4)
}