Featured Guide
~2 hours

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
Basic Python knowledge, SearchHive API key, and about 2 hours. We'll use SwiftSearch for data collection, ScrapeForge for specific sources, and DeepDive for market research.

1. Setup & Installation

Install Dependencies

Project setup

Environment Configuration

.env file configuration

cURL
# .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

Python
# 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

Python
# 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
• Uses SwiftSearch for general Bitcoin news and price data
• 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

Python
# 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
Quick Test

Run a one-time data collection to test everything is working:

python main.py --collect
Continuous Monitoring

Start continuous monitoring (runs until stopped):

python main.py --monitor

Expected Output

Sample output when running

cURL
🚀 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

Advanced Features

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

Integration Options

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.

Deploy to Production

Learn how to deploy this bot to AWS, Google Cloud, or a VPS for 24/7 monitoring.

More Use Cases

Explore other real-world applications like e-commerce monitoring and lead generation.