2026-01-25 01:20:44 -07:00

104 lines
2.8 KiB
Rust

mod handlers;
use crate::engine::PaperTradingEngine;
use crate::metrics::BacktestResult;
use crate::store::SqliteStore;
use axum::routing::{get, post};
use axum::Router;
use chrono::{DateTime, Utc};
use std::path::PathBuf;
use std::sync::Arc;
use tokio::sync::broadcast;
use tower_http::services::ServeDir;
pub enum BacktestRunStatus {
Idle,
Running { started_at: DateTime<Utc> },
Complete,
Failed,
}
pub struct BacktestProgress {
pub phase: std::sync::atomic::AtomicU8,
pub current_step: std::sync::atomic::AtomicU64,
pub total_steps: std::sync::atomic::AtomicU64,
}
impl BacktestProgress {
pub const PHASE_LOADING: u8 = 0;
pub const PHASE_RUNNING: u8 = 1;
pub fn new(total_steps: u64) -> Self {
Self {
phase: std::sync::atomic::AtomicU8::new(
Self::PHASE_LOADING,
),
current_step: std::sync::atomic::AtomicU64::new(0),
total_steps: std::sync::atomic::AtomicU64::new(
total_steps,
),
}
}
pub fn phase_name(&self) -> &'static str {
match self
.phase
.load(std::sync::atomic::Ordering::Relaxed)
{
Self::PHASE_LOADING => "loading data",
Self::PHASE_RUNNING => "simulating",
_ => "unknown",
}
}
}
pub struct BacktestState {
pub status: BacktestRunStatus,
pub progress: Option<Arc<BacktestProgress>>,
pub result: Option<BacktestResult>,
pub error: Option<String>,
}
pub struct AppState {
pub engine: Arc<PaperTradingEngine>,
pub store: Arc<SqliteStore>,
pub shutdown_tx: broadcast::Sender<()>,
pub backtest: Arc<tokio::sync::Mutex<BacktestState>>,
pub data_dir: PathBuf,
}
pub fn build_router(state: Arc<AppState>) -> Router {
Router::new()
.route("/api/status", get(handlers::get_status))
.route("/api/portfolio", get(handlers::get_portfolio))
.route("/api/positions", get(handlers::get_positions))
.route("/api/trades", get(handlers::get_trades))
.route("/api/equity", get(handlers::get_equity))
.route(
"/api/circuit-breaker",
get(handlers::get_circuit_breaker),
)
.route(
"/api/control/pause",
post(handlers::post_pause),
)
.route(
"/api/control/resume",
post(handlers::post_resume),
)
.route(
"/api/backtest/run",
post(handlers::post_backtest_run),
)
.route(
"/api/backtest/status",
get(handlers::get_backtest_status),
)
.route(
"/api/backtest/result",
get(handlers::get_backtest_result),
)
.fallback_service(ServeDir::new("static"))
.with_state(state)
}