use std::collections::VecDeque;
use crate::strategy_engine::Strategy;
#[derive(Debug, Clone)]
pub struct Momentum {
prices: VecDeque<f64>,
window_size: usize,
}
impl Momentum {
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.prices.capacity() {
self.prices.pop_front();
}
}
}
impl Strategy for Momentum {
fn evaluate(&self, price: &f64) -> f64 {
if self.prices.len() < self.window_size {
return 0.0;
}
let current_price = *price;
let past_price = self.prices.front().unwrap();
let momentum = current_price - *past_price;
if momentum > 0.0 {
1.0 } else if momentum < 0.0 {
-1.0 } else {
0.0 }
}
fn calculate_indicator(&self, prices: &Vec<f64>) -> f64 {
let mut wins = 0;
let mut total_trades = 0;
for price in prices {
let signal = self.evaluate(price);
if signal > 0.0 {
total_trades += 1;
if *price > prices[0] {
wins += 1;
}
} else if signal < 0.0 {
total_trades += 1;
if *price < prices[0] {
wins += 1;
}
}
}
if total_trades == 0 {
0.0
} else {
wins as f64 / total_trades as f64
}
}
}