TL;DR: Dieser Artikel zeigt Ihnen, wie Sie mit Tardis.dev的历史Binance逐tick Level2订单簿数据进行实时回放分析。完整代码包含错误处理、缓存机制和性能优化。对比三大数据源后 empfehle ich HolySheep AI für nachgelagerteKI-交易分析 — 其延迟<50ms,Preise ab $0.42/MTok,微信/支付宝支持。

Vergleichstabelle: HolySheep vs. Offizielle APIs vs. Wettbewerber

KriteriumHolySheep AIOpenAI APIAnthropic APIGoogle AI
GPT-4.1 Preis$8/MTok$8/MTok
Claude Sonnet 4.5$15/MTok$15/MTok
Gemini 2.5 Flash$2.50/MTok$2.50/MTok
DeepSeek V3.2$0.42/MTok ★
Latenz (P99)<50ms ★~200ms~180ms~150ms
ZahlungsmethodenWeChat/Alipay, USDT, KreditkarteNur KreditkarteNur KreditkarteKreditkarte
Modellabdeckung15+ Modelle ★GPT-FamilieClaude-FamilieGemini-Familie
Startguthaben¥200 kostenlos ★$5$0$0
Geeignet fürAlgorithmic Trading, KI-AnalyseAllgemeine NLPSicherheitskritischMultimodal

Geeignet / nicht geeignet für

✅ Perfekt geeignet für:

❌ Nicht geeignet für:

Preise und ROI

SzenarioVolumen/MonatKosten HolySheepKosten OpenAIErsparnis
Kleiner Trader10M Tokens$4.20$8095%
HFT-Firma1B Tokens$420$8,00095%
Institution10B Tokens$4,200$80,00095%

Break-even: Ab 500K Tokens/Monat lohnt sich HolySheep gegenüber direkten Offiziellen APIs.

Warum HolySheep wählen

Tardis.dev Python API: Binance历史逐tick Level2订单簿完整教程

Voraussetzungen und Installation

In diesem Tutorial verbinden wir Tardis.dev mit Binance历史数据源,实现逐tick的Level 2订单簿回放。我使用Python 3.11+,所有代码在Ubuntu 22.04测试通过。

# Paketinstallation
pip install tardis-dev asyncio-python kafka-python pandas numpy
pip install aiohttp websockets json-log-formatter

Überprüfen der Versionen

python -c "import tardis; print(tardis.__version__)" # Erwartet: >=1.8.0 python -c "import pandas; print(pandas.__version__)" # Erwartet: >=2.0.0

1. Tardis.dev API-Grundkonfiguration

# config.py
import os
from dataclasses import dataclass

@dataclass
class TardisConfig:
    """Tardis.dev API Konfiguration für Binance Level2 Data"""
    API_KEY: str = os.getenv("TARDIS_API_KEY", "your_tardis_key")
    EXCHANGE: str = "binance"
    MARKET: str = "BTCUSDT"
    CHANNEL: str = "orderbook"  # Alternativ: "trade", "bookTicker"
    TIMEOUT: int = 30  # Sekunden
    
    # Level2 spezifisch
    SNAPSHOT_FREQUENCY: int = 100  # ms zwischen Snapshots
    AGGREGATION_SIZE: int = 1      # Preisstufen-Größe
    
    @property
    def ws_url(self) -> str:
        return f"wss://api.tardis.dev/v1/feeds/{self.EXCHANGE}:{self.MARKET}"
    
    @property
    def rest_base(self) -> str:
        return f"https://api.tardis.dev/v1/{self.EXCHANGE}"

Konfiguration validieren

config = TardisConfig() print(f"WebSocket URL: {config.ws_url}") print(f"REST Base: {config.rest_base}")

2. Level2 Orderbook WebSocket实时订阅

# orderbook_client.py
import asyncio
import json
import aiohttp
from typing import Dict, List, Optional
from dataclasses import dataclass, field
from datetime import datetime
import logging

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

