diff --git a/src/main.rs b/src/main.rs index 5b97272..534ab01 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,16 +1,16 @@ mod records; +use crate::records::{DataPoint, M1Record, OhlcItem, TickRecord}; +use bytemuck::cast_slice; +use eframe::egui; +use std::collections::HashMap; +use std::io::Read; use std::path::{Path, PathBuf}; use std::sync::{Arc, RwLock}; use std::time::Instant; -use eframe::egui; -use tokio::runtime::Runtime; -use std::collections::HashMap; use sysinfo::System; +use tokio::runtime::Runtime; use zip::ZipArchive; -use bytemuck::cast_slice; -use std::io::Read; -use crate::records::{M1Record, TickRecord, OhlcItem, DataPoint}; // --- Data Structures --- @@ -19,7 +19,7 @@ pub struct DataFile { pub path: PathBuf, pub symbol: String, pub year: i32, - pub month: i, + pub month: i32, } struct CacheEntry { @@ -56,7 +56,10 @@ impl DataServer { let path = entry.path(); if let Some(file_name) = path.file_name().and_then(|n| n.to_str()) { if let Some(data_file) = self.parse_file_name(&path, file_name) { - temp_map.entry(data_file.symbol.clone()).or_default().push(data_file); + temp_map + .entry(data_file.symbol.clone()) + .or_default() + .push(data_file); } } } @@ -81,14 +84,24 @@ impl DataServer { let stem = Path::new(file_name).file_stem()?.to_str()?; let ext = Path::new(file_name).extension()?.to_str()?; let parts: Vec<&str> = stem.split('_').collect(); - if parts.len() < 3 { return None; } + if parts.len() < 3 { + return None; + } let month = parts.last()?.parse::().ok()?; let year = parts[parts.len() - 2].parse::().ok()?; let symbol = format!("{}.{}", parts[..parts.len() - 2].join("_"), ext); - Some(DataFile { path: path.to_path_buf(), symbol, year, month }) + Some(DataFile { + path: path.to_path_buf(), + symbol, + year, + month, + }) } - pub async fn load_m1_data(&self, data_file: &DataFile) -> anyhow::Result>>> { + pub async fn load_m1_data( + &self, + data_file: &DataFile, + ) -> anyhow::Result>>> { { let mut cache = self.m1_cache.write().unwrap(); if let Some(entry) = cache.get_mut(&data_file.path) { @@ -97,10 +110,17 @@ impl DataServer { } } let raw_data = self.read_from_zip::(&data_file.path).await?; - let mapped_data: Vec> = raw_data.into_iter().map(|r| r.to_ohlc()).collect(); + let mapped_data: Vec> = + raw_data.into_iter().map(|r| r.to_ohlc()).collect(); let shared_data = Arc::new(mapped_data); let mut cache = self.m1_cache.write().unwrap(); - cache.insert(data_file.path.clone(), CacheEntry { data: Arc::clone(&shared_data), last_accessed: Instant::now() }); + cache.insert( + data_file.path.clone(), + CacheEntry { + data: Arc::clone(&shared_data), + last_accessed: Instant::now(), + }, + ); Ok(shared_data) } @@ -138,7 +158,7 @@ impl DataViewerApp { fn new(cc: &eframe::CreationContext<'_>) -> Self { let server = Arc::new(DataServer::new(r"\\COFFEE\TickData\Pepperstone")); let rt = Runtime::new().unwrap(); - + let (tx, rx) = std::sync::mpsc::channel(); // Initial symbol load @@ -180,7 +200,7 @@ impl DataViewerApp { for file in files { if file.symbol.ends_with(".m1") { if let Ok(data) = server.load_m1_data(&file).await { - all_data.extend((*data).clone()); + all_data.extend_from_slice(&data); } } } @@ -199,7 +219,10 @@ impl eframe::App for DataViewerApp { if let Ok(data) = self.rx.try_recv() { self.loaded_data = Some(data); self.is_loading = false; - self.status_msg = format!("Loaded {} records", self.loaded_data.as_ref().unwrap().len()); + self.status_msg = format!( + "Loaded {} records", + self.loaded_data.as_ref().unwrap().len() + ); } let mut symbol_to_load = None; @@ -229,7 +252,7 @@ impl eframe::App for DataViewerApp { ui.label("Streaming from network share..."); } else if let Some(data) = &self.loaded_data { ui.label(format!("Successfully loaded {} records.", data.len())); - + // Show a small sample egui::ScrollArea::vertical().show(ui, |ui| { for i in 0..data.len().min(10000) { @@ -239,7 +262,10 @@ impl eframe::App for DataViewerApp { let high = d.data.high; let low = d.data.low; let close = d.data.close; - ui.label(format!("{}: O:{:.5} H:{:.5} L:{:.5} C:{:.5}", i, open, high, low, close)); + ui.label(format!( + "{}: O:{:.5} H:{:.5} L:{:.5} C:{:.5}", + i, open, high, low, close + )); } }); }