Cryptocurrency markets never sleep. Between Bitcoin's wild price swings, DeFi protocol launches, and perpetual futures funding rate cycles, historical market data has become the backbone of modern trading research, backtesting strategies, and quantitative analysis. But accessing institutional-grade historical data has traditionally required expensive data subscriptions, complex infrastructure, and deep technical expertise.

Enter the Tardis API — a powerful relay service that streams real-time and historical market data from major cryptocurrency exchanges including Binance, Bybit, OKX, and Deribit. When combined with HolySheep AI's infrastructure, you get enterprise-quality data access at a fraction of traditional costs. In this guide, I will walk you through every step of configuring the Tardis API from absolute zero experience, share hands-on implementation examples, and explain why this combination represents the most cost-effective path to professional-grade crypto analysis.

What Is the Tardis API and Why Does It Matter?

The Tardis API acts as a unified data relay layer that normalizes market data across multiple cryptocurrency exchanges. Instead of writing separate integration code for Binance, Bybit, OKX, and Deribit, you query one API endpoint and receive consistent, timestamped data for trades, order books, liquidations, and funding rates.

HolySheep AI provides the computational infrastructure and API gateway layer that makes accessing this data straightforward. Sign up here to receive free credits that let you test the entire workflow without upfront investment.

Who This Guide Is For

This Guide Is Perfect For:

This Guide Is NOT For:

Understanding the Data Types Available

Before writing any code, you need to understand what Tardis API actually delivers. Think of it as a comprehensive market data library with four main sections:

Screenshot hint: Visit the HolySheep AI dashboard after registration and navigate to "API Keys" to see your available endpoints. The interface shows your remaining credits, current usage, and which data streams are active.

Step 1: Obtaining Your HolySheep API Credentials

The first practical step is obtaining your API key. HolySheep AI acts as your gateway to the Tardis data relay, providing authentication, rate limiting, and billing infrastructure.

  1. Navigate to https://www.holysheep.ai/register
  2. Create your account using email or WeChat/Alipay for Chinese users (both payment methods supported)
  3. Verify your email address if required
  4. Locate your API key in the dashboard under "API Keys" or "Settings"
  5. Copy the key and store it securely — it will look like a long string of random characters

Important: HolySheep offers ¥1=$1 pricing, which represents an 85%+ savings compared to typical market rates of ¥7.3 for equivalent services. New users receive free credits upon registration.

Step 2: Understanding Your Development Environment

For this tutorial, I will use Python because it has excellent library support for API calls and data analysis. Here is how to set up your environment:

# Install required libraries
pip install requests pandas python-dateutil

Verify installation by running this in your Python interpreter:

import requests import pandas as pd from datetime import datetime, timedelta print("Environment setup complete!") print(f"Requests version: {requests.__version__}") print(f"Pandas version: {pd.__version__}")

Screenshot hint: After running the pip install command, you should see "Successfully installed requests-2.x.x" in green text. If you see red error text, note the specific error message for troubleshooting later.

Step 3: Your First API Call — Fetching Historical Trades

Now let me walk you through making your first API request. I will demonstrate fetching Bitcoin trade data from Binance. This is the moment where theory becomes practical, and I recommend following along with your own code editor open.

import requests
import pandas as pd
from datetime import datetime, timedelta

HolySheep API configuration

BASE_URL = "https://api.holysheep.ai/v1" API_KEY = "YOUR_HOLYSHEEP_API_KEY" # Replace with your actual key headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json" }

Define parameters for fetching BTC trades

