Download 360 DBN files (36.3 MB) using Rust databento client
- 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
This commit is contained in:
112
docs/examples/dbn_basic_loading.rs
Normal file
112
docs/examples/dbn_basic_loading.rs
Normal file
@@ -0,0 +1,112 @@
|
||||
//! 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(())
|
||||
}
|
||||
Reference in New Issue
Block a user