use crate::{arbitrage::Arbitrage, blockchain_performance::BlockchainPerformance, bollinger_bands::BollingerBands, breakout::Breakout, day_trading::DayTrading, dollar_cost_averaging::DollarCostAveraging, mean_reversion::MeanReversion, momentum::Momentum, moving_average_cross::MovingAverageCross, news_sentiment::NewsSentiment, scalping::Scalping, swing_trading::SwingTrading, target_price::TargetPrice, trend_following::TrendFollowing, volatility::Volatility, volume_strategy::VolumeStrategy};
pub struct StrategyEngine {
pub strategies: Vec<Box<dyn Strategy>>,
}
impl StrategyEngine {
pub fn new() -> Self {
Self {
strategies: vec![],
}
}
pub fn add_strategy(&mut self, strategy: Box<dyn Strategy>) {
self.strategies.push(strategy);
}
pub fn backtest(&self, prices: Vec<f64>) -> Vec<f64> {
let mut results = vec![];
for strategy in &self.strategies {
let mut result = 0.0;
for price in &prices {
result += strategy.evaluate(price);
}
results.push(result);
}
results
}
pub fn calculate_indicators(&self, prices: Vec<f64>) -> Vec<f64> {
let mut indicators = vec![];
for strategy in &self.strategies {
let indicator = strategy.calculate_indicator(&prices);
indicators.push(indicator);
}
indicators
}
}
impl Default for StrategyEngine {
fn default() -> Self {
let mut engine = Self::new();
let trend_following = TrendFollowing::new(3, 6);
let moving_average_cross = MovingAverageCross::new(3, 6);
let bollinger_bands = BollingerBands::new(10);
let mean_reversion = MeanReversion::new(5);
let momentum = Momentum::new(3);
let arbitrage = Arbitrage::new();
let swing_trading = SwingTrading::new(3, 6);
let day_trading = DayTrading::new();
let dollar_cost_averaging = DollarCostAveraging::new();
let scalping = Scalping::new();
let breakout = Breakout::new(150.0, 100.0);
let news_sentiment = NewsSentiment::new();
let volatility = Volatility::new();
let blockchain_performance = BlockchainPerformance::new();
let target_price = TargetPrice::new(120.0);
let volume_strategy = VolumeStrategy::new();
engine.add_strategy(Box::new(trend_following.clone()));
engine.add_strategy(Box::new(moving_average_cross.clone()));
engine.add_strategy(Box::new(bollinger_bands.clone()));
engine.add_strategy(Box::new(mean_reversion.clone()));
engine.add_strategy(Box::new(momentum.clone()));
engine.add_strategy(Box::new(arbitrage.clone()));
engine.add_strategy(Box::new(swing_trading.clone()));
engine.add_strategy(Box::new(day_trading.clone()));
engine.add_strategy(Box::new(dollar_cost_averaging.clone()));
engine.add_strategy(Box::new(scalping.clone()));
engine.add_strategy(Box::new(breakout.clone()));
engine.add_strategy(Box::new(news_sentiment.clone()));
engine.add_strategy(Box::new(volatility.clone()));
engine.add_strategy(Box::new(blockchain_performance.clone()));
engine.add_strategy(Box::new(target_price.clone()));
engine.add_strategy(Box::new(volume_strategy.clone()));
engine
}
}
pub trait Strategy {
fn evaluate(&self, price: &f64) -> f64;
fn calculate_indicator(&self, prices: &Vec<f64>) -> f64;
}
#[cfg(test)]
mod tests {
use crate::{arbitrage::Arbitrage, blockchain_performance::BlockchainPerformance, bollinger_bands::BollingerBands, breakout::Breakout, day_trading::DayTrading, dollar_cost_averaging::DollarCostAveraging, mean_reversion::MeanReversion, momentum::Momentum, moving_average_cross::MovingAverageCross, news_sentiment::NewsSentiment, scalping::Scalping, swing_trading::SwingTrading, target_price::TargetPrice, trend_following::TrendFollowing, volatility::Volatility, volume_strategy::VolumeStrategy};
use super::*;
#[test]
fn test_strategy_engine() {
let mut engine = StrategyEngine::new();
let mut trend_following = TrendFollowing::new(3, 6);
let mut moving_average_cross = MovingAverageCross::new(3, 6);
let mut bollinger_bands = BollingerBands::new(10);
let mut mean_reversion = MeanReversion::new(5);
let mut momentum = Momentum::new(3);
let arbitrage = Arbitrage::new();
let mut swing_trading = SwingTrading::new(3, 6);
let mut day_trading = DayTrading::new();
let mut dollar_cost_averaging = DollarCostAveraging::new();
let mut scalping = Scalping::new();
let mut breakout = Breakout::new(150.0, 100.0);
let mut news_sentiment = NewsSentiment::new();
let mut volatility = Volatility::new();
let mut blockchain_performance = BlockchainPerformance::new();
let target_price = TargetPrice::new(120.0);
let mut volume_strategy = VolumeStrategy::new();
engine.add_strategy(Box::new(trend_following.clone()));
engine.add_strategy(Box::new(moving_average_cross.clone()));
engine.add_strategy(Box::new(bollinger_bands.clone()));
engine.add_strategy(Box::new(mean_reversion.clone()));
engine.add_strategy(Box::new(momentum.clone()));
engine.add_strategy(Box::new(arbitrage.clone()));
engine.add_strategy(Box::new(swing_trading.clone()));
engine.add_strategy(Box::new(day_trading.clone()));
engine.add_strategy(Box::new(dollar_cost_averaging.clone()));
engine.add_strategy(Box::new(scalping.clone()));
engine.add_strategy(Box::new(breakout.clone()));
engine.add_strategy(Box::new(news_sentiment.clone()));
engine.add_strategy(Box::new(volatility.clone()));
engine.add_strategy(Box::new(blockchain_performance.clone()));
engine.add_strategy(Box::new(target_price.clone()));
engine.add_strategy(Box::new(volume_strategy.clone()));
let prices = vec![10.0, 12.0, 15.0, 14.0, 13.0, 12.0];
for price in &prices {
trend_following.update_price(*price);
moving_average_cross.update_price(*price);
bollinger_bands.update_price(*price);
mean_reversion.update_price(*price);
momentum.update_price(*price);
swing_trading.update_price(*price);
day_trading.update_price(*price);
dollar_cost_averaging.update_price(*price);
scalping.update_price(*price);
breakout.update_price(*price);
news_sentiment.update_sentiment(0.5);
volatility.update_price(*price);
blockchain_performance.update_performance(0.5);
volume_strategy.update_volume(1000.0);
}
let results = engine.backtest(prices.clone());
let indicators = engine.calculate_indicators(prices.clone());
println!("Backtest Results: {:?}", results);
println!("Indicators: {:?}", indicators);
}
#[test]
fn test_strategy_performance() {
let mut engine = StrategyEngine::new();
let mut trend_following = TrendFollowing::new(3, 6);
let mut moving_average_cross = MovingAverageCross::new(3, 6);
engine.add_strategy(Box::new(trend_following.clone()));
engine.add_strategy(Box::new(moving_average_cross.clone()));
let prices = vec![10.0, 12.0, 15.0, 14.0, 13.0, 12.0];
for price in &prices {
trend_following.update_price(*price);
moving_average_cross.update_price(*price);
}
let results = engine.backtest(prices.clone());
let indicators = engine.calculate_indicators(prices.clone());
assert!(results.len() == 2);
assert!(indicators.len() == 2);
}
#[test]
fn test_empty_strategy_engine() {
let engine = StrategyEngine::new();
let prices = vec![10.0, 12.0, 15.0, 14.0, 13.0, 12.0];
let results = engine.backtest(prices.clone());
let indicators = engine.calculate_indicators(prices.clone());
assert!(results.is_empty());
assert!(indicators.is_empty());
}
}