hyper-agent-core 0.1.0

Core domain logic for hyper-agent: pipeline, executor, signals, positions
Documentation
use crate::position_manager::PositionManager;
use serde::Serialize;

#[derive(Serialize)]
pub struct DashboardStats {
    pub engines_running: u32,
    pub open_positions: u32,
    pub total_pnl: f64,
}

pub async fn get_stats(
    pm: &PositionManager,
    engines_running: u32,
) -> Result<DashboardStats, String> {
    let open = pm.list_open().await.map_err(|e| e.to_string())?;
    let closed = pm.list_closed(1000).await.map_err(|e| e.to_string())?;
    let total_pnl: f64 = closed.iter().filter_map(|p| p.pnl).sum();

    Ok(DashboardStats {
        engines_running,
        open_positions: open.len() as u32,
        total_pnl,
    })
}

pub async fn get_pnl_history(pm: &PositionManager) -> Result<Vec<(String, f64)>, String> {
    let closed = pm.list_closed(1000).await.map_err(|e| e.to_string())?;
    let mut cumulative = 0.0;
    let points: Vec<(String, f64)> = closed
        .iter()
        .filter(|p| p.closed_at.is_some())
        .map(|p| {
            cumulative += p.pnl.unwrap_or(0.0);
            (p.closed_at.clone().unwrap_or_default(), cumulative)
        })
        .collect();
    Ok(points)
}