Last updated: May 2026 | Difficulty: Beginner to Intermediate | Reading time: 15 minutes
What This Tutorial Covers
When you build trading algorithms or backtest strategies using historical cryptocurrency market data, you rely on datasets from exchanges like Binance, Bybit, OKX, and Deribit. But here's what most beginners don't know: exchanges regularly correct historical data—and those corrections can silently invalidate your backtesting results.
In this guide, you'll learn how to use Tardis.dev (a professional crypto market data relay service) combined with HolySheep AI (which offers AI-powered data processing at ¥1=$1 with less than 50ms latency and supports WeChat/Alipay) to implement proper dataset version governance. By the end, you'll be able to track exchange corrections, identify data gaps, and understand exactly how these changes impact your backtesting outcomes.
💡 HolySheep AI Quick Facts (2026 Pricing):
• Rate: ¥1=$1 (saves 85%+ vs traditional ¥7.3 pricing)
• Latency: <50ms
• Payment: WeChat, Alipay, credit card
• Output models: GPT-4.1 ($8/Mtok), Claude Sonnet 4.5 ($15/Mtok), Gemini 2.5 Flash ($2.50/Mtok), DeepSeek V3.2 ($0.42/Mtok)
• Sign up here for free credits on registration
Who This Tutorial Is For
| ✅ Perfect For | ❌ Not Ideal For |
|---|---|
| Quantitative traders building backtesting systems | People looking for real-time trading signals only |
| Developers working with crypto exchange APIs | Those with no programming experience whatsoever |
| Data engineers managing historical market datasets | Teams without budget for data infrastructure |
| Algorithmic trading researchers validating results | Casual investors who don't backtest strategies |
| Compliance teams auditing trading decisions | Users who only need spot price data |
Why Dataset Version Governance Matters
The Hidden Problem: Silent Data Corrections
Imagine you've spent three months developing a mean-reversion strategy on Binance futures data. Your backtest shows a Sharpe ratio of 2.3 with 40% annual returns. You go live—and lose money. What went wrong?
Chances are, the exchange corrected historical data after you downloaded it. Common corrections include:
- Trade corrections: A fat-finger trade gets canceled, changing historical volume
- Funding rate adjustments: Historical funding calculations get refined
- Order book reconstruction: Exchange infrastructure changes cause historical order book snapshots to shift
- Time synchronization fixes: Timestamp errors get corrected
Tardis.dev solves the first problem by providing structured, reliable data feeds including trades, order books, liquidations, and funding rates. HolySheep AI then adds an intelligence layer to track when those feeds change and what your backtesting results looked like before versus after.
Understanding Tardis.dev Data Architecture
Tardis.dev provides normalized market data from major exchanges. Here's the data structure you'll work with:
Core Data Types Available
| Data Type | Description | Use Case | HolySheep Processing Cost |
|---|---|---|---|
| Trades | Individual executed orders | Price action analysis | $0.004/1K events |
| Order Book | Bid/ask depth snapshots | Liquidity analysis | $0.008/1K snapshots |
| Liquidations | Forced position closures | Leverage sentiment | $0.003/1K events |
| Funding Rates | Periodic funding payments | Swap pricing | $0.002/1K rates |
Step 1: Setting Up Your Environment
Before we start, you'll need three things:
- A Tardis.dev account (free tier available)
- A HolySheep AI account (get free credits on signup)
- Python 3.9+ installed on your machine
Installing Required Libraries
Open your terminal and run:
# Create a virtual environment
python -m venv crypto-env
source crypto-env/bin/activate # On Windows: crypto-env\Scripts\activate
Install dependencies
pip install requests pandas python-dotenv tardis-client
pip install "holy-sheep-sdk>=1.0.0" # HolySheep official SDK
Verify installation
python -c "import holy_sheep; print('HolySheep SDK ready')"
💡 Screenshot hint: Your terminal should show successful installation with no error messages.
Step 2: Configuring API Credentials
Create a file named .env in your project root:
# Tardis.dev credentials
TARDIS_API_KEY=your_tardis_api_key_here
TARDIS_EXCHANGE=binance
HolySheep AI credentials (base_url is fixed)
Rate: ¥1=$1 — 85%+ savings vs ¥7.3 market rate
HOLYSHEEP_API_KEY=YOUR_HOLYSHEEP_API_KEY
HOLYSHEEP_BASE_URL=https://api.holysheep.ai/v1
Data storage paths
DATA_DIR=./crypto_data
VERSIONS_DIR=./version_history
Important: Never commit this file to version control. Add it to your .gitignore:
echo ".env" >> .gitignore
echo "__pycache__/" >> .gitignore
echo "*.csv" >> .gitignore
Step 3: Building the Dataset Version Tracker
Now let's create a Python module that handles version governance. I'll walk you through each component.
3.1 Initialize the HolySheep Client
# version_tracker.py
import os
import hashlib
import json
from datetime import datetime
from pathlib import Path
from typing import Dict, List, Optional
import requests
import pandas as pd
from dotenv import load_dotenv
Load environment variables
load_dotenv()
class CryptoVersionTracker:
"""
Tracks cryptocurrency dataset versions using Tardis.dev feeds
and HolySheep AI for intelligent change detection.
HolySheep Benefits:
- Rate: ¥1=$1 (85%+ savings vs ¥7.3)
- Latency: <50ms API responses
- Payment: WeChat/Alipay supported
"""
def __init__(self):
self.base_url = "https://api.holysheep.ai/v1"
self.api_key = os.getenv("HOLYSHEEP_API_KEY")
self.tardis_key = os.getenv("TARDIS_API_KEY")
self.exchange = os.getenv("TARDIS_EXCHANGE", "binance")
if not self.api_key:
raise ValueError("HOLYSHEEP_API_KEY not found in environment")
if not self.tardis_key:
raise ValueError("TARDIS_API_KEY not found in environment")
# Setup directories
self.data_dir = Path(os.getenv("DATA_DIR", "./crypto_data"))
self.versions_dir = Path(os.getenv("VERSIONS_DIR", "./version_history"))
self.data_dir.mkdir(exist_ok=True)
self.versions_dir.mkdir(exist_ok=True)
# Initialize HolySheep client headers
self.headers = {
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"
}
print("✅ CryptoVersionTracker initialized")
print(f" - HolySheep rate: ¥1=$1 (<50ms latency)")
print(f" - Exchange: {self.exchange}")
def analyze_backtest_impact(self, old_results: Dict, new_results: Dict) -> str:
"""
Uses HolySheep AI to analyze what changed between two backtest versions.
This helps identify which exchange corrections impacted your strategy.
"""
prompt = f"""
Analyze the impact of exchange data corrections on backtesting results:
PREVIOUS RESULTS:
{json.dumps(old_results, indent=2)}
CURRENT RESULTS:
{json.dumps(new_results, indent=2)}
Identify:
1. Which metrics changed significantly
2. Likely cause (trade correction, funding rate change, gap fill)
3. Whether the strategy is still valid
4. Recommended actions
"""
payload = {
"model": "deepseek-v3.2", # $0.42/Mtok - cost effective
"messages": [
{"role": "system", "content": "You are a quantitative trading analyst specializing in data quality assessment."},
{"role": "user", "content": prompt}
],
"temperature": 0.3
}
response = requests.post(
f"{self.base_url}/chat/completions",
headers=self.headers,
json=payload,
timeout=30 # HolySheep responds in <50ms
)
if response.status_code == 200:
return response.json()["choices"][0]["message"]["content"]
else:
raise Exception(f" HolySheep API error: {response.status_code} - {response.text}")
Usage example
tracker = CryptoVersionTracker()
3.2 Fetching Data from Tardis.dev with Version Hashing
# Continuing in version_tracker.py
import asyncio
from tardis_client import TardisClient, MessageType
class CryptoVersionTracker:
# ... previous code ...
async def fetch_trades_with_version(
self,
symbol: str,
start_date: datetime,
end_date: datetime
) -> Dict:
"""
Fetches trades from Tardis.dev and creates a versioned snapshot.
Includes cryptographic hash to detect any changes.
"""
client = TardisClient(self.tardis_key)
trades_data = []
version_hash_components = []
# Async iterator for trades
async for entry in client.as_iter(
exchange=self.exchange,
symbols=[symbol],
from_time=int(start_date.timestamp() * 1000),
to_time=int(end_date.timestamp() * 1000),
channels=[MessageType.trade]
):
if entry.type == MessageType.trade:
trade = {
"id": entry.id,
"timestamp": entry.timestamp,
"price": float(entry.price),
"amount": float(entry.amount),
"side": entry.side
}
trades_data.append(trade)
version_hash_components.append(f"{entry.id}:{entry.price}:{entry.amount}")
# Create deterministic hash for version tracking
combined = "|".join(sorted(version_hash_components))
version_hash = hashlib.sha256(combined.encode()).hexdigest()[:16]
# Save with version metadata
version_info = {
"version": version_hash,
"fetched_at": datetime.now().isoformat(),
"exchange": self.exchange,
"symbol": symbol,
"start_date": start_date.isoformat(),
"end_date": end_date.isoformat(),
"trade_count": len(trades_data),
"data_file": f"trades_{symbol}_{version_hash}.parquet"
}
# Save data as parquet for efficiency
df = pd.DataFrame(trades_data)
data_path = self.data_dir / version_info["data_file"]
df.to_parquet(data_path, index=False)
# Save version metadata
version_path = self.versions_dir / f"version_{version_hash}.json"
with open(version_path, "w") as f:
json.dump(version_info, f, indent=2)
print(f"✅ Fetched {len(trades_data)} trades")
print(f" Version hash: {version_hash}")
print(f" Saved to: {data_path}")
return version_info
async def fetch_orderbook_snapshots(
self,
symbol: str,
start_date: datetime,
end_date: datetime,
interval_ms: int = 1000 # Snapshot every 1 second
) -> Dict:
"""
Fetches order book snapshots with version tracking.
Order book changes are critical for slippage and liquidity analysis.
"""
client = TardisClient(self.tardis_key)
snapshots = []
version_components = []
async for entry in client.as_iter(
exchange=self.exchange,
symbols=[symbol],
from_time=int(start_date.timestamp() * 1000),
to_time=int(end_date.timestamp() * 1000),
channels=[MessageType.order_book_snapshot]
):
if entry.type == MessageType.order_book_snapshot:
snapshot = {
"timestamp": entry.timestamp,
"asks": [[float(p), float(a)] for p, a in entry.asks[:10]],
"bids": [[float(p), float(a)] for p, a in entry.bids[:10]],
"mid_price": (float(entry.asks[0][0]) + float(entry.bids[0][0])) / 2
}
snapshots.append(snapshot)
version_components.append(
f"{entry.timestamp}:{snapshot['mid_price']}"
)
combined = "|".join(version_components)
version_hash = hashlib.sha256(combined.encode()).hexdigest()[:16]
version_info = {
"version": version_hash,
"fetched_at": datetime.now().isoformat(),
"type": "orderbook_snapshots",
"exchange": self.exchange,
"symbol": symbol,
"snapshot_count": len(snapshots),
"data_file": f"orderbook_{symbol}_{version_hash}.parquet"
}
df = pd.DataFrame(snapshots)
data_path = self.data_dir / version_info["data_file"]
df.to_parquet(data_path, index=False)
version_path = self.versions_dir / f"version_{version_hash}.json"
with open(version_path, "w") as f:
json.dump(version_info, f, indent=2)
print(f"✅ Fetched {len(snapshots)} order book snapshots")
print(f" Version hash: {version_hash}")
return version_info
Run the async fetch
async def main():
tracker = CryptoVersionTracker()
# Fetch 1 hour of BTCUSDT trades from Binance
end_time = datetime(2026, 5, 4, 0, 0)
start_time = datetime(2026, 5, 3, 23, 0)
version = await tracker.fetch_trades_with_version(
symbol="BTCUSDT",
start_date=start_time,
end_date=end_time
)
print(f"\n📋 Version Summary:")
print(json.dumps(version, indent=2))
if __name__ == "__main__":
asyncio.run(main())
3.3 Detecting Data Gaps and Corrections
# gap_detector.py - Detects missing data and exchange corrections
import requests
import pandas as pd
from datetime import datetime, timedelta
from typing import List, Tuple, Dict
class DataGapDetector:
"""
Identifies gaps in historical data and detects when exchanges
make corrections that affect backtesting validity.
Powered by HolySheep AI for intelligent gap analysis.
"""
def __init__(self, holy_sheep_api_key: str):
self.api_key = holy_sheep_api_key
self.base_url = "https://api.holysheep.ai/v1"
self.headers = {
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"
}
def detect_timestamp_gaps(
self,
df: pd.DataFrame,
expected_interval_ms: int = 1000
) -> List[Dict]:
"""
Finds gaps in timestamp sequences.
Common cause: Exchange downtime or data relay issues.
"""
if "timestamp" not in df.columns:
raise ValueError("DataFrame must have 'timestamp' column")
gaps = []
df = df.sort_values("timestamp").reset_index(drop=True)
for i in range(1, len(df)):
time_diff = df.loc[i, "timestamp"] - df.loc[i-1, "timestamp"]
if time_diff > expected_interval_ms * 1.5: # 50% tolerance
gaps.append({
"gap_id": i,
"before_timestamp": df.loc[i-1, "timestamp"],
"after_timestamp": df.loc[i, "timestamp"],
"gap_duration_ms": time_diff,
"gap_duration_hours": time_diff / (1000 * 3600),
"data_loss_percent": (time_diff / expected_interval_ms - 1) * 100
})
return gaps
def detect_volume_anomalies(
self,
df: pd.DataFrame,
z_score_threshold: float = 3.0
) -> List[Dict]:
"""
Identifies unusual volume spikes that might indicate data errors
or require special handling in backtests.
"""
if "amount" not in df.columns:
raise ValueError("DataFrame must have 'amount' column")
mean_volume = df["amount"].mean()
std_volume = df["amount"].std()
anomalies = []
for idx, row in df.iterrows():
z_score = abs(row["amount"] - mean_volume) / std_volume if std_volume > 0 else 0
if z_score > z_score_threshold:
anomalies.append({
"timestamp": row.get("timestamp", idx),
"volume": row["amount"],
"z_score": z_score,
"deviation_from_mean": f"{(row['amount']/mean_volume - 1)*100:.1f}%",
"severity": "high" if z_score > 5 else "medium"
})
return anomalies
def analyze_correction_impact(
self,
old_df: pd.DataFrame,
new_df: pd.DataFrame,
strategy_params: Dict
) -> Dict:
"""
Uses HolySheep AI to intelligently assess how exchange corrections
impact specific backtesting strategy parameters.
HolySheep Pricing (2026):
- DeepSeek V3.2: $0.42/Mtok (most cost-effective for this)
- GPT-4.1: $8/Mtok (most capable)
- Claude Sonnet 4.5: $15/Mtok
- Gemini 2.5 Flash: $2.50/Mtok
"""
old_stats = {
"trade_count": len(old_df),
"avg_price": old_df["price"].mean() if "price" in old_df else 0,
"total_volume": old_df["amount"].sum() if "amount" in old_df else 0,
"price_std": old_df["price"].std() if "price" in old_df else 0
}
new_stats = {
"trade_count": len(new_df),
"avg_price": new_df["price"].mean() if "price" in new_df else 0,
"total_volume": new_df["amount"].sum() if "amount" in new_df else 0,
"price_std": new_df["price"].std() if "price" in new_df else 0
}
prompt = f"""
Analyze this backtesting dataset correction impact:
STRATEGY PARAMETERS:
{json.dumps(strategy_params, indent=2)}
OLD DATASET STATS:
{json.dumps(old_stats, indent=2)}
NEW DATASET STATS:
{json.dumps(new_stats, indent=2)}
Changes detected:
- Trade count change: {len(new_df) - len(old_df)} ({(len(new_df)/len(old_df)-1)*100 if len(old_df) > 0 else 0:+.2f}%)
- Average price change: {new_stats['avg_price'] - old_stats['avg_price']:+.6f}
- Volume change: {new_stats['total_volume'] - old_stats['total_volume']:+.2f}
Provide a detailed impact analysis focusing on:
1. Which strategy parameters are most affected
2. Should the backtest be re-run?
3. Risk assessment for live trading
4. Specific data points that changed (if identifiable)
"""
payload = {
"model": "deepseek-v3.2", # $0.42/Mtok - excellent value
"messages": [
{
"role": "system",
"content": "You are an expert quantitative analyst specializing in crypto data quality and backtesting validation."
},
{"role": "user", "content": prompt}
],
"temperature": 0.2,
"max_tokens": 1000
}
response = requests.post(
f"{self.base_url}/chat/completions",
headers=self.headers,
json=payload,
timeout=30
)
if response.status_code == 200:
analysis = response.json()["choices"][0]["message"]["content"]
return {
"status": "success",
"analysis": analysis,
"old_stats": old_stats,
"new_stats": new_stats,
"cost_estimate_usd": response.json().get("usage", {}).get("total_tokens", 0) * 0.00042
}
else:
raise Exception(f"Analysis failed: {response.status_code}")
Usage example
detector = DataGapDetector("YOUR_HOLYSHEEP_API_KEY")
Detect gaps in fetched data
df = pd.read_parquet("./crypto_data/trades_BTCUSDT_abc123.parquet")
gaps = detector.detect_timestamp_gaps(df)
print(f"🔍 Found {len(gaps)} gaps in the data")
for gap in gaps[:5]: # Show first 5
print(f" Gap at {gap['before_timestamp']}: {gap['gap_duration_hours']:.2f} hours missing")
Step 4: Implementing Complete Version Governance
# main_backtest_governance.py - Complete implementation
import asyncio
import json
from datetime import datetime, timedelta
from pathlib import Path
from typing import Dict, List
import pandas as pd
import requests
from dotenv import load_dotenv
from version_tracker import CryptoVersionTracker
from gap_detector import DataGapDetector
load_dotenv()
class BacktestVersionManager:
"""
Complete version governance system for crypto backtesting.
Features:
- Automatic version hashing of all data sources
- Gap detection and reporting
- Exchange correction impact analysis
- Backtest result diffing with HolySheep AI
HolySheep Benefits:
- Rate: ¥1=$1 (85%+ savings vs ¥7.3)
- Latency: <50ms per API call
- Payment: WeChat/Alipay
"""
def __init__(self):
self.tracker = CryptoVersionTracker()
self.detector = DataGapDetector(os.getenv("HOLYSHEEP_API_KEY"))
self.version_history = []
def run_backtest(self, version_hash: str, params: Dict) -> Dict:
"""
Simulates running a backtest with a specific data version.
In production, replace with your actual backtesting engine.
"""
# Load the version's data
data_file = self.tracker.data_dir / f"trades_BTCUSDT_{version_hash}.parquet"
if not data_file.exists():
raise FileNotFoundError(f"Data file not found: {data_file}")
df = pd.read_parquet(data_file)
# Simulated backtest results (replace with real backtest)
results = {
"version_hash": version_hash,
"run_timestamp": datetime.now().isoformat(),
"total_trades": len(df),
"avg_slippage_bps": abs(df["price"].pct_change().std() * 10000) if len(df) > 1 else 0,
"win_rate": 0.58, # Simulated
"sharpe_ratio": 2.1, # Simulated
"max_drawdown": 0.12, # Simulated
"profit_factor": 1.45 # Simulated
}
return results
async def fetch_and_version_data(
self,
symbol: str,
hours: int = 24
) -> Dict:
"""Fetches fresh data and creates new version."""
end_time = datetime.now()
start_time = end_time - timedelta(hours=hours)
print(f"📥 Fetching {symbol} data from {start_time} to {end_time}")
# Fetch from Tardis.dev
version_info = await self.tracker.fetch_trades_with_version(
symbol=symbol,
start_date=start_time,
end_date=end_time
)
# Analyze for gaps
data_file = self.tracker.data_dir / version_info["data_file"]
df = pd.read_parquet(data_file)
gaps = self.detector.detect_timestamp_gaps(df)
anomalies = self.detector.detect_volume_anomalies(df)
version_info["gaps_detected"] = len(gaps)
version_info["anomalies_detected"] = len(anomalies)
version_info["gap_details"] = gaps[:10] # Store top 10
version_info["anomaly_details"] = anomalies[:10]
return version_info
def compare_versions(
self,
old_version: Dict,
new_version: Dict
) -> Dict:
"""
Compares two versions using HolySheep AI analysis.
"""
print(f"🔄 Comparing versions:")
print(f" Old: {old_version['version']} ({old_version.get('trade_count', 'N/A')} trades)")
print(f" New: {new_version['version']} ({new_version.get('trade_count', 'N/A')} trades)")
# Run backtests for both versions
old_results = self.run_backtest(old_version["version"], {})
new_results = self.run_backtest(new_version["version"], {})
# Use HolySheep AI for intelligent comparison
analysis = self.tracker.analyze_backtest_impact(old_results, new_results)
comparison = {
"old_version": old_version["version"],
"new_version": new_version["version"],
"trade_count_delta": new_version.get("trade_count", 0) - old_version.get("trade_count", 0),
"gap_change": new_version.get("gaps_detected", 0) - old_version.get("gaps_detected", 0),
"backtest_comparison": {
"old_results": old_results,
"new_results": new_results
},
"holy_sheep_analysis": analysis
}
return comparison
def generate_version_report(self) -> str:
"""
Generates a comprehensive version governance report using HolySheep.
"""
prompt = f"""
Generate a dataset version governance report for cryptocurrency backtesting.
Total versions tracked: {len(self.version_history)}
{json.dumps(self.version_history[:10], indent=2) if self.version_history else "No versions yet"}
Include:
1. Data quality summary
2. Trend analysis (are gaps increasing/decreasing?)
3. Recommendations for improving data reliability
4. Risk assessment for production deployment
"""
payload = {
"model": "gpt-4.1", # $8/Mtok - best for comprehensive reports
"messages": [
{
"role": "system",
"content": "You are a senior data engineering analyst creating executive summaries for quantitative trading teams."
},
{"role": "user", "content": prompt}
],
"temperature": 0.3
}
response = requests.post(
f"https://api.holysheep.ai/v1/chat/completions",
headers=self.tracker.headers,
json=payload,
timeout=45
)
if response.status_code == 200:
return response.json()["choices"][0]["message"]["content"]
else:
return f"Report generation failed: {response.status_code}"
async def main():
"""Main execution example."""
print("🚀 Starting Crypto Dataset Version Governance\n")
manager = BacktestVersionManager()
# Step 1: Fetch current data
current_version = await manager.fetch_and_version_data("BTCUSDT", hours=1)
print(f"\n✅ Current version created: {current_version['version']}")
# Step 2: If we have a previous version, compare
if manager.version_history:
previous_version = manager.version_history[-1]
comparison = manager.compare_versions(previous_version, current_version)
print(f"\n📊 Comparison Results:")
print(f" Trade count change: {comparison['trade_count_delta']:+d}")
print(f" Gap change: {comparison['gap_change']:+d}")
print(f"\n💡 HolySheep AI Analysis:")
print(comparison['holy_sheep_analysis'])
# Step 3: Add to history
manager.version_history.append(current_version)
# Step 4: Generate governance report
print(f"\n📋 Generating version governance report...")
report = manager.generate_version_report()
print(f"\n{report}")
print(f"\n✨ Done! Version {current_version['version']} is now tracked.")
print(f" HolySheep latency: <50ms | Rate: ¥1=$1")
if __name__ == "__main__":
asyncio.run(main())
Step 5: Visualizing Version History
To complete the governance system, let's add visualization capabilities:
# visualization.py - Track and visualize dataset changes
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import pandas as pd
from datetime import datetime
from pathlib import Path
from typing import List, Dict
import json
def plot_version_timeline(version_history: List[Dict], save_path: str = "version_timeline.png"):
"""
Creates a timeline visualization of dataset versions and quality metrics.
This helps you quickly spot:
- Increasing gap frequency (exchange problems)
- Correction waves (exchange data rebuilds)
- Data quality trends
"""
if not version_history:
print("No version history to plot")
return
fig, axes = plt.subplots(3, 1, figsize=(14, 10), sharex=True)
fig.suptitle("Crypto Dataset Version Governance Timeline", fontsize=14, fontweight="bold")
# Extract data
versions = [v["version"][:8] for v in version_history] # Short hash
timestamps = [datetime.fromisoformat(v["fetched_at"]) for v in version_history]
trade_counts = [v.get("trade_count", 0) for v in version_history]
gaps = [v.get("gaps_detected", 0) for v in version_history]
anomalies = [v.get("anomalies_detected", 0) for v in version_history]
# Plot 1: Trade counts
axes[0].plot(timestamps, trade_counts, 'b-o', linewidth=2, markersize=6)
axes[0].set_ylabel("Trade Count")
axes[0].set_title("Data Volume Over Time")
axes[0].grid(True, alpha=0.3)
axes[0].fill_between(timestamps, trade_counts, alpha=0.3)
# Plot 2: Gap count
axes[1].bar(timestamps, gaps, width=0.0005, color='orange', alpha=0.7, label="Gaps")
axes[1].bar(timestamps, anomalies, width=0.0005, bottom=gaps, color='red', alpha=0.7, label="Anomalies")
axes[1].set_ylabel("Issue Count")
axes[1].set_title("Data Quality Issues Detected")
axes[1].legend()
axes[1].grid(True, alpha=0.3)
# Plot 3: Cumulative trade count
cumulative = pd.Series(trade_counts).cumsum()
axes[2].plot(timestamps, cumulative, 'g-', linewidth=2)
axes[2].set_ylabel("Cumulative Trades")
axes[2].set_xlabel("Version Fetch Time")
axes[2].set_title("Cumulative Data Collection")
axes[2].grid(True, alpha=0.3)
# Format x-axis
axes[2].xaxis.set_major_formatter(mdates.DateFormatter('%m-%d %H:%M'))
plt.xticks(rotation=45)
plt.tight_layout()
plt.savefig(save_path, dpi=150, bbox_inches='tight')
print(f"📊 Timeline saved to {save_path}")
return fig
def generate_summary_stats(version_history: List[Dict]) -> Dict:
"""Generate summary statistics from version history."""
if not version_history:
return {}
trade_counts = [v.get("trade_count", 0) for v in version_history]
gaps = [v.get("gaps_detected", 0) for v in version_history]
anomalies = [v.get("anomal