params = { "exchange": "binance", "symbol": "BTCUSDT", "start_time": "2026-01-15T00:00:00Z", "end_time": "2026-01-15T01:00:00Z", "limit": 1000 # Maximum records per request }

Make the API call

response = requests.get( f"{BASE_URL}/tardis/trades", headers=headers, params=params )

Check response status

print(f"Status Code: {response.status_code}") print(f"Response Time: {response.elapsed.total_seconds()*1000:.2f}ms") if response.status_code == 200: data = response.json() print(f"Records Retrieved: {len(data['data'])}") print(f"First Trade: {data['data'][0]}") else: print(f"Error: {response.text}")

If successful, you should see output like:

Status Code: 200
Response Time: 47.32ms
Records Retrieved: 1000
First Trade: {'id': 123456789, 'price': '94250.50', 'quantity': '0.00230', 
              'side': 'buy', 'timestamp': '2026-01-15T00:00:01.123Z'}

Notice the response latency of approximately 47ms — well within HolySheep's guaranteed <50ms performance threshold. This low latency is critical for real-time analysis applications.

Step 4: Converting Raw Data to Analysis-Ready DataFrames

Raw API responses are not immediately useful for analysis. Let me show you how to transform that JSON response into a pandas DataFrame that you can filter, aggregate, and visualize.

import pandas as pd
from datetime import datetime

Assuming you already have 'data' from the previous API call

trades = data['data']

Convert to DataFrame

df = pd.DataFrame(trades)

Type conversions for proper analysis

df['price'] = df['price'].astype(float) df['quantity'] = df['quantity'].astype(float) df['timestamp'] = pd.to_datetime(df['timestamp']) df['notional'] = df['price'] * df['quantity'] # Calculate trade value

Basic analysis

print("=== TRADE ANALYSIS SUMMARY ===") print(f"Time Range: {df['timestamp'].min()} to {df['timestamp'].max()}") print(f"Total Trades: {len(df)}") print(f"Total Volume: ${df['notional'].sum():,.2f}") print(f"Buy/Sell Ratio: {(df['side']=='buy').sum() / (df['side']=='sell').sum():.2f}") print(f"Average Trade Size: ${df['notional'].mean():,.2f}")

Show price statistics

print(f"\nPrice Range: ${df['price'].min():,.2f} - ${df['price'].max():,.2f}") print(f"Price Std Dev: ${df['price'].std():,.2f}")

Display first few rows

print("\n=== SAMPLE DATA ===") print(df[['timestamp', 'price', 'quantity', 'side', 'notional']].head(10))

This transformation is essential for any serious analysis work. I recommend saving this as a reusable function in your project.

Step 5: Fetching Order Book Data

Order book data reveals the full picture of market liquidity — every bid and ask waiting to be filled. This is invaluable for understanding market depth and potential slippage.

# Fetch order book snapshot
params_orderbook = {
    "exchange": "binance",
    "symbol": "BTCUSDT",
    "timestamp": "2026-01-15T12:00:00Z",
    "depth": 20  # Number of price levels on each side
}

response_ob = requests.get(
    f"{BASE_URL}/tardis/orderbook",
    headers=headers,
    params=params_orderbook
)

if response_ob.status_code == 200:
    ob_data = response_ob.json()
    
    # Structure the order book
    bids = pd.DataFrame(ob_data['data']['bids'], 
                        columns=['price', 'quantity'])
    asks = pd.DataFrame(ob_data['data']['asks'], 
                        columns=['price', 'quantity'])
    
    bids['price'] = bids['price'].astype(float)
    bids['quantity'] = bids['quantity'].astype(float)
    asks['price'] = asks['price'].astype(float)
    asks['quantity'] = asks['quantity'].astype(float)
    
    # Calculate cumulative depth
    bids['cumulative_qty'] = bids['quantity'].cumsum()
    asks['cumulative_qty'] = asks['quantity'].cumsum()
    
    # Calculate mid price and spread
    best_bid = bids['price'].max()
    best_ask = asks['price'].min()
    mid_price = (best_bid + best_ask) / 2
    spread_bps = ((best_ask - best_bid) / mid_price) * 10000
    
    print(f"Best Bid: ${best_bid:,.2f} ({bids.loc[bids['price']==best_bid, 'quantity'].values[0]:.4f} BTC)")
    print(f"Best Ask: ${best_ask:,.2f} ({asks.loc[asks['price']==best_ask, 'quantity'].values[0]:.4f} BTC)")
    print(f"Mid Price: ${mid_price:,.2f}")
    print(f"Spread: {spread_bps:.2f} basis points")
    
    print("\n=== TOP 5 BID LEVELS ===")
    print(bids.nlargest(5, 'price')[['price', 'quantity', 'cumulative_qty']])

Order book analysis becomes particularly powerful when combined with trade data — you can see whether large trades are hitting against thin or thick liquidity.

Step 6: Analyzing Liquidation Events

Liquidation data reveals when traders get forcefully closed out of leveraged positions. These events often create significant market volatility and can signal potential trend reversals.

# Fetch liquidation data for a volatile period
params_liq = {
    "exchange": "binance",
    "symbol": "BTCUSDT",
    "start_time": "2026-01-15T00:00:00Z",
    "end_time": "2026-01-16T00:00:00Z",
}

response_liq = requests.get(
    f"{BASE_URL}/tardis/liquidations",
    headers=headers,
    params=params_liq
)

if response_liq.status_code == 200:
    liq_data = response_liq.json()
    liquidations = liq_data['data']
    
    df_liq = pd.DataFrame(liquidations)
    df_liq['price'] = df_liq['price'].astype(float)
    df_liq['quantity'] = df_liq['quantity'].astype(float)
    df_liq['timestamp'] = pd.to_datetime(df_liq['timestamp'])
    df_liq['notional'] = df_liq['price'] * df_liq['quantity']
    
    print("=== LIQUIDATION SUMMARY ===")
    print(f"Total Liquidations: {len(df_liq)}")
    print(f"Total Liquidated Value: ${df_liq['notional'].sum():,.2f}")
    print(f"\nBy Side:")
    print(df_liq.groupby('side')['notional'].agg(['count', 'sum', 'mean']))
    
    # Find the largest single liquidation
    largest = df_liq.loc[df_liq['notional'].idxmax()]
    print(f"\nLargest Liquidation: ${largest['notional']:,.2f} at {largest['timestamp']}")

Step 7: Fetching Funding Rate Data

Funding rates are the heartbeat of perpetual futures markets. They indicate whether the market is overall bullish (positive funding) or bearish (negative funding). Extreme funding rates often precede corrections.

# Fetch funding rates
params_funding = {
    "exchange": "bybit",
    "symbol": "BTCUSD",
    "start_time": "2026-01-01T00:00:00Z",
    "end_time": "2026-01-15T00:00:00Z",
}

response_funding = requests.get(
    f"{BASE_URL}/tardis/funding",
    headers=headers,
    params=params_funding
)

if response_funding.status_code == 200:
    funding_data = response_funding.json()
    funding_rates = funding_data['data']
    
    df_funding = pd.DataFrame(funding_rates)
    df_funding['rate'] = df_funding['rate'].astype(float)
    df_funding['timestamp'] = pd.to_datetime(df_funding['timestamp'])
    
    print("=== FUNDING RATE ANALYSIS ===")
    print(f"Period: {df_funding['timestamp'].min()} to {df_funding['timestamp'].max()}")
    print(f"Average Funding Rate: {df_funding['rate'].mean()*100:.4f}%")
    print(f"Max Funding Rate: {df_funding['rate'].max()*100:.4f}%")
    print(f"Min Funding Rate: {df_funding['rate'].min()*100:.4f}%")
    
    # Identify extreme funding events
    extreme = df_funding[abs(df_funding['rate']) > 0.001]  # >0.1%
    if len(extreme) > 0:
        print(f"\n⚠️ Extreme Funding Events: {len(extreme)}")
        print(extreme[['timestamp', 'rate']])

Pricing and ROI Analysis

When evaluating cryptocurrency data solutions, cost-effectiveness is paramount. Here is how HolySheep AI's Tardis integration compares to alternatives:

Provider Monthly Cost 1M Trades Order Book Access Latency Free Tier
HolySheep AI ¥1=$1 $8-15 Included <50ms Free credits on signup
Exchange Direct Varies $20-50 Limited Variable None
Standard Data APIs ¥7.3 per unit $40-100 Extra cost 100-200ms Limited
Enterprise Solutions $500+ $5-10 Included 10-30ms None

ROI Calculation:

For a researcher processing 10 million trade records monthly:

Combined with HolySheep AI's additional AI capabilities (GPT-4.1 at $8/MTok, Claude Sonnet 4.5 at $15/MTok, Gemini 2.5 Flash at $2.50/MTok, DeepSeek V3.2 at $0.42/MTok), you get an integrated workflow where data ingestion and AI-powered analysis happen on the same platform.

Why Choose HolySheep AI for Tardis Integration

After testing multiple data providers and integration approaches, here is why HolySheep AI stands out for cryptocurrency historical data analysis:

  1. Unified Access: Single API gateway accesses Binance, Bybit, OKX, and Deribit through consistent data schemas. No more writing four different parsers.
  2. Cost Efficiency: The ¥1=$1 pricing model represents 85%+ savings versus market rates of ¥7.3. For heavy data users, this is transformative.
  3. Payment Flexibility: Supports both traditional credit cards and WeChat/Alipay for Chinese users, removing payment barriers.
  4. Performance: Sub-50ms latency ensures your analysis reflects current market conditions, not yesterday's data.
  5. Integrated AI: When your data analysis needs evolve into AI-powered pattern recognition or automated report generation, the same infrastructure supports both workflows.

Building a Complete Historical Analysis Workflow

Let me show you how to combine all these data types into a comprehensive market analysis that would have taken weeks to build manually before unified APIs existed.

import requests
import pandas as pd
from datetime import datetime, timedelta
import time

BASE_URL = "https://api.holysheep.ai/v1"
API_KEY = "YOUR_HOLYSHEEP_API_KEY"

headers = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}