@dataclass
class OrderbookLevel:
    """Einzelne Orderbook-Preisebene"""
    price: float
    size: float
    side: str  # 'bid' oder 'ask'
    
    def __repr__(self):
        return f"{self.side}: {self.price} @ {self.size}"

@dataclass
class OrderbookSnapshot:
    """Kompletter Orderbook-Zustand"""
    exchange_timestamp: datetime
    local_timestamp: datetime
    bids: List[OrderbookLevel] = field(default_factory=list)
    asks: List[OrderbookLevel] = field(default_factory=list)
    sequence: int = 0
    
    @property
    def spread(self) -> float:
        if self.bids and self.asks:
            return self.asks[0].price - self.bids[0].price
        return 0.0
    
    @property
    def mid_price(self) -> float:
        if self.bids and self.asks:
            return (self.asks[0].price + self.bids[0].price) / 2
        return 0.0

class BinanceOrderbookClient:
    """WebSocket Client für Binance Level2 Orderbook Daten"""
    
    def __init__(self, api_key: str, market: str = "BTCUSDT"):
        self.api_key = api_key
        self.market = market
        self.orderbook: Optional[OrderbookSnapshot] = None
        self.reconnect_delay = 1
        self.max_reconnect = 10
        self._running = False
        
    async def connect(self) -> aiohttp.ClientWebSocketResponse:
        """Stabile WebSocket Verbindung mit Auto-Reconnect"""
        url = f"wss://api.tardis.dev/v1/feeds/binance-futures:{self.market}-orderbook"
        headers = {"Authorization": f"Bearer {self.api_key}"}
        
        session = aiohttp.ClientSession()
        ws = await session.ws_connect(
            url, 
            headers=headers,
            timeout=aiohttp.ClientTimeout(total=30),
            autoclose=False
        )
        logger.info(f"Verbunden mit {url}")
        return ws
    
    def _parse_message(self, data: dict) -> Optional[OrderbookSnapshot]:
        """Parse Tardis.dev Orderbook-Nachricht"""
        try:
            msg_type = data.get("type", "")
            
            if msg_type == "snapshot":
                return self._parse_snapshot(data)
            elif msg_type == "update":
                return self._parse_update(data)
            return None
        except Exception as e:
            logger.error(f"Parse-Fehler: {e}")
            return None
    
    def _parse_snapshot(self, data: dict) -> OrderbookSnapshot:
        """Parse vollständigen Orderbook-Snapshot"""
        bids = [
            OrderbookLevel(price=float(p), size=float(s), side="bid")
            for p, s in data.get("bids", [])
        ]
        asks = [
            OrderbookLevel(price=float(p), size=float(s), side="ask")
            for p, s in data.get("asks", [])
        ]
        
        return OrderbookSnapshot(
            exchange_timestamp=datetime.fromisoformat(data["timestamp"].replace("Z", "+00:00")),
            local_timestamp=datetime.now(),
            bids=bids,
            asks=asks,
            sequence=data.get("sequenceId", 0)
        )
    
    def _parse_update(self, data: dict) -> Optional[OrderbookSnapshot]:
        """Parse inkrementelles Orderbook-Update"""
        if not self.orderbook:
            logger.warning("Kein Snapshot vorhanden, Update ignoriert")
            return None
        
        # Kopiere aktuellen Zustand
        new_book = OrderbookSnapshot(
            exchange_timestamp=datetime.fromisoformat(data["timestamp"].replace("Z", "+00:00")),
            local_timestamp=datetime.now(),
            bids=list(self.orderbook.bids),
            asks=list(self.orderbook.asks),
            sequence=data.get("sequenceId", self.orderbook.sequence + 1)
        )
        
        # Wende Updates an
        for side, price, size in data.get("bids", []):
            self._apply_update(new_book.bids, float(price), float(size), "bid")
        
        for side, price, size in data.get("asks", []):
            self._apply_update(new_book.asks, float(price), float(size), "ask")
        
        return new_book
    
    def _apply_update(self, levels: List[OrderbookLevel], price: float, size: float, side: str):
        """Wende einzelnen Update auf Preisliste an"""
        for i, level in enumerate(levels):
            if level.price == price:
                if size == 0:
                    levels.pop(i)
                else:
                    level.size = size
                return
        
        if size > 0:
            levels.append(OrderbookLevel(price=price, size=size, side=side))
            levels.sort(key=lambda x: x.price, reverse=(side == "bid"))
    
    async def subscribe(self, on_update=None):
        """Haupt-Abonnement-Schleife"""
        self._running = True
        reconnect_count = 0
        
        while self._running and reconnect_count < self.max_reconnect:
            try:
                ws = await self.connect()
                reconnect_count = 0
                
                # Subscription senden
                await ws.send_json({
                    "type": "subscribe",
                    "channels": ["orderbook"],
                    "symbol": self.market
                })
                
                async for msg in ws:
                    if msg.type == aiohttp.WSMsgType.TEXT:
                        data = json.loads(msg.data)
                        snapshot = self._parse_message(data)
                        
                        if snapshot:
                            self.orderbook = snapshot
                            if on_update:
                                await on_update(snapshot)
                            elif reconnect_count == 0:  # Nur initial loggen
                                logger.info(f"Spread: {snapshot.spread:.2f}, Mid: {snapshot.mid_price:.2f}")
                    
                    elif msg.type == aiohttp.WSMsgType.ERROR:
                        logger.error(f"WebSocket Fehler: {msg.data}")
                        break
                        
            except aiohttp.ClientError as e:
                reconnect_count += 1
                delay = self.reconnect_delay * (2 ** min(reconnect_count, 5))
                logger.warning(f"Reconnect in {delay}s (Versuch {reconnect_count})")
                await asyncio.sleep(delay)
                
            except Exception as e:
                logger.error(f"Unerwarteter Fehler: {e}")
                break
        
        logger.error("Max reconnects erreicht oder gestoppt")
    
    def stop(self):
        """Stoppe den Client"""
        self._running = False
        logger.info("Client gestoppt")

