104 lines
2.8 KiB
Rust
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)
|
|
}
|