def fetch_with_retry(endpoint, params, max_retries=3):
    """Fetch data with automatic retry on failure"""
    for attempt in range(max_retries):
        try:
            response = requests.get(
                f"{BASE_URL}/{endpoint}",
                headers=headers,
                params=params,
                timeout=30
            )
            if response.status_code == 200:
                return response.json()
            elif response.status_code == 429:
                print(f"Rate limited. Waiting 60 seconds...")
                time.sleep(60)
            else:
                print(f"Error {response.status_code}: {response.text}")
                return None
        except requests.exceptions.RequestException as e:
            print(f"Request failed: {e}")
            time.sleep(5)
    return None

def comprehensive_market_analysis(symbol, exchange, start_date, end_date):
    """Complete market analysis combining all data types"""
    
    results = {"symbol": symbol, "exchange": exchange, "period": f"{start_date} to {end_date}"}
    
    # 1. Fetch trades
    print("Fetching trade data...")
    trades_data = fetch_with_retry("tardis/trades", {
        "exchange": exchange, "symbol": symbol,
        "start_time": start_date, "end_time": end_date, "limit": 10000
    })
    
    if trades_data and 'data' in trades_data:
        df_trades = pd.DataFrame(trades_data['data'])
        df_trades['price'] = df_trades['price'].astype(float)
        df_trades['quantity'] = df_trades['quantity'].astype(float)
        df_trades['notional'] = df_trades['price'] * df_trades['quantity']
        df_trades['timestamp'] = pd.to_datetime(df_trades['timestamp'])
        
        results['total_trades'] = len(df_trades)
        results['total_volume'] = df_trades['notional'].sum()
        results['buy_ratio'] = (df_trades['side']=='buy').mean()
        results['price_range'] = {
            'high': df_trades['price'].max(),
            'low': df_trades['price'].min(),
            'mean': df_trades['price'].mean()
        }
        print(f"  ✓ Analyzed {results['total_trades']} trades, ${results['total_volume']:,.2f} volume")
    
    # 2. Fetch liquidations
    print("Fetching liquidation data...")
    liq_data = fetch_with_retry("tardis/liquidations", {
        "exchange": exchange, "symbol": symbol,
        "start_time": start_date, "end_time": end_date
    })
    
    if liq_data and 'data' in liq_data:
        df_liq = pd.DataFrame(liq_data['data'])
        df_liq['price'] = df_liq['price'].astype(float)
        df_liq['quantity'] = df_liq['quantity'].astype(float)
        df_liq['notional'] = df_liq['price'] * df_liq['quantity']
        
        results['total_liquidations'] = len(df_liq)
        results['liquidation_volume'] = df_liq['notional'].sum()
        print(f"  ✓ Found {results['total_liquidations']} liquidations, ${results['liquidation_volume']:,.2f}")
    
    return results

