//! Debug DBN Raw Prices //! //! Prints the first 20 bars with RAW price values to diagnose conversion issues. use anyhow::Result; use dbn::decode::{DecodeRecordRef, DbnDecoder}; use dbn::{OhlcvMsg, VersionUpgradePolicy}; #[tokio::main] async fn main() -> Result<()> { println!("DBN Raw Price Debug"); println!("===================\n"); let file_path = "test_data/real/databento/ES.FUT_ohlcv-1m_2024-01-02.dbn"; // Create decoder let mut decoder = DbnDecoder::from_file(file_path)?; decoder.set_upgrade_policy(VersionUpgradePolicy::UpgradeToV3)?; let mut count = 0; let start_bar = 1495; // Start from bar 1495 let max_bars = 1520; // Show through bar 1520 println!("Bar# | RAW Open | RAW High | RAW Low | RAW Close | Converted Close | % Change"); println!("{}", "-".repeat(120)); let mut prev_close_converted = 0.0; while let Some(record_ref) = decoder.decode_record_ref()? { if let Some(ohlcv) = record_ref.get::() { count += 1; // Skip bars before start_bar if count < start_bar { continue; } // Raw values let raw_open = ohlcv.open; let raw_high = ohlcv.high; let raw_low = ohlcv.low; let raw_close = ohlcv.close; // Converted value (current method: divide by 1 billion) let converted_close = raw_close as f64 / 1_000_000_000.0; // Alternative conversion (divide by 10 million - 2 decimal places less) let alt_converted_close = raw_close as f64 / 10_000_000.0; // Calculate percent change from previous bar let pct_change = if count > 1 { ((converted_close - prev_close_converted) / prev_close_converted).abs() * 100.0 } else { 0.0 }; println!("{:4} | {:14} | {:14} | {:14} | {:14} | ${:11.2} | {:6.2}%", count, raw_open, raw_high, raw_low, raw_close, converted_close, pct_change); // Show alternative conversion for anomalous bars if pct_change > 10.0 && count > 1 { println!(" | Alternative (÷10M): ${:.2} | % change: {:.2}%", alt_converted_close, ((alt_converted_close - (prev_close_converted * 100.0)) / (prev_close_converted * 100.0)).abs() * 100.0 ); } prev_close_converted = converted_close; if count >= max_bars { break; } } } println!("\n📊 Analysis:"); println!(" Current conversion: price_i64 / 1,000,000,000 (9 decimal places)"); println!(" Alternative conversion: price_i64 / 10,000,000 (7 decimal places)"); println!("\n If alternating between two price levels, check:"); println!(" 1. Whether some bars use different scale factors"); println!(" 2. Whether price encoding varies by bar type/flag"); println!(" 3. Whether DBN metadata specifies per-message scale"); Ok(()) }