Update main.rs
This commit is contained in:
+42
-16
@@ -1,16 +1,16 @@
|
|||||||
mod records;
|
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::path::{Path, PathBuf};
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use eframe::egui;
|
|
||||||
use tokio::runtime::Runtime;
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use sysinfo::System;
|
use sysinfo::System;
|
||||||
|
use tokio::runtime::Runtime;
|
||||||
use zip::ZipArchive;
|
use zip::ZipArchive;
|
||||||
use bytemuck::cast_slice;
|
|
||||||
use std::io::Read;
|
|
||||||
use crate::records::{M1Record, TickRecord, OhlcItem, DataPoint};
|
|
||||||
|
|
||||||
// --- Data Structures ---
|
// --- Data Structures ---
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ pub struct DataFile {
|
|||||||
pub path: PathBuf,
|
pub path: PathBuf,
|
||||||
pub symbol: String,
|
pub symbol: String,
|
||||||
pub year: i32,
|
pub year: i32,
|
||||||
pub month: i,
|
pub month: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CacheEntry<T> {
|
struct CacheEntry<T> {
|
||||||
@@ -56,7 +56,10 @@ impl DataServer {
|
|||||||
let path = entry.path();
|
let path = entry.path();
|
||||||
if let Some(file_name) = path.file_name().and_then(|n| n.to_str()) {
|
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) {
|
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 stem = Path::new(file_name).file_stem()?.to_str()?;
|
||||||
let ext = Path::new(file_name).extension()?.to_str()?;
|
let ext = Path::new(file_name).extension()?.to_str()?;
|
||||||
let parts: Vec<&str> = stem.split('_').collect();
|
let parts: Vec<&str> = stem.split('_').collect();
|
||||||
if parts.len() < 3 { return None; }
|
if parts.len() < 3 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
let month = parts.last()?.parse::<i32>().ok()?;
|
let month = parts.last()?.parse::<i32>().ok()?;
|
||||||
let year = parts[parts.len() - 2].parse::<i32>().ok()?;
|
let year = parts[parts.len() - 2].parse::<i32>().ok()?;
|
||||||
let symbol = format!("{}.{}", parts[..parts.len() - 2].join("_"), ext);
|
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<Arc<Vec<DataPoint<OhlcItem>>>> {
|
pub async fn load_m1_data(
|
||||||
|
&self,
|
||||||
|
data_file: &DataFile,
|
||||||
|
) -> anyhow::Result<Arc<Vec<DataPoint<OhlcItem>>>> {
|
||||||
{
|
{
|
||||||
let mut cache = self.m1_cache.write().unwrap();
|
let mut cache = self.m1_cache.write().unwrap();
|
||||||
if let Some(entry) = cache.get_mut(&data_file.path) {
|
if let Some(entry) = cache.get_mut(&data_file.path) {
|
||||||
@@ -97,10 +110,17 @@ impl DataServer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let raw_data = self.read_from_zip::<M1Record>(&data_file.path).await?;
|
let raw_data = self.read_from_zip::<M1Record>(&data_file.path).await?;
|
||||||
let mapped_data: Vec<DataPoint<OhlcItem>> = raw_data.into_iter().map(|r| r.to_ohlc()).collect();
|
let mapped_data: Vec<DataPoint<OhlcItem>> =
|
||||||
|
raw_data.into_iter().map(|r| r.to_ohlc()).collect();
|
||||||
let shared_data = Arc::new(mapped_data);
|
let shared_data = Arc::new(mapped_data);
|
||||||
let mut cache = self.m1_cache.write().unwrap();
|
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)
|
Ok(shared_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,7 +200,7 @@ impl DataViewerApp {
|
|||||||
for file in files {
|
for file in files {
|
||||||
if file.symbol.ends_with(".m1") {
|
if file.symbol.ends_with(".m1") {
|
||||||
if let Ok(data) = server.load_m1_data(&file).await {
|
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() {
|
if let Ok(data) = self.rx.try_recv() {
|
||||||
self.loaded_data = Some(data);
|
self.loaded_data = Some(data);
|
||||||
self.is_loading = false;
|
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;
|
let mut symbol_to_load = None;
|
||||||
@@ -239,7 +262,10 @@ impl eframe::App for DataViewerApp {
|
|||||||
let high = d.data.high;
|
let high = d.data.high;
|
||||||
let low = d.data.low;
|
let low = d.data.low;
|
||||||
let close = d.data.close;
|
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
|
||||||
|
));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user