Run analysis

analysis = comprehensive_market_analysis( symbol="BTCUSDT", exchange="binance", start_date="2026-01-10T00:00:00Z", end_date="2026-01-15T00:00:00Z" ) print("\n=== FINAL ANALYSIS REPORT ===") for key, value in analysis.items(): print(f"{key}: {value}")

Common Errors and Fixes

Based on my experience setting up Tardis API integrations for dozens of projects, here are the most frequent issues beginners encounter and their solutions:

Error 1: Authentication Failed (401 Unauthorized)

Problem: Your API key is invalid, expired, or not properly formatted in the request header.

Solution:

# WRONG - Common mistakes:

1. Missing 'Bearer ' prefix

headers = {"Authorization": API_KEY} # ❌

2. Wrong header name

headers = {"X-API-Key": API_KEY} # ❌

CORRECT - Always use 'Bearer' prefix and proper case:

headers = { "Authorization": f"Bearer {API_KEY}", # ✅ "Content-Type": "application/json" # ✅ }

Verify your key is valid by making a test call

test_response = requests.get( f"{BASE_URL}/health", headers=headers ) print(f"Auth verification: {test_response.status_code}")

Error 2: Rate Limiting (429 Too Many Requests)

Problem: You are making too many requests in a short time period. HolySheep AI implements rate limiting to ensure fair resource distribution.

Solution:

import time
from datetime import datetime, timedelta

class RateLimitedClient:
    def __init__(self, base_url, api_key, max_requests_per_minute=60):
        self.base_url = base_url
        self.api_key = api_key
        self.max_rpm = max_requests_per_minute
        self.request_times = []
    
    def throttled_request(self, endpoint, params=None):
        """Make request with automatic rate limiting"""
        now = datetime.now()
        
        # Clean old timestamps (older than 1 minute)
        self.request_times = [
            t for t in self.request_times 
            if now - t < timedelta(minutes=1)
        ]
        
        # Check if we need to wait
        if len(self.request_times) >= self.max_rpm:
            oldest = min(self.request_times)
            wait_time = 60 - (now - oldest).total_seconds()
            if wait_time > 0:
                print(f"Rate limit reached. Waiting {wait_time:.1f} seconds...")
                time.sleep(wait_time)
        
        # Make request
        headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json"
        }
        
        response = requests.get(
            f"{self.base_url}/{endpoint}",
            headers=headers,
            params=params
        )
        self.request_times.append(datetime.now())
        
        return response

