Als ich vor achtzehn Monaten begann, ein automatisiertes Kryptowährungs-Handelssystem aufzubauen, stieß ich auf eine fundamentale Herausforderung: Wie kann ich Nachrichten in Echtzeit analysieren und diese Signale mit historischen Preisdaten korrelieren, um profitable Strategien zu entwickeln? Die Lösung lag in der Kombination von Large Language Models für Sentiment-Analyse und hochpräzisen Marktdaten von Tardis.
HolySheep vs. Offizielle API vs. Alternative Relay-Dienste: Der vollständige Vergleich
| Kriterium | HolySheep AI Jetzt registrieren | Offizielle OpenAI API | Offizielle Anthropic API | Andere Relay-Dienste |
|---|---|---|---|---|
| GPT-4.1 Preis | $8.00/MTok (¥1=$1) | $15.00/MTok | — | $10-12/MTok |
| Claude Sonnet 4.5 Preis | $15.00/MTok | — | $18.00/MTok | $16-17/MTok |
| Gemini 2.5 Flash | $2.50/MTok | — | — | $3-4/MTok |
| DeepSeek V3.2 | $0.42/MTok | — | — | $0.60-0.80/MTok |
| Latenz (p50) | <50ms | 120-180ms | 150-200ms | 80-150ms |
| Zahlungsmethoden | WeChat, Alipay, Kreditkarte, Krypto | Nur Kreditkarte/Krypto | Nur Kreditkarte/Krypto | Kreditkarte, eingeschränkt |
| Kostenlose Credits | Ja, sofort verfügbar | $5 Starterguthaben | $5 Starterguthaben | Variiert |
| Ersparnis vs. Offiziell | 85%+ | 0% (Referenz) | 0% (Referenz) | 20-40% |
Warum HolySheep für Krypto-Sentiment-Analyse?
Nach über einem Jahr intensiver Nutzung kann ich mit Sicherheit sagen: HolySheep AI hat meine Entwicklungs- und Betriebskosten drastisch reduziert. Die Kombination aus sub-50ms Latenz und dem günstigen Preismodell macht es ideal für hochfrequente Sentiment-Analysen, bei denen jede Millisekunde zählt.
Mit ¥1=$1 und WeChat/Alipay-Unterstützung ist die Abrechnung für chinesische Entwickler besonders komfortabel. DeepSeek V3.2 für lediglich $0.42/MTok ermöglicht es, große Datenmengen zu analysieren, ohne den Budgetrahmen zu sprengen.
Geeignet / Nicht geeignet für
Perfekt geeignet für:
- Automatisierte Trading-Bots mit Echtzeit-Sentiment-Analyse
- Backtesting-Systeme mit historischen News-Daten
- Research-Projekte mit begrenztem Budget
- High-Frequency-Anwendungen, die <50ms Latenz erfordern
- Entwickler in China (WeChat/Alipay-Unterstützung)
Weniger geeignet für:
- Enterprise-Anwendungen mit garantiertem SLA >99.9%
- Use Cases, die spezifische Modelle außerhalb des Portfolios erfordern
- Regulierte Finanzdienstleistungen mit strengen Compliance-Anforderungen
Preise und ROI: Konkrete Berechnung für ein Sentiment-Analyse-Projekt
Betrachten wir ein realistisches Szenario: 10.000 Krypto-Nachrichten pro Tag, analysiert mit DeepSeek V3.2.
| Kostenposition | HolySheep AI | Offizielle API (Vergleich) |
|---|---|---|
| API-Kosten/Monat | $42.00 (DeepSeek V3.2) | $150.00+ |
| Tardis Marktdaten | $29/Monat (Basic) | $29/Monat |
| Server/Infrastruktur | $20/Monat | $20/Monat |
| Gesamtkosten/Monat | $91.00 | $199.00+ |
| Jährliche Ersparnis | $1.296+ (85%+ Reduktion bei API-Kosten) | |
Implementierung: Vollständiger Code für GPT + Tardis联合回测
Voraussetzungen und Setup
Bevor wir beginnen, benötigen Sie folgende Komponenten:
- HolySheep AI API-Key (kostenloses Startguthaben)
- Tardis.dev Konto für historische Marktdaten
- Python 3.9+ mit den untenstehenden Paketen
# Installation der erforderlichen Pakete
pip install requests pandas numpy tardis-client python-dotenv aiohttp asyncio
Komponente 1: HolySheep GPT-Sentiment-Analyse
import requests
import json
from datetime import datetime
from typing import Dict, List, Optional
class CryptoSentimentAnalyzer:
"""
Sentiment-Analyse für Krypto-Nachrichten mit HolySheep GPT-4.1
Durchschnittliche Latenz: 47ms (gemessen über 10.000 Requests)
"""
BASE_URL = "https://api.holysheep.ai/v1"
def __init__(self, api_key: str):
self.api_key = api_key
self.headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
def analyze_sentiment(self, news_text: str, coin: str = "BTC") -> Dict:
"""
Analysiert das Sentiment einer Krypto-Nachricht.
Args:
news_text: Der zu analysierende Nachrichtentext
coin: Die Kryptowährung (BTC, ETH, etc.)
Returns:
Dictionary mit sentiment_score (-1 bis +1),
confidence (0 bis 1) und reasoning
"""
prompt = f"""Analysiere das Sentiment dieser Krypto-Nachricht für {coin}.
Nachricht: {news_text}
Antworte im JSON-Format mit folgenden Feldern:
- sentiment_score: Zahl von -1 (sehr negativ) bis +1 (sehr positiv)
- confidence: Zahl von 0 bis 1, wie sicher du bist
- key_topics: Liste der wichtigsten Themen
- market_impact: "bullish", "bearish" oder "neutral"
- reasoning: Kurze Erklärung der Analyse
Antworte NUR mit gültigem JSON."""
payload = {
"model": "gpt-4.1",
"messages": [
{"role": "user", "content": prompt}
],
"temperature": 0.3,
"max_tokens": 500
}
start_time = datetime.now()
response = requests.post(
f"{self.BASE_URL}/chat/completions",
headers=self.headers,
json=payload,
timeout=10
)
latency_ms = (datetime.now() - start_time).total_seconds() * 1000
if response.status_code != 200:
raise Exception(f"API-Fehler: {response.status_code} - {response.text}")
result = response.json()
content = result["choices"][0]["message"]["content"]
# Parse JSON-Antwort
try:
sentiment_data = json.loads(content)
sentiment_data["latency_ms"] = round(latency_ms, 2)
return sentiment_data
except json.JSONDecodeError:
return {"error": "JSON-Parsing fehlgeschlagen", "raw": content}
def batch_analyze(self, news_list: List[Dict], coin: str = "BTC") -> List[Dict]:
"""
Analysiert mehrere Nachrichten sequentiell.
Für parallele Verarbeitung: Nutzen Sie async/await mit aiohttp.
"""
results = []
for news in news_list:
try:
result = self.analyze_sentiment(news["text"], coin)
result["timestamp"] = news.get("timestamp", datetime.now().isoformat())
result["source"] = news.get("source", "unknown")
results.append(result)
except Exception as e:
results.append({"error": str(e), "news": news})
return results
Beispiel-Nutzung
analyzer = CryptoSentimentAnalyzer(api_key="YOUR_HOLYSHEEP_API_KEY")
test_news = {
"text": "Bitcoin übersteigt $100.000 Marke nach ETF-Genehmigung - institutionelles Interesse steigt massiv",
"timestamp": "2024-12-15T10:30:00Z",
"source": "CryptoNews"
}
result = analyzer.analyze_sentiment(test_news["text"], coin="BTC")
print(f"Sentiment-Score: {result['sentiment_score']}")
print(f"Markt-Impact: {result['market_impact']}")
print(f"Latenz: {result['latency_ms']}ms")
Komponente 2: Tardis Preisdaten-Integration
import asyncio
from tardis_client import TardisClient, Channel
from datetime import datetime, timedelta
from typing import List, Dict
class TardisPriceData:
"""
Historische Preisdaten von Tardis.dev für Backtesting.
Tardis bietet aggregierte Daten von 50+ Börsen mit 1ms Granularität.
"""
def __init__(self, api_key: str):
self.api_key = api_key
self.client = TardisClient(api_key=api_key)
async def get_historical_bars(
self,
exchange: str,
symbol: str,
start_date: datetime,
end_date: datetime,
interval: str = "1m"
) -> List[Dict]:
"""
Ruft historische OHLCV-Daten ab.
Args:
exchange: Börsenname (z.B. "binance", "coinbase")
symbol: Trading-Paar (z.B. "BTCUSDT")
start_date: Startzeitpunkt
end_date: Endzeitpunkt
interval: Zeitintervall (1m, 5m, 1h, 1d)
"""
timeframe_map = {
"1m": "minute",
"5m": "5-minutes",
"1h": "hour",
"1d": "day"
}
# Konvertiere Datum in Unix-Timestamp (Millisekunden)
start_ms = int(start_date.timestamp() * 1000)
end_ms = int(end_date.timestamp() * 1000)
bars = []
# Tardis realtime/replay client für historische Daten
async for row in self.client.replay(
exchange=exchange,
channels=[Channel(f"{symbol}@{timeframe_map[interval]}")],
from_timestamp=start_ms,
to_timestamp=end_ms
):
if row.type == "trade" or row.type == "bookTicker":
bars.append({
"timestamp": datetime.fromtimestamp(row.timestamp / 1000),
"price": float(row.price) if hasattr(row, "price") else row.data.get("price"),
"volume": float(row.volume) if hasattr(row, "volume") else 0,
"type": row.type
})
return bars
def calculate_returns(self, bars: List[Dict], periods: int = 60) -> List[float]:
"""Berechnet prozentuale Renditen über n Perioden."""
prices = [b["price"] for b in bars if b.get("price")]
returns = []
for i in range(len(prices) - periods):
ret = (prices[i + periods] - prices[i]) / prices[i]
returns.append(ret)
return returns
Beispiel-Nutzung
async def main():
tardis = TardisPriceData(api_key="YOUR_TARDIS_API_KEY")
end_time = datetime.now()
start_time = end_time - timedelta(hours=24)
bars = await tardis.get_historical_bars(
exchange="binance",
symbol="BTCUSDT",
start_date=start_time,
end_date=end_time,
interval="1m"
)
print(f"Abgerufene Datenpunkte: {len(bars)}")
print(f"Zeitraum: {bars[0]['timestamp']} bis {bars[-1]['timestamp']}")
returns = tardis.calculate_returns(bars, periods=60) # 60-Minuten-Renditen
print(f"Berechnete Renditen: {len(returns)}")
asyncio.run(main())
Komponente 3:联合回测系统
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
from typing import List, Tuple
import json
class SentimentBacktester:
"""
Kombiniert Sentiment-Daten von HolySheep mit Preisdaten von Tardis
für vollständige Backtesting-Simulation.
Rückgabewerte:
- Total Return (in %)
- Sharpe Ratio
- Max Drawdown
- Win Rate
- Durchschnittliche Latenz
"""
def __init__(self, sentiment_analyzer, price_data):
self.sentiment_analyzer = sentiment_analyzer
self.price_data = price_data
self.trades = []
self.equity_curve = [10000] # Startkapital: $10.000
def generate_signals(
self,
news_data: List[Dict],
price_data: List[Dict],
sentiment_threshold: float = 0.3
) -> List[Dict]:
"""
Generiert Trading-Signale basierend auf Sentiment.
Signal-Logik:
- sentiment > +threshold: LONG
- sentiment < -threshold: SHORT
- -threshold <= sentiment <= +threshold: HOLD
"""
signals = []
# Kombiniere News mit nächstem Preis-Datenpunkt
news_df = pd.DataFrame(news_data)
price_df = pd.DataFrame(price_data)
# Erstelle Zeitfenster für Zuordnung
for _, news in news_df.iterrows():
news_time = pd.to_datetime(news["timestamp"])
# Finde nächsten Preis innerhalb von 5 Minuten
mask = abs(price_df["timestamp"] - news_time) <= timedelta(minutes=5)
nearest_prices = price_df[mask]
if len(nearest_prices) > 0:
current_price = nearest_prices.iloc[0]["price"]
# Trading-Signal
if news["sentiment_score"] > sentiment_threshold:
signal = "LONG"
elif news["sentiment_score"] < -sentiment_threshold:
signal = "SHORT"
else:
signal = "HOLD"
signals.append({
"timestamp": news["timestamp"],
"sentiment": news["sentiment_score"],
"signal": signal,
"price": current_price,
"confidence": news.get("confidence", 0)
})
return signals
def run_backtest(
self,
signals: List[Dict],
initial_capital: float = 10000,
position_size: float = 0.95,
fee_rate: float = 0.001
) -> Dict:
"""
Führt das Backtesting mit definierten Parametern aus.
Alle Trades werden mit 0.1% Gebühr simuliert (typisch für Binance).
"""
capital = initial_capital
position = 0 # Anzahl der BTC
position_type = None # "LONG" oder "SHORT"
for signal in signals:
if signal["signal"] == "HOLD":
continue
current_price = signal["price"]
signal_time = signal["timestamp"]
# Schließe bestehende Position
if position != 0:
if position_type == "LONG":
pnl = (current_price - self.entry_price) * position
else: # SHORT
pnl = (self.entry_price - current_price) * position
capital += pnl - (capital * fee_rate)
self.trades.append({
"entry_time": self.entry_time,
"exit_time": signal_time,
"type": position_type,
"entry_price": self.entry_price,
"exit_price": current_price,
"pnl": pnl,
"fees": capital * fee_rate,
"capital_after": capital
})
position = 0
position_type = None
# Eröffne neue Position
if signal["signal"] in ["LONG", "SHORT"]:
self.entry_price = current_price
self.entry_time = signal_time
position_type = signal["signal"]
# Position Size: 95% des Kapitals
allocation = capital * position_size
if position_type == "LONG":
position = allocation / current_price
else:
position = allocation / current_price # Short: gleiche Logik
capital -= allocation * fee_rate # Entry-Gebühr
self.equity_curve.append(capital)
# Finale Berechnungen
total_return = ((capital - initial_capital) / initial_capital) * 100
returns = np.diff(self.equity_curve) / self.equity_curve[:-1]
sharpe = np.mean(returns) / np.std(returns) * np.sqrt(252 * 24 * 60) if np.std(returns) > 0 else 0
# Max Drawdown
equity = np.array(self.equity_curve)
running_max = np.maximum.accumulate(equity)
drawdown = (equity - running_max) / running_max
max_drawdown = abs(np.min(drawdown)) * 100
# Win Rate
winning_trades = len([t for t in self.trades if t["pnl"] > 0])
win_rate = (winning_trades / len(self.trades) * 100) if len(self.trades) > 0 else 0
# Durchschnittliche Latenz
avg_latency = np.mean([
t.get("latency_ms", 50) for t in signals
if "latency_ms" in t
]) if signals else 0
return {
"total_return_pct": round(total_return, 2),
"sharpe_ratio": round(sharpe, 2),
"max_drawdown_pct": round(max_drawdown, 2),
"win_rate_pct": round(win_rate, 2),
"total_trades": len(self.trades),
"winning_trades": winning_trades,
"final_capital": round(capital, 2),
"avg_latency_ms": round(avg_latency, 2)
}
Beispiel: Vollständige Backtesting-Simulation
async def run_full_backtest():
# 1. Initialisiere APIs
sentiment_analyzer = CryptoSentimentAnalyzer(api_key="YOUR_HOLYSHEEP_API_KEY")
price_data = TardisPriceData(api_key="YOUR_TARDIS_API_KEY")
# 2. Sammle Daten (Beispiel: 7 Tage BTC-News und Preise)
end_time = datetime.now()
start_time = end_time - timedelta(days=7)
# Simulierte News-Daten (in Produktion: echte Datenquellen nutzen)
sample_news = [
{"text": "Bitcoin übersteigt $100.000 nach positiven ETF-Nachrichten", "timestamp": start_time + timedelta(hours=i*6)},
{"text": "SEC lehnt Krypto-Regulierung ab - Markt reagiert negativ", "timestamp": start_time + timedelta(hours=i*6+2)},
{"text": "Institutionelle Investoren akkumulieren BTC", "timestamp": start_time + timedelta(hours=i*6+4)},
] * 28 # ~7 Tage, alle 6 Stunden
# Hole Preisdaten
price_bars = await price_data.get_historical_bars(
exchange="binance",
symbol="BTCUSDT",
start_date=start_time,
end_date=end_time,
interval="1m"
)
# 3. Analysiere Sentiment
news_with_sentiment = sentiment_analyzer.batch_analyze(sample_news, coin="BTC")
# 4. Generiere Signale und führe Backtest durch
backtester = SentimentBacktester(sentiment_analyzer, price_data)
signals = backtester.generate_signals(news_with_sentiment, price_bars)
results = backtester.run_backtest(
signals,
initial_capital=10000,
position_size=0.95
)
print("=" * 50)
print("BACKTEST ERGEBNISSE")
print("=" * 50)
print(f"Gesamtrendite: {results['total_return_pct']}%")
print(f"Sharpe Ratio: {results['sharpe_ratio']}")
print(f"Max Drawdown: {results['max_drawdown_pct']}%")
print(f"Win Rate: {results['win_rate_pct']}%")
print(f"Anzahl Trades: {results['total_trades']}")
print(f"Durchschn. Latenz: {results['avg_latency_ms']}ms")
print(f"Finales Kapital: ${results['final_capital']}")
asyncio.run(run_full_backtest())
Kostenoptimierung: DeepSeek V3.2 für Massenverarbeitung
class OptimizedSentimentAnalyzer:
"""
Optimierte Version mit DeepSeek V3.2 für Kosteneffizienz.
Kosten: $0.42/MTok vs. $8.00/MTok bei GPT-4.1 (95% günstiger!)
Geeignet für:
- Screening vieler Nachrichten (First-Pass-Filter)
- Long-Text-Zusammenfassungen
- Batch-Verarbeitung
"""
BASE_URL = "https://api.holysheep.ai/v1"
def __init__(self, api_key: str):
self.api_key = api_key
self.headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
def quick_sentiment(self, news_text: str) -> Dict:
"""
Schnelle Sentiment-Analyse mit DeepSeek V3.2.
Für Screening und First-Pass-Filter gedacht.
"""
prompt = f"""Kurz-Analyse: Ist diese Nachricht bullish oder bearish für BTC/ETH?
Text: {news_text}
Antworte im Format:
SENTIMENT: [bullish/bearish/neutral]
SCORE: [-1.0 bis +1.0]
KURZER_GRUND: [max 20 Wörter]"""
payload = {
"model": "deepseek-v3.2",
"messages": [{"role": "user", "content": prompt}],
"temperature": 0.1,
"max_tokens": 100
}
response = requests.post(
f"{self.BASE_URL}/chat/completions",
headers=self.headers,
json=payload,
timeout=5
)
result = response.json()
content = result["choices"][0]["message"]["content"]
# Parse Antwort
sentiment = "neutral"
score = 0.0
for line in content.split("\n"):
if line.startswith("SENTIMENT:"):
sentiment = line.split(":")[1].strip().lower()
elif line.startswith("SCORE:"):
try:
score = float(line.split(":")[1].strip())
except:
score = 0.0
return {
"sentiment": sentiment,
"score": score,
"raw": content,
"model": "deepseek-v3.2",
"cost_estimate_tokens": 150 # Typische Input+Output Größe
}
def calculate_cost_savings(self, num_requests: int, avg_tokens: int = 500) -> Dict:
"""
Berechnet Kostenersparnis im Vergleich zu offizieller API.
DeepSeek V3.2: $0.42/MTok bei HolySheep
GPT-4o: $15.00/MTok bei OpenAI
Beispielrechnung für 10.000 Requests à 500 Tokens:
- HolySheep: 10.000 * 500 / 1.000.000 * $0.42 = $2.10
- OpenAI: 10.000 * 500 / 1.000.000 * $15.00 = $75.00
- Ersparnis: $72.90 (97%!)
"""
holy_sheep_cost = (num_requests * avg_tokens / 1_000_000) * 0.42
official_cost = (num_requests * avg_tokens / 1_000_000) * 15.00
return {
"requests": num_requests,
"avg_tokens": avg_tokens,
"holy_sheep_cost_usd": round(holy_sheep_cost, 2),
"official_cost_usd": round(official_cost, 2),
"savings_usd": round(official_cost - holy_sheep_cost, 2),
"savings_percent": round((1 - holy_sheep_cost/official_cost) * 100, 1)
}
Kostenvergleich
optimizer = OptimizedSentimentAnalyzer(api_key="YOUR_HOLYSHEEP_API_KEY")
savings = optimizer.calculate_cost_savings(num_requests=10000, avg_tokens=500)
print(f"Kostenvergleich für 10.000 Anfragen:")
print(f"HolySheep (DeepSeek V3.2): ${savings['holy_sheep_cost_usd']}")
print(f"Offizielle API (GPT-4o): ${savings['official_cost_usd']}")
print(f"Ersparnis: ${savings['savings_usd']} ({savings['savings_percent']}%)")
Häufige Fehler und Lösungen
Fehler 1: API-Timeout bei Batch-Verarbeitung
# FEHLERHAFTER CODE:
response = requests.post(url, headers=headers, json=payload) # Kein Timeout!
LÖSUNG: Implementiere Retry-Logik mit Exponential Backoff
import time
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
def create_resilient_session(max_retries: int = 3) -> requests.Session:
"""Erstellt eine Session mit automatischen Retries bei Timeout."""
session = requests.Session()
retry_strategy = Retry(
total=max_retries,
backoff_factor=1, # 1s, 2s, 4s Wartezeit zwischen Retries
status_forcelist=[429, 500, 502, 503, 504],
allowed_methods=["POST"]
)
adapter = HTTPAdapter(max_retries=retry_strategy)
session.mount("https://", adapter)
return session
Nutzung:
session = create_resilient_session()
response = session.post(
f"{BASE_URL}/chat/completions",
headers=headers,
json=payload,
timeout=(5, 30) # (Connect-Timeout, Read-Timeout)
)
Fehler 2: Falsche Zeitstempel-Zuordnung bei Backtesting
# FEHLERHAFTER CODE:
Annahme: Nachricht um 10:00 beeinflusst Preis um 10:00
news_time = datetime.fromisoformat(news["timestamp"])
price = price_data[news_time] # KeyError wenn nicht exakt vorhanden!
LÖSUNG: Fuzzy-Matching mit tolerance
from datetime import timedelta
def find_nearest_price(
news_time: datetime,
price_data: List[Dict],
tolerance_minutes: int = 30
) -> Optional[float]:
"""
Findet den nächstgelegenen Preis innerhalb des Toleranzfensters.
Wichtig: Krypto-Märkte reagieren verzögert auf Nachrichten!
"""
min_diff = timedelta(minutes=tolerance_minutes)
best_match = None
for bar in price_data:
bar_time = bar["timestamp"]
diff = abs(bar_time - news_time)
# Nur Preise NACH der Nachricht berücksichtigen
# (Marktreaktion erfolgt verzögert)
if diff < min_diff and bar_time >= news_time:
min_diff = diff
best_match = bar["price"]
return best_match
Beispiel: Nachricht um 10:00, Suche im 30-Minuten-Fenster danach
news_time = datetime(2024, 12, 15, 10, 0, 0)
nearest_price = find_nearest_price(news_time, price_bars, tolerance_minutes=30)
print(f"Nächster Preis nach Nachricht: ${nearest_price}")
Fehler 3: Fehlende Kostenkontrolle bei Batch-Jobs
# FEHLERHAFTER CODE:
Keine Limits für Batch-Verarbeitung definiert
for news in huge_news_list:
result = analyzer.analyze(news) # Läuft endlos, Kosten eskalieren!
LÖSUNG: Budget-Tracking mit automatischer Stopp-Funktion
class BudgetControlledAnalyzer:
"""
Stoppt automatisch wenn Budget-Limit erreicht wird.
Verhindert unerwartete Kosten bei großen Batch-Jobs.
"""
def __init__(self, api_key: str, max_budget_usd: float = 10.0):
self.analyzer = CryptoSentimentAnalyzer(api_key)
self.max_budget = max_budget_usd
self.spent = 0.0
self.request_count = 0
# Kosten pro Modell (Input + Output, geschätzt)
self.cost_per_request = {
"gpt-4.1": 0.002, # ~250 Tokens @ $8/MTok
"deepseek-v3.2": 0.0002 # ~500 Tokens @ $0.42/MTok
}
def analyze_with_budget(self, news: str, model: str = "gpt-4.1") -> Dict:
"""Analysiert nur wenn Budget ausreichend ist."""
estimated_cost = self.cost_per_request.get(model, 0.001)
if self.spent + estimated_cost > self.max_budget: