- Created data/examples/download_ml_training_data.rs using reqwest + Databento HTTP API - Downloaded 90 days × 4 symbols (ES.FUT, NQ.FUT, ZN.FUT, 6E.FUT) - Files saved to test_data/real/databento/ml_training/ - Total: 360 files, 15 MB compressed DBN format - Used existing Rust pattern from download_nq_fut.rs - API key loaded from .env file - 100% success rate (360/360 files) - Ready for ML training benchmarks Next: Create simplified training benchmark for RTX 3050 Ti GPU measurements
113 lines
2.9 KiB
Rust
113 lines
2.9 KiB
Rust
//! Basic DBN Loading Example
|
|
//!
|
|
//! This example demonstrates the simplest way to load OHLCV bars from a DBN file.
|
|
//!
|
|
//! ## Usage
|
|
//!
|
|
//! ```bash
|
|
//! cargo run --example dbn_basic_loading
|
|
//! ```
|
|
|
|
use backtesting_service::dbn_data_source::DbnDataSource;
|
|
use std::collections::HashMap;
|
|
|
|
#[tokio::main]
|
|
async fn main() -> anyhow::Result<()> {
|
|
println!("=== DBN Basic Loading Example ===\n");
|
|
|
|
// 1. Create file mapping (symbol -> file path)
|
|
let mut file_mapping = HashMap::new();
|
|
file_mapping.insert(
|
|
"ES.FUT".to_string(),
|
|
"test_data/real/databento/ES.FUT_ohlcv-1m_2024-01-02.dbn".to_string(),
|
|
);
|
|
|
|
println!("Creating data source with 1 symbol...");
|
|
|
|
// 2. Create data source
|
|
let data_source = DbnDataSource::new(file_mapping).await?;
|
|
|
|
println!("Available symbols: {:?}", data_source.available_symbols());
|
|
|
|
// 3. Load OHLCV bars
|
|
println!("\nLoading OHLCV bars for ES.FUT...");
|
|
let bars = data_source.load_ohlcv_bars("ES.FUT").await?;
|
|
|
|
println!("✅ Loaded {} bars from DBN file\n", bars.len());
|
|
|
|
// 4. Display first and last bars
|
|
println!("First bar:");
|
|
let first = &bars[0];
|
|
println!(
|
|
" {} @ {} (open={}, high={}, low={}, close={}, volume={})",
|
|
first.symbol,
|
|
first.timestamp,
|
|
first.open,
|
|
first.high,
|
|
first.low,
|
|
first.close,
|
|
first.volume
|
|
);
|
|
|
|
println!("\nLast bar:");
|
|
let last = &bars[bars.len() - 1];
|
|
println!(
|
|
" {} @ {} (open={}, high={}, low={}, close={}, volume={})",
|
|
last.symbol,
|
|
last.timestamp,
|
|
last.open,
|
|
last.high,
|
|
last.low,
|
|
last.close,
|
|
last.volume
|
|
);
|
|
|
|
// 5. Validate data quality
|
|
println!("\n=== Data Quality Checks ===");
|
|
|
|
// Check OHLCV relationships
|
|
let mut valid_count = 0;
|
|
for bar in &bars {
|
|
if bar.high >= bar.low
|
|
&& bar.high >= bar.open
|
|
&& bar.high >= bar.close
|
|
&& bar.low <= bar.open
|
|
&& bar.low <= bar.close
|
|
{
|
|
valid_count += 1;
|
|
}
|
|
}
|
|
|
|
println!("OHLCV validation: {}/{} bars passed", valid_count, bars.len());
|
|
|
|
// Check timestamp ordering
|
|
let mut ordered = true;
|
|
for i in 1..bars.len() {
|
|
if bars[i].timestamp < bars[i - 1].timestamp {
|
|
ordered = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
println!("Timestamp ordering: {}", if ordered { "✅ Sorted" } else { "❌ Not sorted" });
|
|
|
|
// Check price ranges (ES.FUT typical: $3,000-$6,000)
|
|
let mut realistic_prices = 0;
|
|
for bar in &bars {
|
|
let close_f64 = bar.close.to_string().parse::<f64>().unwrap();
|
|
if close_f64 > 3000.0 && close_f64 < 6000.0 {
|
|
realistic_prices += 1;
|
|
}
|
|
}
|
|
|
|
println!(
|
|
"Realistic prices: {}/{} bars in range",
|
|
realistic_prices,
|
|
bars.len()
|
|
);
|
|
|
|
println!("\n✅ Example completed successfully!");
|
|
|
|
Ok(())
|
|
}
|