use std::collections::VecDeque;
use crate::strategy_engine::Strategy;
#[derive(Debug, Clone)]
pub struct MeanReversion {
pub prices: VecDeque<f64>,
pub window_size: usize,
}
impl MeanReversion {
pub fn new(window_size: usize) -> Self {
Self {
prices: VecDeque::with_capacity(window_size),
window_size,
}
}
pub fn update_price(&mut self, price: f64) {
self.prices.push_back(price);
if self.prices.len() > self.window_size {
self.prices.pop_front();
}
}
}
impl Strategy for MeanReversion {
fn evaluate(&self, _price: &f64) -> f64 {
if self.prices.len() < self.window_size {
return 0.0; }
let avg = self.prices.iter().take(self.window_size).sum::<f64>() / self.window_size as f64;
let last_price = self.prices.back().unwrap();
if *last_price < avg {
1.0 } else if *last_price > avg {
-1.0 } else {
0.0 }
}
fn calculate_indicator(&self, prices: &Vec<f64>) -> f64 {
let mut returns = vec![];
for price in prices {
let signal = self.evaluate(price);
if signal > 0.0 {
returns.push(*price / prices[0] - 1.0); } else if signal < 0.0 {
returns.push(1.0 - (*price / prices[0])); } else {
returns.push(0.0); }
}
let avg_return = returns.iter().sum::<f64>() / returns.len() as f64;
let std_dev = (returns.iter().map(|x| (x - avg_return).powi(2)).sum::<f64>() / returns.len() as f64).sqrt();
avg_return / std_dev }
}