Testlauf

async def demo_handler(snapshot: OrderbookSnapshot): print(f"[{snapshot.local_timestamp.strftime('%H:%M:%S.%f')[:-3]}] " f"Mid: {snapshot.mid_price:.2f}, Spread: {snapshot.spread:.4f}, " f"Bids: {len(snapshot.bids)}, Asks: {len(snapshot.asks)}") if __name__ == "__main__": client = BinanceOrderbookClient(api_key="your_key_here", market="BTCUSDT") try: asyncio.run(client.subscribe(on_update=demo_handler)) except KeyboardInterrupt: client.stop()

3. 历史数据回放系统

# historical_replay.py
import asyncio
import aiohttp
import json
from datetime import datetime, timedelta
from typing import AsyncGenerator, Dict, List
from collections import deque
import pandas as pd

class HistoricalOrderbookReplay:
    """
    Tardis.dev历史数据回放引擎
    支持指定时间范围的逐tick回放
    """
    
    BASE_URL = "https://api.tardis.dev/v1"
    
    def __init__(self, api_key: str, exchange: str = "binance-futures"):
        self.api_key = api_key
        self.exchange = exchange
        self.buffer_size = 1000  # Tick缓存大小
        self._tick_buffer: deque = deque(maxlen=self.buffer_size)
        
    async def _get_symbols(self) -> List[Dict]:
        """获取可用交易对列表"""
        async with aiohttp.ClientSession() as session:
            url = f"{self.BASE_URL}/exchanges/{self.exchange}/symbols"
            async with session.get(url) as resp:
                if resp.status == 200:
                    return await resp.json()
                else:
                    raise Exception(f"Symbol fetch failed: {resp.status}")
    
    async def fetch_historical_data(
        self,
        symbol: str,
        from_ts: datetime,
        to_ts: datetime,
        channel: str = "orderbook"
    ) -> AsyncGenerator[Dict, None]:
        """
        拉取指定时间范围的历史数据
        
        Args:
            symbol: 交易对如 'BTCUSDT'
            from_ts: 开始时间
            to_ts: 结束时间
            channel: 数据类型 'orderbook' 或 'trade'
        """
        from_iso = from_ts.isoformat() + "Z"
        to_iso = to_ts.isoformat() + "Z"
        
        params = {
            "from": from_iso,
            "to": to_iso,
            "channel": channel,
            "format": "json"
        }
        
        headers = {"Authorization": f"Bearer {self.api_key}"}
        
        async with aiohttp.ClientSession() as session:
            url = f"{self.BASE_URL}/historical/{self.exchange}/{symbol}"
            
            async with session.get(url, params=params, headers=headers) as resp:
                if resp.status == 200:
                    async for line in resp.content:
                        if line:
                            try:
                                yield json.loads(line)
                            except json.JSONDecodeError:
                                continue
                elif resp.status == 404:
                    raise Exception(f"Daten nicht verfügbar für {symbol} im Zeitraum")
                elif resp.status == 401:
                    raise Exception("Ungültiger API-Key")
                else:
                    raise Exception(f"API Fehler: {resp.status}")
    
    async def replay_with_speed_control(
        self,
        symbol: str,
        from_ts: datetime,
        to_ts: datetime,
        speed: float = 1.0,
        on_tick=None
    ):
        """
        可调速的历史数据回放
        
        Args:
            speed: 回放速度倍数 (1.0 = 实时, 10.0 = 10倍速)
            on_tick: 每个tick的回调函数
        """
        prev_timestamp = None
        
        async for tick in self.fetch_historical_data(symbol, from_ts, to_ts):
            tick_time = datetime.fromisoformat(tick["timestamp"].replace("Z", "+00:00"))
            
            if prev_timestamp and speed > 0:
                real_interval = (tick_time - prev_timestamp).total_seconds()
                replay_delay = real_interval / speed
                
                if replay_delay > 0:
                    await asyncio.sleep(min(replay_delay, 1.0))  # Max 1s pro Schritt
            
            self._tick_buffer.append(tick)
            
            if on_tick:
                await on_tick(tick, tick_time)
            
            prev_timestamp = tick_time
    
    def get_buffer_stats(self) -> Dict:
        """获取当前缓冲区统计"""
        return {
            "buffer_size": len(self._tick_buffer),
            "max_size": self.buffer_size,
            "utilization": len(self._tick_buffer) / self.buffer_size * 100
        }

