Bitcoin Price Tracking Bot
Build a comprehensive Bitcoin price monitoring system that tracks prices, analyzes market sentiment, sends alerts, and provides predictive insights using SearchHive APIs.
What You'll Build
Real-time Tracking
Monitor Bitcoin prices from multiple sources with automatic updates
Sentiment Analysis
Analyze market sentiment from news articles and social media
Smart Alerts
Price threshold alerts and sentiment change notifications
Historical Data
Store and analyze price history with trend analysis
Prerequisites
1. Setup & Installation
Install Dependencies
Project setup
Environment Configuration
.env file configuration
# .env
SEARCHHIVE_API_KEY=sk_live_your_key_here
# Monitoring Settings
CHECK_INTERVAL_MINUTES=30
PRICE_THRESHOLD_HIGH=150000
PRICE_THRESHOLD_LOW=80000
# Email Alerts (optional)
EMAIL_ALERTS=true
EMAIL_FROM=your_email@gmail.com
EMAIL_TO=alerts@yourcompany.com
EMAIL_PASSWORD=your_app_password
SMTP_SERVER=smtp.gmail.com
SMTP_PORT=587
2. Configuration Module
Create a configuration module to manage all settings, thresholds, and data sources.
config.py - Centralized configuration
# config.py
import os
from dotenv import load_dotenv
load_dotenv()
class Config:
# API Keys
SEARCHHIVE_API_KEY = os.getenv('SEARCHHIVE_API_KEY')
# Monitoring settings
CHECK_INTERVAL_MINUTES = int(os.getenv('CHECK_INTERVAL_MINUTES', 30))
PRICE_THRESHOLD_HIGH = float(os.getenv('PRICE_THRESHOLD_HIGH', 150000))
PRICE_THRESHOLD_LOW = float(os.getenv('PRICE_THRESHOLD_LOW', 80000))
# Data sources to monitor
SOURCES = [
'coinmarketcap.com/currencies/bitcoin',
'coingecko.com/en/coins/bitcoin',
'bloomberg.com/quote/XBTUSD:CUR',
'cnn.com/business/bitcoin',
'reuters.com/technology/bitcoin'
]
# Alert settings
EMAIL_ALERTS = os.getenv('EMAIL_ALERTS', 'False').lower() == 'true'
EMAIL_FROM = os.getenv('EMAIL_FROM')
EMAIL_TO = os.getenv('EMAIL_TO')
SMTP_SERVER = os.getenv('SMTP_SERVER', 'smtp.gmail.com')
SMTP_PORT = int(os.getenv('SMTP_PORT', 587))
EMAIL_PASSWORD = os.getenv('EMAIL_PASSWORD')
# Storage
DATA_FILE = 'bitcoin_data.csv'
LOG_FILE = 'bitcoin_tracker.log'
3. Bitcoin Tracker Implementation
The core tracker class that handles data collection, analysis, and alerting using SearchHive APIs.
bitcoin_tracker.py - Main implementation
# bitcoin_tracker.py
import requests
import pandas as pd
import json
import re
import schedule
import time
import smtplib
from email.mime.text import MimeText
from email.mime.multipart import MimeMultipart
from datetime import datetime
import logging
from config import Config
class BitcoinTracker:
def __init__(self):
self.api_key = Config.SEARCHHIVE_API_KEY
self.setup_logging()
self.data_history = self.load_existing_data()
def setup_logging(self):
"""Set up logging configuration."""
logging.basicConfig(
filename=Config.LOG_FILE,
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
self.logger = logging.getLogger(__name__)
def load_existing_data(self):
"""Load existing price data from CSV file."""
try:
return pd.read_csv(Config.DATA_FILE)
except FileNotFoundError:
# Create new DataFrame with required columns
return pd.DataFrame(columns=[
'timestamp', 'current_price', 'market_cap',
'volume_24h', 'price_change_24h', 'sentiment_score',
'news_count', 'prediction_avg', 'source'
])
def search_bitcoin_info(self, query="Bitcoin price current market analysis"):
"""Search for Bitcoin information using SwiftSearch."""
try:
response = requests.post(
"https://www.searchhive.dev/api/v1/swiftsearch",
headers={
"Authorization": "Bearer " + self.api_key,
"Content-Type": "application/json"
},
json={
"query": query,
"max_results": 10,
"auto_scrape_top": 5
}
)
response.raise_for_status()
return response.json()
except Exception as e:
self.logger.error(f"Search failed: {e}")
return None
def scrape_specific_source(self, url):
"""Scrape a specific Bitcoin data source."""
try:
response = requests.post(
"https://www.searchhive.dev/api/v1/scrapeforge",
headers={
"Authorization": "Bearer " + self.api_key,
"Content-Type": "application/json"
},
json={
"url": url,
"extract_options": ["title", "text", "metadata"]
}
)
response.raise_for_status()
return response.json()
except Exception as e:
self.logger.error(f"Scraping {url} failed: {e}")
return None
def extract_price_from_text(self, text):
"""Extract Bitcoin price from scraped text using regex."""
# Common price patterns
patterns = [
r'\$([0-9]{1,3}(?:,[0-9]{3})*(?:\.[0-9]{2})?)', # $123,456.78
r'([0-9]{1,3}(?:,[0-9]{3})*(?:\.[0-9]{2})?)\s*USD', # 123,456.78 USD
r'BTC[:s]*\$?([0-9]{1,3}(?:,[0-9]{3})*(?:\.[0-9]{2})?)', # BTC: $123,456
]
for pattern in patterns:
matches = re.findall(pattern, text, re.IGNORECASE)
if matches:
# Clean and convert to float
price_str = matches[0].replace(',', '')
try:
price = float(price_str)
# Sanity check: Bitcoin price should be reasonable
if 1000 <= price <= 1000000:
return price
except ValueError:
continue
return None
def analyze_sentiment(self, scraped_content):
"""Analyze market sentiment from scraped content."""
positive_words = [
'bullish', 'surge', 'rally', 'growth', 'increase', 'rise',
'optimistic', 'breakthrough', 'adoption', 'institutional'
]
negative_words = [
'bearish', 'crash', 'decline', 'drop', 'fall', 'pessimistic',
'regulation', 'ban', 'risk', 'volatility', 'correction'
]
sentiment_score = 0
word_count = 0
for content in scraped_content:
if content.get('text'):
text = content['text'].lower()
words = text.split()
word_count += len(words)
for word in positive_words:
sentiment_score += text.count(word) * 1
for word in negative_words:
sentiment_score -= text.count(word) * 1
# Normalize sentiment score
if word_count > 0:
return sentiment_score / (word_count / 1000) # Per 1000 words
return 0
def extract_predictions(self, scraped_content):
"""Extract price predictions from scraped content."""
predictions = []
for content in scraped_content:
if content.get('text'):
text = content['text']
# Look for price predictions
prediction_patterns = [
r'predict[s]?.*?\$([0-9]{1,3}(?:,[0-9]{3})*)',
r'target.*?\$([0-9]{1,3}(?:,[0-9]{3})*)',
r'forecast[s]?.*?\$([0-9]{1,3}(?:,[0-9]{3})*)',
r'2025.*?\$([0-9]{1,3}(?:,[0-9]{3})*)',
]
for pattern in prediction_patterns:
matches = re.findall(pattern, text, re.IGNORECASE)
for match in matches:
try:
price = float(match.replace(',', ''))
if 50000 <= price <= 1000000: # Reasonable prediction range
predictions.append(price)
except ValueError:
continue
return predictions
def collect_data(self):
"""Main data collection function."""
self.logger.info("Starting Bitcoin data collection...")
# Search for current Bitcoin information
search_data = self.search_bitcoin_info()
if not search_data:
self.logger.error("Failed to get search data")
return None
current_price = None
all_scraped_content = search_data.get('scraped_content', [])
# Try to extract price from search results
for content in all_scraped_content:
if content.get('text'):
price = self.extract_price_from_text(content['text'])
if price:
current_price = price
break
# If no price found in search, try specific sources
if not current_price:
for source_url in Config.SOURCES[:2]: # Check first 2 sources
scraped_data = self.scrape_specific_source(f"https://{source_url}")
if scraped_data and scraped_data.get('primary_content', {}).get('text'):
text = scraped_data['primary_content']['text']
price = self.extract_price_from_text(text)
if price:
current_price = price
all_scraped_content.append(scraped_data['primary_content'])
break
if not current_price:
self.logger.warning("Could not extract Bitcoin price")
return None
# Analyze data
sentiment_score = self.analyze_sentiment(all_scraped_content)
predictions = self.extract_predictions(all_scraped_content)
prediction_avg = sum(predictions) / len(predictions) if predictions else None
# Create data record
data_record = {
'timestamp': datetime.now().isoformat(),
'current_price': current_price,
'sentiment_score': sentiment_score,
'news_count': len(search_data.get('search_results', [])),
'prediction_avg': prediction_avg,
'source': 'searchhive_analysis',
'scraped_sources': len(all_scraped_content)
}
self.logger.info(f"Collected data: BTC ${current_price:,.2f}, Sentiment: {sentiment_score:.2f}")
# Save to history
new_row = pd.DataFrame([data_record])
self.data_history = pd.concat([self.data_history, new_row], ignore_index=True)
self.data_history.to_csv(Config.DATA_FILE, index=False)
# Check for alerts
self.check_alerts(current_price, data_record)
return data_record
def check_alerts(self, current_price, data_record):
"""Check if price alerts should be triggered."""
alert_triggered = False
alert_message = ""
if current_price >= Config.PRICE_THRESHOLD_HIGH:
alert_triggered = True
alert_message = f"🚀 Bitcoin BULL ALERT: ${current_price:,.2f} (Above ${Config.PRICE_THRESHOLD_HIGH:,.2f})"
elif current_price <= Config.PRICE_THRESHOLD_LOW:
alert_triggered = True
alert_message = f"📉 Bitcoin BEAR ALERT: ${current_price:,.2f} (Below ${Config.PRICE_THRESHOLD_LOW:,.2f})"
# Check for significant sentiment changes
if len(self.data_history) > 1:
prev_sentiment = self.data_history.iloc[-2]['sentiment_score']
current_sentiment = data_record['sentiment_score']
sentiment_change = abs(current_sentiment - prev_sentiment)
if sentiment_change > 5: # Significant sentiment shift
alert_triggered = True
trend = "POSITIVE" if current_sentiment > prev_sentiment else "NEGATIVE"
alert_message += f"\n\n📊 SENTIMENT ALERT: {trend} shift detected (Change: {sentiment_change:.1f})"
if alert_triggered:
self.logger.info(f"Alert triggered: {alert_message}")
if Config.EMAIL_ALERTS:
self.send_email_alert(alert_message, data_record)
print(f"\n{alert_message}\n")
def send_email_alert(self, message, data_record):
"""Send email alert."""
try:
msg = MimeMultipart()
msg['From'] = Config.EMAIL_FROM
msg['To'] = Config.EMAIL_TO
msg['Subject'] = f"Bitcoin Alert - ${data_record['current_price']:,.2f}"
body = f"""
Bitcoin Tracker Alert
{message}
Current Data:
- Price: ${data_record['current_price']:,.2f}
- Sentiment Score: {data_record['sentiment_score']:.2f}
- News Articles: {data_record['news_count']}
- Avg Prediction: ${data_record.get('prediction_avg', 'N/A')}
- Timestamp: {data_record['timestamp']}
Visit your dashboard for more details.
"""
msg.attach(MimeText(body, 'plain'))
server = smtplib.SMTP(Config.SMTP_SERVER, Config.SMTP_PORT)
server.starttls()
server.login(Config.EMAIL_FROM, Config.EMAIL_PASSWORD)
server.sendmail(Config.EMAIL_FROM, Config.EMAIL_TO, msg.as_string())
server.quit()
self.logger.info("Email alert sent successfully")
except Exception as e:
self.logger.error(f"Failed to send email alert: {e}")
def get_summary_report(self):
"""Generate a summary report of recent data."""
if len(self.data_history) == 0:
return "No data available yet."
recent_data = self.data_history.tail(24) # Last 24 records
current_price = recent_data.iloc[-1]['current_price']
avg_price = recent_data['current_price'].mean()
price_change = current_price - recent_data.iloc[0]['current_price']
price_change_pct = (price_change / recent_data.iloc[0]['current_price']) * 100
avg_sentiment = recent_data['sentiment_score'].mean()
report = f"""
Bitcoin Tracker Summary Report
================================
Current Status:
- Latest Price: ${current_price:,.2f}
- 24-Record Average: ${avg_price:,.2f}
- Change: ${price_change:,.2f} ({price_change_pct:+.2f}%)
- Average Sentiment: {avg_sentiment:.2f}
Data Points: {len(self.data_history)}
Last Updated: {recent_data.iloc[-1]['timestamp']}
Thresholds:
- High Alert: ${Config.PRICE_THRESHOLD_HIGH:,.2f}
- Low Alert: ${Config.PRICE_THRESHOLD_LOW:,.2f}
"""
return report
def start_monitoring(self):
"""Start the monitoring process."""
print("🚀 Starting Bitcoin Price Tracker...")
print(f"⏰ Checking every {Config.CHECK_INTERVAL_MINUTES} minutes")
print(f"📊 Alert thresholds: ${Config.PRICE_THRESHOLD_LOW:,} - ${Config.PRICE_THRESHOLD_HIGH:,}")
# Schedule data collection
schedule.every(Config.CHECK_INTERVAL_MINUTES).minutes.do(self.collect_data)
# Run initial collection
self.collect_data()
# Keep running
try:
while True:
schedule.run_pending()
time.sleep(60) # Check every minute for scheduled jobs
except KeyboardInterrupt:
print("\n👋 Bitcoin tracker stopped.")
self.logger.info("Bitcoin tracker stopped by user")
Key features of this implementation
• Falls back to ScrapeForge for specific sources if needed
• Extracts prices using regex patterns
• Analyzes sentiment from scraped content
• Sends email alerts for threshold breaches
• Stores historical data in CSV format
4. Main Script
Create a main script with command-line options for different modes of operation.
main.py - Command-line interface
# main.py
from bitcoin_tracker import BitcoinTracker
import argparse
def main():
parser = argparse.ArgumentParser(description='Bitcoin Price Tracker')
parser.add_argument('--collect', action='store_true', help='Run one-time data collection')
parser.add_argument('--report', action='store_true', help='Show summary report')
parser.add_argument('--monitor', action='store_true', help='Start continuous monitoring')
args = parser.parse_args()
tracker = BitcoinTracker()
if args.collect:
print("Collecting Bitcoin data...")
data = tracker.collect_data()
if data:
print(f"✅ Data collected: BTC ${data['current_price']:,.2f}")
else:
print("❌ Data collection failed")
elif args.report:
print(tracker.get_summary_report())
elif args.monitor:
tracker.start_monitoring()
else:
print("Bitcoin Price Tracker")
print("Usage:")
print(" python main.py --collect # One-time data collection")
print(" python main.py --report # Show summary report")
print(" python main.py --monitor # Start continuous monitoring")
if __name__ == "__main__":
main()
5. Usage & Testing
How to run the Bitcoin tracker
# Run one-time data collection
python main.py --collect
# Show current summary report
python main.py --report
# Start continuous monitoring (runs until stopped)
python main.py --monitor
Run a one-time data collection to test everything is working:
python main.py --collect
Start continuous monitoring (runs until stopped):
python main.py --monitor
Expected Output
Sample output when running
🚀 Starting Bitcoin Price Tracker...
⏰ Checking every 30 minutes
📊 Alert thresholds: $80,000 - $150,000
INFO - Collected data: BTC $118,450.23, Sentiment: 2.3
INFO - Collected data: BTC $119,123.45, Sentiment: 1.8
INFO - Collected data: BTC $120,890.12, Sentiment: 3.1
📊 SENTIMENT ALERT: POSITIVE shift detected (Change: 1.3)
✅ Data collected: BTC $120,890.12
📧 Email alert sent successfully
Bitcoin Tracker Summary Report
================================
Current Status:
- Latest Price: $120,890.12
- 24-Record Average: $119,456.78
- Change: +$2,890.12 (+2.45%)
- Average Sentiment: 2.4
Data Points: 48
Last Updated: 2025-07-22T15:30:42.123456
Enhancement Ideas
Technical Analysis
Add moving averages, RSI, and other indicators
Social Media Monitoring
Track Twitter sentiment and Reddit discussions
Machine Learning Predictions
Train models on historical data for price forecasting
Webhook Notifications
Send alerts to Slack, Discord, or custom endpoints
Database Storage
Replace CSV with PostgreSQL or MongoDB
Web Dashboard
Build a Flask/FastAPI dashboard with charts
Troubleshooting
Price extraction fails
Check the regex patterns in extract_price_from_text()
. Websites may change their format. Add debugging prints to see the scraped text.
High credit usage
Reduce auto_scrape_top
value or increase CHECK_INTERVAL_MINUTES
. Each scraped page costs 3 credits.
Email alerts not working
Check your email credentials and make sure you're using an app password for Gmail. Enable 2FA and generate an app-specific password.