fix(backtesting): Add mock() method to DefaultRepositories for tests
- Implements DefaultRepositories::mock() for wave_comparison tests - Mock implementations use in-memory Arc<RwLock<>> for thread-safe testing - Method is #[cfg(test)] scoped to test builds only - Fixes compilation errors in wave_comparison.rs (lines 711, 730) - All backtesting tests pass (2/2 wave_comparison tests OK) Additional updates: - Update .dockerignore, .env.runpod, CLAUDE.md - Update Cargo.lock and Dockerfile.foxhunt-build
This commit is contained in:
@@ -171,3 +171,201 @@ impl BacktestingRepositories for DefaultRepositories {
|
||||
self.news.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
impl DefaultRepositories {
|
||||
/// Create a mock instance for testing
|
||||
///
|
||||
/// This method is only available in test builds and creates
|
||||
/// in-memory mock repositories for unit testing.
|
||||
pub fn mock() -> Self {
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::RwLock;
|
||||
use std::collections::HashMap;
|
||||
|
||||
// Mock market data repository
|
||||
struct MockMarketData {
|
||||
data: Arc<RwLock<Vec<crate::strategy_engine::MarketData>>>,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl MarketDataRepository for MockMarketData {
|
||||
async fn load_historical_data(
|
||||
&self,
|
||||
_symbols: &[String],
|
||||
_start_time: i64,
|
||||
_end_time: i64,
|
||||
) -> Result<Vec<crate::strategy_engine::MarketData>> {
|
||||
Ok(self.data.read().await.clone())
|
||||
}
|
||||
|
||||
async fn check_data_availability(
|
||||
&self,
|
||||
symbols: &[String],
|
||||
_start_time: i64,
|
||||
_end_time: i64,
|
||||
) -> Result<HashMap<String, bool>> {
|
||||
let mut availability = HashMap::new();
|
||||
for symbol in symbols {
|
||||
availability.insert(symbol.clone(), true);
|
||||
}
|
||||
Ok(availability)
|
||||
}
|
||||
}
|
||||
|
||||
// Mock trading repository
|
||||
struct MockTrading {
|
||||
trades: Arc<RwLock<HashMap<String, Vec<BacktestTrade>>>>,
|
||||
metrics: Arc<RwLock<HashMap<String, PerformanceMetrics>>>,
|
||||
backtests: Arc<RwLock<Vec<BacktestSummary>>>,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl TradingRepository for MockTrading {
|
||||
async fn save_backtest_results(
|
||||
&self,
|
||||
backtest_id: &str,
|
||||
trades: &[BacktestTrade],
|
||||
metrics: &PerformanceMetrics,
|
||||
) -> Result<()> {
|
||||
self.trades.write().await.insert(backtest_id.to_string(), trades.to_vec());
|
||||
self.metrics.write().await.insert(backtest_id.to_string(), metrics.clone());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn load_backtest_results(
|
||||
&self,
|
||||
backtest_id: &str,
|
||||
) -> Result<(Vec<BacktestTrade>, PerformanceMetrics)> {
|
||||
let trades = self.trades.read().await
|
||||
.get(backtest_id)
|
||||
.cloned()
|
||||
.unwrap_or_default();
|
||||
let metrics = self.metrics.read().await
|
||||
.get(backtest_id)
|
||||
.cloned()
|
||||
.unwrap_or_default();
|
||||
Ok((trades, metrics))
|
||||
}
|
||||
|
||||
async fn create_backtest_record(
|
||||
&self,
|
||||
backtest_id: &str,
|
||||
strategy_name: &str,
|
||||
symbols: &[String],
|
||||
start_date: DateTime<Utc>,
|
||||
end_date: DateTime<Utc>,
|
||||
_initial_capital: f64,
|
||||
_parameters: &HashMap<String, String>,
|
||||
description: &str,
|
||||
) -> Result<()> {
|
||||
let summary = BacktestSummary {
|
||||
backtest_id: backtest_id.to_string(),
|
||||
strategy_name: strategy_name.to_string(),
|
||||
symbols: symbols.to_vec(),
|
||||
status: BacktestStatus::Queued,
|
||||
total_return: 0.0,
|
||||
sharpe_ratio: 0.0,
|
||||
max_drawdown: 0.0,
|
||||
created_at: Utc::now(),
|
||||
start_date,
|
||||
end_date,
|
||||
description: description.to_string(),
|
||||
};
|
||||
self.backtests.write().await.push(summary);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn update_backtest_status(
|
||||
&self,
|
||||
backtest_id: &str,
|
||||
status: BacktestStatus,
|
||||
_error_message: Option<&str>,
|
||||
) -> Result<()> {
|
||||
let mut backtests = self.backtests.write().await;
|
||||
if let Some(bt) = backtests.iter_mut().find(|b| b.backtest_id == backtest_id) {
|
||||
bt.status = status;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn list_backtests(
|
||||
&self,
|
||||
limit: u32,
|
||||
offset: u32,
|
||||
strategy_name: Option<String>,
|
||||
status_filter: Option<BacktestStatus>,
|
||||
) -> Result<Vec<BacktestSummary>> {
|
||||
let backtests = self.backtests.read().await;
|
||||
let filtered: Vec<BacktestSummary> = backtests
|
||||
.iter()
|
||||
.filter(|bt| {
|
||||
let name_match = strategy_name.as_ref()
|
||||
.map(|n| bt.strategy_name == *n)
|
||||
.unwrap_or(true);
|
||||
let status_match = status_filter.map(|s| bt.status == s).unwrap_or(true);
|
||||
name_match && status_match
|
||||
})
|
||||
.skip(offset as usize)
|
||||
.take(limit as usize)
|
||||
.cloned()
|
||||
.collect();
|
||||
Ok(filtered)
|
||||
}
|
||||
|
||||
async fn store_time_series_data(
|
||||
&self,
|
||||
_backtest_id: &str,
|
||||
_timestamp: DateTime<Utc>,
|
||||
_equity: f64,
|
||||
_drawdown: f64,
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// Mock news repository
|
||||
struct MockNews {
|
||||
events: Arc<RwLock<Vec<crate::strategy_engine::NewsEvent>>>,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl NewsRepository for MockNews {
|
||||
async fn load_news_events(
|
||||
&self,
|
||||
_symbols: &[String],
|
||||
_start_time: DateTime<Utc>,
|
||||
_end_time: DateTime<Utc>,
|
||||
) -> Result<Vec<crate::strategy_engine::NewsEvent>> {
|
||||
Ok(self.events.read().await.clone())
|
||||
}
|
||||
|
||||
async fn get_sentiment_data(
|
||||
&self,
|
||||
symbols: &[String],
|
||||
_timestamp: DateTime<Utc>,
|
||||
_lookback_hours: i32,
|
||||
) -> Result<HashMap<String, f64>> {
|
||||
let mut sentiment_map = HashMap::new();
|
||||
for symbol in symbols {
|
||||
sentiment_map.insert(symbol.clone(), 0.0);
|
||||
}
|
||||
Ok(sentiment_map)
|
||||
}
|
||||
}
|
||||
|
||||
Self {
|
||||
market_data: Box::new(MockMarketData {
|
||||
data: Arc::new(RwLock::new(Vec::new())),
|
||||
}),
|
||||
trading: Box::new(MockTrading {
|
||||
trades: Arc::new(RwLock::new(HashMap::new())),
|
||||
metrics: Arc::new(RwLock::new(HashMap::new())),
|
||||
backtests: Arc::new(RwLock::new(Vec::new())),
|
||||
}),
|
||||
news: Box::new(MockNews {
|
||||
events: Arc::new(RwLock::new(Vec::new())),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user