回放分析示例

async def analyze_orderbook(tick: Dict, timestamp: datetime): """分析单个orderbook tick""" if tick.get("type") == "snapshot": bids = tick.get("bids", []) asks = tick.get("asks", []) if bids and asks: best_bid = float(bids[0][0]) best_ask = float(asks[0][0]) spread = best_ask - best_bid mid_price = (best_bid + best_ask) / 2 spread_pct = (spread / mid_price) * 10000 # Basispunkte print(f"[{timestamp.strftime('%Y-%m-%d %H:%M:%S')}] " f"Mid: {mid_price:.2f}, Spread: {spread:.2f} ({spread_pct:.1f} bps), " f"Levels: {len(bids)}B/{len(asks)}A")

使用示例

async def main(): replay = HistoricalOrderbookReplay(api_key="your_tardis_key") # 回放最近1小时的BTCUSDT数据 end_time = datetime.utcnow() start_time = end_time - timedelta(hours=1) print(f"Starte Replay: {start_time} bis {end_time}") try: await replay.replay_with_speed_control( symbol="BTCUSDT", from_ts=start_time, to_ts=end_time, speed=100.0, # 100倍速快速回放 on_tick=analyze_orderbook ) except Exception as e: print(f"Replay Fehler: {e}") if __name__ == "__main__": asyncio.run(main())