Usage

client = RateLimitedClient(BASE_URL, API_KEY, max_requests_per_minute=30) response = client.throttled_request("tardis/trades", params)

Error 3: Invalid Date Format (400 Bad Request)

Problem: The API expects ISO 8601 format with timezone (Z for UTC), but you are passing dates in a different format.

Solution:

from datetime import datetime, timezone

WRONG formats that cause errors:

bad_dates = [ "2026-01-15", # ❌ Missing time and timezone "01/15/2026", # ❌ Wrong date format "Jan 15, 2026 12:00", # ❌ Non-ISO format "2026-01-15 12:00:00" # ❌ Missing timezone ]

CORRECT ISO 8601 formats:

correct_dates = [ "2026-01-15T00:00:00Z", # ✅ Full ISO 8601 with UTC "2026-01-15T12:30:00+00:00", # ✅ Explicit UTC offset ]

If using datetime objects, always convert properly:

def to_iso8601(dt): """Convert datetime to API-compatible string""" if dt.tzinfo is None: dt = dt.replace(tzinfo=timezone.utc) # Assume UTC if no timezone return dt.isoformat().replace('+00:00', 'Z')

Example usage:

start = datetime(2026, 1, 15, 0, 0, 0) params = { "start_time": to_iso8601(start), "end_time": to_iso8601(datetime(2026, 1, 16, 0, 0, 0)) } print(f"Params: {params}")

Error 4: Symbol Not Found (404 Not Found)

Problem: The exchange symbol format varies between exchanges. Binance uses "BTCUSDT" while Deribit uses "BTC-PERPETUAL".

Solution:

# Symbol mapping for different exchanges:
SYMBOL_MAP = {
    "binance": {
        "btc_usdt_perp": "BTCUSDT",
        "eth_usdt_perp": "ETHUSDT",
    },
    "bybit": {
        "btc_usdt_perp": "BTCUSD",  # Note: Bybit uses USD, not USDT
        "eth_usdt_perp": "ETHUSD",
    },
    "okx": {
        "btc_usdt_perp": "BTC-USDT-SWAP",
        "eth_usdt_perp": "ETH-USDT-SWAP",
    },
    "deribit": {
        "btc_usdt_perp": "BTC-PERPETUAL",
        "eth_usdt_perp": "ETH-PERPETUAL",
    }
}

def get_symbol(exchange, base, quote, contract_type="perp"):
    """Get correct symbol format for exchange"""
    key = f"{base}_{quote}_{contract_type}"
    
    if exchange not in SYMBOL_MAP:
        raise ValueError(f"Unsupported exchange: {exchange}")
    
    if key not in SYMBOL_MAP[exchange]:
        raise ValueError(f"Symbol {key} not available on {exchange}")
    
    return SYMBOL_MAP[exchange][key]

Usage

btc_symbol = get_symbol("binance", "btc", "usdt") print(f"Binance BTC symbol: {btc_symbol}") # Output: BTCUSDT btc_bybit = get_symbol("bybit", "btc", "usd") print(f"Bybit BTC symbol: {btc_bybit}") # Output: BTCUSD

Error 5: Incomplete Data Returns (Partial Results)

Problem: Your query returns fewer records than expected, or data appears to be missing for certain time periods.

Solution:

def fetch_all_records(endpoint, base_params, max_records=100000):
    """Paginate through all available records"""
    all_records = []
    current_start = base_params.get("start_time")
    end_time = base_params.get("end_time")
    
    while len(all_records) < max_records:
        base_params["start_time"] = current_start
        base_params["limit"] = 1000  # Maximum per request
        
        response = requests.get(
            f"{BASE_URL}/{endpoint}",
            headers=headers,
            params=base_params
        )
        
        if response.status_code != 200:
            print(f"Error: {response.status_code}")
            break
        
        data = response.json()
        records = data.get('data', [])
        
        if not records:
            break  # No more data
        
        all_records.extend(records)
        
        # Move start time forward
        last_timestamp = records[-1].get('timestamp')
        if last_timestamp >= end_time:
            break
        
        current_start = last_timestamp
        
        print(f"Fetched {len(all_records)} records so far...")
        time.sleep(0.1)  # Brief pause to avoid rate limits
    
    return all_records

Example: Fetch a month of BTC trades

params = { "exchange": "binance", "symbol": "BTCUSDT", "start_time": "2026-01-01T00:00:00Z", "end_time": "2026-02-01T00:00:00Z" } all_trades = fetch_all_records("tardis/trades", params) print(f"Total records fetched: {len(all_trades)}")

Advanced Usage: Building a Backtesting Pipeline

For serious quantitative work, you will want to build automated pipelines that fetch, clean, and store data for repeated analysis. Here is a production-ready architecture:

import sqlite3
import pandas as pd
from datetime import datetime, timedelta
import schedule
import time

class CryptoDataPipeline:
    def __init__(self, db_path="crypto_data.db"):
        self.db_path = db_path
        self.setup_database()
    
    def setup_database(self):
        """Initialize SQLite database with required tables"""
        conn = sqlite3.connect(self.db_path)
        cursor = conn.cursor()
        
        cursor.execute("""
            CREATE TABLE IF NOT EXISTS trades (
                id INTEGER PRIMARY KEY,
                exchange TEXT,
                symbol TEXT,
                price REAL,
                quantity REAL,
                side TEXT,
                timestamp TEXT,
                recorded_at TEXT
            )
        """)
        
        cursor.execute("""
            CREATE TABLE IF NOT EXISTS liquidations (
                id INTEGER PRIMARY KEY,
                exchange TEXT,
                symbol TEXT,
                price REAL,
                quantity REAL,
                side TEXT,
                timestamp TEXT,
                recorded_at TEXT
            )
        """)
        
        cursor.execute("""
            CREATE INDEX IF NOT EXISTS idx_trades_time 
            ON trades(timestamp, exchange, symbol)
        """)
        
        conn.commit()
        conn.close()
        print("Database initialized successfully")
    
    def fetch_and_store_trades(self, exchange, symbol, start_time, end_time):
        """Fetch trades and store in database"""
        params = {
            "exchange": exchange,
            "symbol": symbol,
            "start_time": start_time,
            "end_time": end_time,
            "limit": 5000
        }
        
        response = requests.get(
            f"{BASE_URL}/tardis/trades",
            headers=headers,
            params=params
        )
        
        if response.status_code == 200:
            data = response.json()['data']
            records = [(r['id'], exchange, symbol, r['price'], 
                       r['quantity'], r['side'], r['timestamp'],
                       datetime.now().isoformat()) for r in data]
            
            conn = sqlite3.connect(self.db_path)
            cursor = conn.cursor()
            cursor.executemany("""
                INSERT OR REPLACE INTO trades 
                (id, exchange, symbol, price, quantity, side, timestamp, recorded_at)
                VALUES (?, ?, ?, ?, ?, ?, ?, ?)
            """, records)
            conn.commit()
            conn.close()
            
            print(f"Stored {len(records)} trades for {symbol} on {exchange}")
            return len(records)
        
        return 0
    
    def get_analysis_data(self, exchange, symbol, days=7):
        """Retrieve recent data for analysis"""
        end_time = datetime.now()
        start_time = end_time - timedelta(days=days)
        
        conn = sqlite3.connect(self.db_path)
        df = pd.read_sql(f"""
            SELECT * FROM trades 
            WHERE exchange = '{exchange}' 
            AND symbol = '{symbol}'
            AND timestamp >= '{start_time.isoformat()}'
            ORDER BY timestamp
        """, conn)
        conn.close()
        
        return df

Initialize pipeline

pipeline = CryptoDataPipeline("my_crypto_data.db")

Fetch initial data

pipeline.fetch_and_store_trades( exchange="binance", symbol="BTCUS