//! 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::().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(()) }