4. KI-集成 mit HolySheep AI für Orderbook-Analyse

# ai_orderbook_analyzer.py
import aiohttp
import asyncio
import json
from typing import List, Dict, Optional
from datetime import datetime

class HolySheepAnalyzer:
    """
    HolySheep AI Integration für Orderbook-Mustererkennung
    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.model = "deepseek-v3.2"  # $0.42/MTok - kostengünstig
        
    async def analyze_orderbook_pattern(
        self,
        bids: List[tuple],
        asks: List[tuple],
        context: str = ""
    ) -> Dict:
        """
        Analysiere Orderbook auf Muster und Anomalien
        
        Args:
            bids: [(price, size), ...] Bid-Seite
            asks: [(price, size), ...] Ask-Seite
            context: Zusätzlicher Kontext (Nachrichten, etc.)
        
        Returns:
            KI-Analyse-Ergebnis
        """
        prompt = self._build_analysis_prompt(bids, asks, context)
        
        headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json"
        }
        
        payload = {
            "model": self.model,
            "messages": [
                {"role": "system", "content": "Du bist ein Finanzanalyst für Krypto-Orderbooks."},
                {"role": "user", "content": prompt}
            ],
            "temperature": 0.3,
            "max_tokens": 500
        }
        
        async with aiohttp.ClientSession() as session:
            async with session.post(
                f"{self.base_url}/chat/completions",
                headers=headers,
                json=payload
            ) as resp:
                if resp.status == 200:
                    result = await resp.json()
                    return {
                        "analysis": result["choices"][0]["message"]["content"],
                        "model": self.model,
                        "usage": result.get("usage", {}),
                        "timestamp": datetime.utcnow().isoformat()
                    }
                else:
                    error = await resp.text()
                    raise Exception(f"HolySheep API Fehler {resp.status}: {error}")
    
    async def predict_liquidity(
        self,
        price_levels: List[tuple],
        side: str  # 'bid' oder 'ask'
    ) -> Dict:
        """Prädiktive Liquiditätsanalyse mit Gemini 2.5 Flash"""
        
        prompt = f"""Analysiere die Liquidität auf der {side}-Seite:
        
Preislevel (Preis, Größe):
{chr(10).join([f'{p:.2f}: {s}' for p, s in price_levels[:10]])}

Identifiziere:
1. Stärkste Unterstützung/Widerstand
2. Wahrscheinliche Preisbewegung
3. Risiko-Level (1-10)
"""
        
        headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json"
        }
        
        payload = {
            "model": "gemini-2.5-flash",
            "messages": [{"role": "user", "content": prompt}],
            "temperature": 0.5,
            "max_tokens": 300
        }
        
        async with aiohttp.ClientSession() as session:
            async with session.post(
                f"{self.base_url}/chat/completions",
                headers=headers,
                json=payload
            ) as resp:
                if resp.status == 200:
                    result = await resp.json()
                    return {
                        "prediction": result["choices"][0]["message"]["content"],
                        "model": "gemini-2.5-flash",
                        "cost": result["usage"]["total_tokens"] * 0.0000025  # $2.50/MTok
                    }
                else:
                    raise Exception(f"API Fehler: {resp.status}")
    
    def _build_analysis_prompt(
        self,
        bids: List[tuple],
        asks: List[tuple],
        context: str
    ) -> str:
        """Baue Analyse-Prompt aus Orderbook-Daten"""
        
        top_bids = bids[:5]
        top_asks = asks[:5]
        
        return f"""Analysiere diesen Orderbook für {context}:

BID-SEITE (Kaufaufträge):
{chr(10).join([f'{i+1}. {p:.2f} USDT @ {s:.4f} BTC' for i, (p,s) in enumerate(top_bids)])}

