ef7ea500a9
- Implement comprehensive Bitcoin trading signal system - Add MACD (Moving Average Convergence Divergence) indicator - Integrate news sentiment analysis from CryptoCompare - Combine technical analysis with market sentiment - Generate trading recommendations (Strong Buy, Buy, Hold, Sell, Strong Sell) Features: - Real-time Bitcoin price data from Binance and CoinGecko APIs - Historical data analysis with MACD indicator - News sentiment analysis with keyword-based scoring - Weighted signal combination (60% MACD, 40% Sentiment) - Confidence scoring for each recommendation - Detailed reasoning for trading signals - CLI interface with verbose and quick modes Components: - data_fetcher.py: Bitcoin price and market data retrieval - macd_indicator.py: MACD calculation and signal generation - news_sentiment.py: News analysis and sentiment scoring - signal_generator.py: Combined signal generation - bitcoin_trader.py: Main CLI application Usage: python bitcoin_trading/bitcoin_trader.py [--verbose] [--days N] [--quick] Documentation in bitcoin_trading/README.md
176 lines
5.8 KiB
Python
176 lines
5.8 KiB
Python
"""
|
|
Bitcoin Price Data Fetcher
|
|
Ruft aktuelle und historische Bitcoin-Preisdaten von verschiedenen APIs ab
|
|
"""
|
|
|
|
import requests
|
|
from datetime import datetime, timedelta
|
|
import pandas as pd
|
|
from typing import Dict, List, Optional
|
|
import time
|
|
|
|
|
|
class BitcoinDataFetcher:
|
|
"""Fetches Bitcoin price data from various sources"""
|
|
|
|
def __init__(self):
|
|
self.base_url_coingecko = "https://api.coingecko.com/api/v3"
|
|
self.base_url_binance = "https://api.binance.com/api/v3"
|
|
|
|
def get_current_price(self) -> Optional[float]:
|
|
"""
|
|
Holt den aktuellen Bitcoin-Preis in USD
|
|
|
|
Returns:
|
|
float: Aktueller BTC/USD Preis oder None bei Fehler
|
|
"""
|
|
try:
|
|
# Versuche zuerst Binance (schneller und zuverlässiger)
|
|
url = f"{self.base_url_binance}/ticker/price"
|
|
params = {"symbol": "BTCUSDT"}
|
|
response = requests.get(url, params=params, timeout=10)
|
|
|
|
if response.status_code == 200:
|
|
data = response.json()
|
|
return float(data['price'])
|
|
|
|
except Exception as e:
|
|
print(f"Fehler beim Abrufen von Binance: {e}")
|
|
|
|
try:
|
|
# Fallback zu CoinGecko
|
|
url = f"{self.base_url_coingecko}/simple/price"
|
|
params = {
|
|
"ids": "bitcoin",
|
|
"vs_currencies": "usd"
|
|
}
|
|
response = requests.get(url, params=params, timeout=10)
|
|
|
|
if response.status_code == 200:
|
|
data = response.json()
|
|
return float(data['bitcoin']['usd'])
|
|
|
|
except Exception as e:
|
|
print(f"Fehler beim Abrufen von CoinGecko: {e}")
|
|
|
|
return None
|
|
|
|
def get_historical_data(self, days: int = 30) -> pd.DataFrame:
|
|
"""
|
|
Holt historische Bitcoin-Preisdaten
|
|
|
|
Args:
|
|
days: Anzahl der Tage zurück
|
|
|
|
Returns:
|
|
DataFrame mit Spalten: timestamp, price, volume
|
|
"""
|
|
try:
|
|
# Binance Klines (Candlestick-Daten)
|
|
url = f"{self.base_url_binance}/klines"
|
|
|
|
# Berechne Zeitstempel
|
|
end_time = int(datetime.now().timestamp() * 1000)
|
|
start_time = int((datetime.now() - timedelta(days=days)).timestamp() * 1000)
|
|
|
|
params = {
|
|
"symbol": "BTCUSDT",
|
|
"interval": "1h", # Stündliche Daten
|
|
"startTime": start_time,
|
|
"endTime": end_time,
|
|
"limit": 1000
|
|
}
|
|
|
|
response = requests.get(url, params=params, timeout=30)
|
|
|
|
if response.status_code == 200:
|
|
data = response.json()
|
|
|
|
# Konvertiere zu DataFrame
|
|
df = pd.DataFrame(data, columns=[
|
|
'timestamp', 'open', 'high', 'low', 'close',
|
|
'volume', 'close_time', 'quote_volume', 'trades',
|
|
'taker_buy_base', 'taker_buy_quote', 'ignore'
|
|
])
|
|
|
|
# Behalte nur relevante Spalten
|
|
df = df[['timestamp', 'close', 'volume']]
|
|
df.columns = ['timestamp', 'price', 'volume']
|
|
|
|
# Konvertiere Datentypen
|
|
df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')
|
|
df['price'] = df['price'].astype(float)
|
|
df['volume'] = df['volume'].astype(float)
|
|
|
|
return df
|
|
|
|
except Exception as e:
|
|
print(f"Fehler beim Abrufen historischer Daten: {e}")
|
|
|
|
# Fallback: Leeres DataFrame
|
|
return pd.DataFrame(columns=['timestamp', 'price', 'volume'])
|
|
|
|
def get_market_data(self) -> Dict:
|
|
"""
|
|
Holt erweiterte Marktdaten für Bitcoin
|
|
|
|
Returns:
|
|
Dict mit Marktdaten (Volumen, Marktkapitalisierung, etc.)
|
|
"""
|
|
try:
|
|
url = f"{self.base_url_coingecko}/coins/bitcoin"
|
|
params = {
|
|
"localization": "false",
|
|
"tickers": "false",
|
|
"market_data": "true",
|
|
"community_data": "false",
|
|
"developer_data": "false"
|
|
}
|
|
|
|
response = requests.get(url, params=params, timeout=15)
|
|
|
|
if response.status_code == 200:
|
|
data = response.json()
|
|
market_data = data.get('market_data', {})
|
|
|
|
return {
|
|
'current_price': market_data.get('current_price', {}).get('usd'),
|
|
'market_cap': market_data.get('market_cap', {}).get('usd'),
|
|
'total_volume': market_data.get('total_volume', {}).get('usd'),
|
|
'price_change_24h': market_data.get('price_change_percentage_24h'),
|
|
'price_change_7d': market_data.get('price_change_percentage_7d'),
|
|
'price_change_30d': market_data.get('price_change_percentage_30d'),
|
|
'high_24h': market_data.get('high_24h', {}).get('usd'),
|
|
'low_24h': market_data.get('low_24h', {}).get('usd'),
|
|
}
|
|
|
|
except Exception as e:
|
|
print(f"Fehler beim Abrufen von Marktdaten: {e}")
|
|
|
|
return {}
|
|
|
|
|
|
if __name__ == "__main__":
|
|
# Test
|
|
fetcher = BitcoinDataFetcher()
|
|
|
|
print("=== Bitcoin Preis ===")
|
|
price = fetcher.get_current_price()
|
|
if price:
|
|
print(f"Aktueller BTC/USD Preis: ${price:,.2f}")
|
|
|
|
print("\n=== Marktdaten ===")
|
|
market = fetcher.get_market_data()
|
|
for key, value in market.items():
|
|
if value is not None:
|
|
if 'price' in key or 'cap' in key or 'volume' in key or 'high' in key or 'low' in key:
|
|
print(f"{key}: ${value:,.2f}")
|
|
else:
|
|
print(f"{key}: {value:.2f}%")
|
|
|
|
print("\n=== Historische Daten (letzte 7 Tage) ===")
|
|
df = fetcher.get_historical_data(days=7)
|
|
if not df.empty:
|
|
print(f"Anzahl Datenpunkte: {len(df)}")
|
|
print(df.tail())
|