Documentation

use std::collections::VecDeque;

use crate::strategy_engine::Strategy;

#[derive(Debug, Clone)]
pub struct TrendFollowing {
    pub short_window: VecDeque<f64>,
    pub long_window: VecDeque<f64>,
    pub short_window_size: usize,
    pub long_window_size: usize,
}

impl TrendFollowing {
    pub fn new(short_window_size: usize, long_window_size: usize) -> Self {
        Self {
            short_window: VecDeque::with_capacity(short_window_size),
            long_window: VecDeque::with_capacity(long_window_size),
            short_window_size,
            long_window_size,
        }
    }

    pub fn update_price(&mut self, price: f64) {
        self.short_window.push_back(price);
        self.long_window.push_back(price);

        if self.short_window.len() > self.short_window_size {
            self.short_window.pop_front();
        }
        if self.long_window.len() > self.long_window_size {
            self.long_window.pop_front();
        }
    }
}

impl Strategy for TrendFollowing {
    fn evaluate(&self, _price: &f64) -> f64 {
        if self.short_window.len() < self.short_window_size || self.long_window.len() < self.long_window_size {
            return 0.0; // 如果价格数量不足,返回无信号
        }

        let short_avg = self.short_window.iter().sum::<f64>() / self.short_window_size as f64;
        let long_avg = self.long_window.iter().sum::<f64>() / self.long_window_size as f64;

        if short_avg > long_avg {
            1.0 // 买入信号
        } else if short_avg < long_avg {
            -1.0 // 卖出信号
        } else {
            0.0 // 无信号
        }
    }

    fn calculate_indicator(&self, prices: &Vec<f64>) -> f64 {
        // 计算年化收益率作为指标
        let mut total_return = 1.0;
        for price in prices {
            let signal = self.evaluate(price);
            if signal > 0.0 {
                total_return *= 1.0 + (*price / prices[0]) - 1.0; // 买入信号,计算收益
            } else if signal < 0.0 {
                total_return *= 1.0 - (*price / prices[0]) + 1.0; // 卖出信号,计算收益
            }
        }
        total_return - 1.0 // 返回年化收益率
    }
}