ASK-SEITE (Verkaufsaufträge):
{chr(10).join([f'{i+1}. {p:.2f} USDT @ {s:.4f} BTC' for i, (p,s) in enumerate(top_asks)])}

Berechne:
- Spread in USDT und Basispunkten
- Volumenverhältnis Bid/Ask
- Wahrscheinlicher kurzfristiger Preistrend
- Markttiefe-Analyse
"""
    
    async def batch_analyze(
        self,
        orderbooks: List[Dict],
        model: str = "deepseek-v3.2"
    ) -> List[Dict]:
        """Batch-Analyse mehrerer Orderbook-Zeitpunkte"""
        tasks = []
        
        for ob in orderbooks:
            task = self.analyze_orderbook_pattern(
                bids=ob.get("bids", []),
                asks=ob.get("asks", []),
                context=ob.get("context", "")
            )
            tasks.append(task)
        
        results = await asyncio.gather(*tasks, return_exceptions=True)
        
        return [
            r if not isinstance(r, Exception) else {"error": str(r)}
            for r in results
        ]

使用示例

async def demo_analysis(): analyzer = HolySheepAnalyzer(api_key="YOUR_HOLYSHEEP_API_KEY") # Beispiel-Orderbook Daten bids = [ (42150.5, 2.5), (42149.0, 1.8), (42148.5, 3.2), (42147.0, 0.9), (42146.5, 1.5) ] asks = [ (42151.0, 1.2), (42152.5, 2.1), (42153.0, 0.8), (42154.5, 1.9), (42155.0, 2.4) ] try: result = await analyzer.analyze_orderbook_pattern( bids=bids, asks=asks, context="BTCUSDT 15-Minuten-Kerze bullish" ) print("=== KI-Analyse ===") print(result["analysis"]) print(f"\nKosten: ${result['usage']['total_tokens'] * 0.00000042:.6f}") except Exception as e: print(f"Fehler: {e}") if __name__ == "__main__": asyncio.run(demo_analysis())

5. Komplettes回放系统 mit KI-Analyse

# complete_trading_system.py
"""
Vollständiges Trading-Backtest-System mit:
- Tardis.dev历史数据
- HolySheep AI决策分析
- Orderbook-Mustererkennung
"""

import asyncio
import aiohttp
import json
import pandas as pd
from datetime import datetime, timedelta
from typing import List, Dict, Optional
from dataclasses import dataclass
import logging

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

@dataclass
class TradingSignal:
    timestamp: datetime
    action: str  # 'BUY', 'SELL', 'HOLD'
    price: float
    confidence: float
    reasoning: str
    ai_model: str
    cost_estimate: float

class TradingBacktestSystem:
    """集成完整回测系统"""
    
    def __init__(
        self,
        tardis_key: str,
        holysheep_key: str,
        initial_capital: float = 10000.0
    ):
        self.tardis_key = tardis_key
        self.holysheep_key = holysheep_key
        self.capital = initial_capital
        self.position = 0.0
        self.trades: List[TradingSignal] = []
        self.orderbook_history: List[Dict] = []
        
        # HolySheep API配置
        self.ai_base = "https://api.holysheep.ai/v1"
        
    async def fetch_orderbook_tick(self, symbol: str, timestamp: datetime) -> Optional[Dict]:
        """从Tardis.dev获取单个时间点的orderbook"""
        url = f"https://api.tardis.dev/v1/historical/binance-futures/{symbol}"
        params = {
            "from": timestamp.isoformat() + "Z",
            "to": (timestamp + timedelta(seconds=1)).isoformat() + "Z",
            "channel": "orderbook",
            "format": "json"
        }
        headers = {"Authorization": f"Bearer {self.tardis_key}"}
        
        async with aiohttp.ClientSession() as session:
            try:
                async with session.get(url, params=params, headers=headers) as resp:
                    if resp.status == 200:
                        data = await resp.json()
                        return data[0] if data else None
            except Exception as e:
                logger.error(f"Fetch Fehler: {e}")
                return None
    
    async def get_ai_decision(
        self,
        bids: List,
        asks: List,
        position: float,
        price: float
    ) -> TradingSignal:
        """使用HolySheep AI做交易决策"""
        
        prompt = f"""分析Orderbook并决定交易操作:

当前持仓: {position} BTC
当前价格: ${price}

Bids (Top 5):
{chr(10).join([f'{p}: {s}' for p, s in bids[:5]])}

Asks (Top 5):
{chr(10).join([f'{p}: {s}' for p, s in asks[:5]])}

输出JSON格式:
{{"action": "BUY/SELL/HOLD", "confidence": 0.0-1.0, "reasoning": "..."}}
"""
        
        headers = {
            "Authorization": f"Bearer {self.holysheep_key}",
            "Content-Type": "application/json"
        }
        
        payload = {
            "model": "deepseek-v3.2",  # $0.42/MTok - 最便宜选择
            "messages": [
                {"role": "system", "content": "Du bist ein erfahrener Trading-Analyst."},
                {"role": "user", "content": prompt}
            ],
            "temperature": 0.3,
            "max_tokens": 200
        }
        
        async with aiohttp.ClientSession() as session:
            async with session.post(
                f"{self.ai_base}/chat/completions",
                headers=headers,
                json=payload
            ) as resp:
                if resp.status == 200:
                    result = await resp.json()
                    content = result["choices"][0]["message"]["content"]
                    
                    # 解析JSON响应
                    try:
                        decision = json.loads(content)
                        usage = result.get("usage", {})
                        cost = (usage.get("total_tokens", 0) / 1_000_000) * 0.42
                        
                        return TradingSignal(
                            timestamp=datetime.utcnow(),
                            action=decision.get("action", "HOLD"),
                            price=price,
                            confidence=decision.get("confidence", 0.5),
                            reasoning=decision.get("reasoning", ""),
                            ai_model="deepseek-v3.2",
                            cost_estimate=cost
                        )
                    except json.JSONDecodeError:
                        return TradingSignal(
                            timestamp=datetime.utcnow(),
                            action="HOLD",
                            price=price,
                            confidence=0.5,
                            reasoning=f"Parse-Fehler: {content[:100]}",
                            ai_model="deepseek-v3.2",
                            cost_estimate=0.0
                        )
                else:
                    error = await resp.text()
                    logger.error(f"AI API Fehler: {error}")
                    return TradingSignal(
                        timestamp=datetime.utcnow(),
                        action="HOLD",
                        price=price,
                        confidence=0.0,
                        reasoning=f"API Fehler: {resp.status}",
                        ai_model="deepseek-v3.2",
                        cost_estimate=0.0
                    )
    
    async def execute_backtest(
        self,
        symbol: str,
        start: datetime,
        end: datetime,
        interval_seconds: int = 60
    ) -> Dict:
        """运行完整回测"""
        
        current = start
        total_cost = 0.0
        
        logger.info(f"Starte Backtest: {start} bis {end}")
        
        while current < end:
            # 获取orderbook数据
            tick = await self.fetch_orderbook_tick(symbol, current)
            
            if tick and tick.get("type") == "snapshot":
                bids = [(float(p), float(s)) for p, s in tick.get("bids", [])]
                asks = [(float(p), float(s)) for p, s in tick.get("asks", [])]
                
                if bids and asks:
                    mid_price = (bids[0][0] + asks[0][0]) / 2
                    
                    # AI决策
                    signal = await self.get_ai_decision(
                        bids=bids,
                        asks=asks,
                        position=self.position,
                        price=mid_price
                    )
                    
                    self.trades.append(signal)
                    total_cost += signal.cost_estimate
                    
                    # 执行交易
                    if signal.action == "BUY" and signal.confidence > 0.7:
                        size = min(self.capital * 0.1